Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2012-08-30 15:47:25 +0000
committerThomas Watson2012-10-02 18:54:42 +0000
commit2f49cd7039cbda2ec95446c7c202a24a47100221 (patch)
tree786a3e44ca92e349f3b516d262c605627e57746a /bundles/org.eclipse.osgi.compatibility.state
parentf98dd6b7b33f9762c389b0cb35f9d4023273fb54 (diff)
downloadrt.equinox.framework-2f49cd7039cbda2ec95446c7c202a24a47100221.tar.gz
rt.equinox.framework-2f49cd7039cbda2ec95446c7c202a24a47100221.tar.xz
rt.equinox.framework-2f49cd7039cbda2ec95446c7c202a24a47100221.zip
Initial work on the PlatformAdmin implementation
Diffstat (limited to 'bundles/org.eclipse.osgi.compatibility.state')
-rw-r--r--bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/FilterParser.java416
-rw-r--r--bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/PlatformAdminImpl.java71
-rw-r--r--bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlyState.java (renamed from bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java)51
-rw-r--r--bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlySystemState.java317
-rw-r--r--bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/StateConverter.java197
5 files changed, 696 insertions, 356 deletions
diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/FilterParser.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/FilterParser.java
new file mode 100644
index 000000000..8a9251d05
--- /dev/null
+++ b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/FilterParser.java
@@ -0,0 +1,416 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.osgi.compatibility.state;
+
+import java.util.*;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+public class FilterParser {
+ static class Range {
+ private char leftRule = 0;
+ private Version leftVersion;
+ private Version rightVersion;
+ private char rightRule = 0;
+ private Collection<Version> excludes = new ArrayList<Version>(0);
+
+ public String toString() {
+ if (rightVersion == null) {
+ return leftVersion.toString();
+ }
+ return leftRule + leftVersion.toString() + ',' + rightVersion.toString() + rightRule;
+ }
+
+ void addExclude(Version exclude) {
+ this.excludes.add(exclude);
+ setLeft(leftRule, leftVersion);
+ setRight(rightRule, rightVersion);
+ }
+
+ boolean setLeft(char leftRule, Version leftVersion) {
+ if (this.leftVersion != null && this.leftVersion != leftVersion)
+ return false;
+ this.leftRule = excludes.contains(leftVersion) ? '(' : leftRule;
+ this.leftVersion = leftVersion;
+ return true;
+ }
+
+ boolean setRight(char rightRule, Version rightVersion) {
+ if (this.rightVersion != null && this.rightVersion != rightVersion)
+ return false;
+ this.rightRule = excludes.contains(rightVersion) ? ')' : rightRule;
+ this.rightVersion = rightVersion;
+ return true;
+ }
+ }
+
+ public static class FilterComponent {
+ /* filter operators */
+ public static final int EQUAL = 1;
+ public static final int APPROX = 2;
+ public static final int GREATER = 3;
+ public static final int LESS = 4;
+ public static final int AND = 7;
+ public static final int OR = 8;
+ public static final int NOT = 9;
+
+ private final int op;
+ private final String attr;
+ private final String value;
+ private final List<FilterComponent> nested;
+
+ public FilterComponent(int op, List<FilterComponent> nested) {
+ this.op = op;
+ this.attr = null;
+ this.value = null;
+ this.nested = nested;
+ }
+
+ public FilterComponent(int op, String attr, String value) {
+ this.op = op;
+ this.attr = attr;
+ this.value = value;
+ this.nested = Collections.emptyList();
+ }
+
+ public int getOp() {
+ return op;
+ }
+
+ public String getAttr() {
+ return attr;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public List<FilterComponent> getNested() {
+ return nested;
+ }
+
+ public Map<String, String> getStandardOSGiAttributes(String... versions) {
+ if (op != AND && op != EQUAL)
+ throw new IllegalStateException("Invalid filter for Starndard OSGi Attributes: " + op); //$NON-NLS-1$
+ Map<String, String> result = new HashMap<String, String>();
+ Map<String, Range> versionAttrs = new HashMap<String, Range>();
+ if (versions != null) {
+ for (String versionAttr : versions) {
+ versionAttrs.put(versionAttr, null);
+ }
+ }
+ addAttributes(result, versionAttrs, false);
+ for (Map.Entry<String, Range> entry : versionAttrs.entrySet()) {
+ Range range = entry.getValue();
+ if (range != null) {
+ result.put(entry.getKey(), range.toString());
+ }
+ }
+
+ return result;
+ }
+
+ private void addAttributes(Map<String, String> attributes, Map<String, Range> versionAttrs, boolean not) {
+ if (op == EQUAL) {
+ if (!versionAttrs.containsKey(attr)) {
+ attributes.put(attr, value);
+ } else {
+ // this is an exact range e.g. [value,value]
+ Range currentRange = versionAttrs.get(attr);
+ if (currentRange != null) {
+ if (not) {
+ // this is an expanded for of the filter, e.g.:
+ // [1.0,2.0) -> (&(version>=1.0)(version<=2.0)(!(version=2.0)))
+ currentRange.addExclude(new Version(value));
+ } else {
+ throw new IllegalStateException("Invalid range for: " + attr); //$NON-NLS-1$
+ }
+ }
+ currentRange = new Range();
+ Version version = new Version(value);
+ currentRange.setLeft('[', version);
+ currentRange.setRight(']', version);
+ versionAttrs.put(attr, currentRange);
+ }
+ } else if (op == LESS) {
+ if (!versionAttrs.containsKey(attr))
+ throw new IllegalStateException("Invalid attribute: " + attr); //$NON-NLS-1$
+ Range currentRange = versionAttrs.get(attr);
+ if (currentRange == null) {
+ currentRange = new Range();
+ versionAttrs.put(attr, currentRange);
+ }
+ if (not) {
+ // this must be a range start "(value"
+ if (!currentRange.setLeft('(', new Version(value)))
+ throw new IllegalStateException("range start is already processed for attribute: " + attr); //$NON-NLS-1$
+ } else {
+ // this must be a range end "value]"
+ if (!currentRange.setRight(']', new Version(value)))
+ throw new IllegalStateException("range end is already processed for attribute: " + attr); //$NON-NLS-1$
+ }
+ } else if (op == GREATER) {
+ if (!versionAttrs.containsKey(attr))
+ throw new IllegalStateException("Invalid attribute: " + attr); //$NON-NLS-1$
+ Range currentRange = versionAttrs.get(attr);
+ if (currentRange == null) {
+ currentRange = new Range();
+ versionAttrs.put(attr, currentRange);
+ }
+ if (not) {
+ // this must be a range end "value)"
+ if (!currentRange.setRight(')', new Version(value)))
+ throw new IllegalStateException("range end is already processed for attribute: " + attr); //$NON-NLS-1$
+ } else {
+ // this must be a range start "[value"
+ if (!currentRange.setLeft('[', new Version(value)))
+ throw new IllegalStateException("range start is already processed for attribute: " + attr); //$NON-NLS-1$
+ }
+ } else if (op == AND) {
+ for (FilterComponent component : nested) {
+ component.addAttributes(attributes, versionAttrs, false);
+ }
+ } else if (op == NOT) {
+ nested.get(0).addAttributes(attributes, versionAttrs, true);
+ } else {
+ throw new IllegalStateException("Invalid filter for standard OSGi requirements: " + op); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private final String filterstring;
+ private final char[] filterChars;
+ private int pos;
+
+ public FilterParser(String filterstring) {
+ this.filterstring = filterstring;
+ filterChars = filterstring.toCharArray();
+ pos = 0;
+ }
+
+ public FilterComponent parse() throws InvalidSyntaxException {
+ FilterComponent filter;
+ try {
+ filter = parse_filter();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new InvalidSyntaxException("Filter ended abruptly", filterstring, e); //$NON-NLS-1$
+ }
+
+ if (pos != filterChars.length) {
+ throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+ return filter;
+ }
+
+ private FilterComponent parse_filter() throws InvalidSyntaxException {
+ FilterComponent filter;
+ skipWhiteSpace();
+
+ if (filterChars[pos] != '(') {
+ throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ pos++;
+
+ filter = parse_filtercomp();
+
+ skipWhiteSpace();
+
+ if (filterChars[pos] != ')') {
+ throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ pos++;
+
+ skipWhiteSpace();
+
+ return filter;
+ }
+
+ private FilterComponent parse_filtercomp() throws InvalidSyntaxException {
+ skipWhiteSpace();
+
+ char c = filterChars[pos];
+
+ switch (c) {
+ case '&' : {
+ pos++;
+ return parse_and();
+ }
+ case '|' : {
+ pos++;
+ return parse_or();
+ }
+ case '!' : {
+ pos++;
+ return parse_not();
+ }
+ }
+ return parse_item();
+ }
+
+ private FilterComponent parse_and() throws InvalidSyntaxException {
+ int lookahead = pos;
+ skipWhiteSpace();
+
+ if (filterChars[pos] != '(') {
+ pos = lookahead - 1;
+ return parse_item();
+ }
+
+ List<FilterComponent> operands = new ArrayList<FilterComponent>(10);
+
+ while (filterChars[pos] == '(') {
+ FilterComponent child = parse_filter();
+ operands.add(child);
+ }
+
+ return new FilterComponent(FilterComponent.AND, operands);
+ }
+
+ private FilterComponent parse_or() throws InvalidSyntaxException {
+ int lookahead = pos;
+ skipWhiteSpace();
+
+ if (filterChars[pos] != '(') {
+ pos = lookahead - 1;
+ return parse_item();
+ }
+
+ List<FilterComponent> operands = new ArrayList<FilterComponent>(10);
+
+ while (filterChars[pos] == '(') {
+ FilterComponent child = parse_filter();
+ operands.add(child);
+ }
+
+ return new FilterComponent(FilterComponent.OR, operands);
+ }
+
+ private FilterComponent parse_not() throws InvalidSyntaxException {
+ int lookahead = pos;
+ skipWhiteSpace();
+
+ if (filterChars[pos] != '(') {
+ pos = lookahead - 1;
+ return parse_item();
+ }
+
+ List<FilterComponent> operands = new ArrayList<FilterComponent>(1);
+ FilterComponent child = parse_filter();
+ operands.add(child);
+
+ return new FilterComponent(FilterComponent.NOT, operands);
+ }
+
+ private FilterComponent parse_item() throws InvalidSyntaxException {
+ String attr = parse_attr();
+
+ skipWhiteSpace();
+
+ switch (filterChars[pos]) {
+ case '~' : {
+ if (filterChars[pos + 1] == '=') {
+ pos += 2;
+ return new FilterComponent(FilterComponent.APPROX, attr, parse_value());
+ }
+ break;
+ }
+ case '>' : {
+ if (filterChars[pos + 1] == '=') {
+ pos += 2;
+ return new FilterComponent(FilterComponent.GREATER, attr, parse_value());
+ }
+ break;
+ }
+ case '<' : {
+ if (filterChars[pos + 1] == '=') {
+ pos += 2;
+ return new FilterComponent(FilterComponent.LESS, attr, parse_value());
+ }
+ break;
+ }
+ case '=' : {
+ pos++;
+ return new FilterComponent(FilterComponent.EQUAL, attr, parse_value());
+ }
+ }
+
+ throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ private String parse_attr() throws InvalidSyntaxException {
+ skipWhiteSpace();
+
+ int begin = pos;
+ int end = pos;
+
+ char c = filterChars[pos];
+
+ while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') {
+ pos++;
+
+ if (!Character.isWhitespace(c)) {
+ end = pos;
+ }
+
+ c = filterChars[pos];
+ }
+
+ int length = end - begin;
+
+ if (length == 0) {
+ throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ return new String(filterChars, begin, length);
+ }
+
+ private String parse_value() throws InvalidSyntaxException {
+ StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+ parseloop: while (true) {
+ char c = filterChars[pos];
+
+ switch (c) {
+ case ')' : {
+ break parseloop;
+ }
+
+ case '(' : {
+ throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ case '\\' : {
+ pos++;
+ c = filterChars[pos];
+ /* fall through into default */
+ }
+
+ default : {
+ sb.append(c);
+ pos++;
+ break;
+ }
+ }
+ }
+
+ if (sb.length() == 0) {
+ throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); //$NON-NLS-1$
+ }
+
+ return sb.toString();
+ }
+
+ private void skipWhiteSpace() {
+ for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) {
+ pos++;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/PlatformAdminImpl.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/PlatformAdminImpl.java
index 735ee2ccf..25c5c88b5 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/PlatformAdminImpl.java
+++ b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/PlatformAdminImpl.java
@@ -9,27 +9,30 @@
******************************************************************************/
package org.eclipse.osgi.compatibility.state;
-import org.eclipse.osgi.container.ModuleContainer;
-import org.eclipse.osgi.container.ModuleDatabase;
+import java.util.*;
+import org.eclipse.osgi.container.*;
import org.eclipse.osgi.internal.framework.BundleContextImpl;
+import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.module.ResolverImpl;
import org.eclipse.osgi.internal.resolver.StateHelperImpl;
import org.eclipse.osgi.internal.resolver.StateObjectFactoryImpl;
import org.eclipse.osgi.service.resolver.*;
-import org.eclipse.osgi.storage.Storage;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
public class PlatformAdminImpl implements PlatformAdmin {
private final StateHelper stateHelper = new StateHelperImpl();
private final StateObjectFactory factory = new StateObjectFactoryImpl();
- private volatile ModuleContainer container;
- private volatile ModuleDatabase database;
+ private final Object monitor = new Object();
+ private EquinoxContainer equinoxContainer;
+ private State systemState;
+ @SuppressWarnings("unused")
+ // this is used by DS to activate us
private void activate(BundleContext context) {
- Storage storage = ((BundleContextImpl) context).getContainer().getStorage();
- this.container = storage.getModuleContainer();
- this.database = storage.getModuleDatabase();
+ synchronized (this.monitor) {
+ equinoxContainer = ((BundleContextImpl) context).getContainer();
+ }
context.registerService(PlatformAdmin.class, this, null);
}
@@ -41,26 +44,66 @@ public class PlatformAdminImpl implements PlatformAdmin {
@Override
public State getState(boolean mutable) {
if (mutable) {
- return stateCopy();
+ return factory.createState(getSystemState());
}
- return new ReadOnlySystemState(container, database);
+ return new ReadOnlyState(this);
}
- private State stateCopy() {
- // TODO
- throw new UnsupportedOperationException();
+ State getSystemState() {
+ synchronized (this.monitor) {
+ if (systemState == null) {
+ systemState = createSystemState();
+ }
+ return systemState;
+ }
+ }
+
+ long getTimeStamp() {
+ synchronized (this.monitor) {
+ return equinoxContainer.getStorage().getModuleDatabase().getTimestamp();
+ }
+ }
+
+ private State createSystemState() {
+ State state = factory.createState(true);
+ StateConverter converter = new StateConverter(state);
+ ModuleDatabase database = equinoxContainer.getStorage().getModuleDatabase();
+ database.lockRead();
+ try {
+ List<Module> modules = equinoxContainer.getStorage().getModuleContainer().getModules();
+ for (Module module : modules) {
+ ModuleRevision current = module.getCurrentRevision();
+ BundleDescription description = converter.createDescription(current);
+ state.addBundle(description);
+ state.setPlatformProperties(asDictionary(equinoxContainer.getConfiguration().asMap()));
+ }
+ state.setTimeStamp(database.getTimestamp());
+ // TODO add hooks to get the resolution correct
+ // TODO add listeners to keep state copy in sync
+ } finally {
+ database.unlockRead();
+ }
+ return state;
+ }
+
+ private Dictionary<String, String> asDictionary(Map<String, String> map) {
+ return new Hashtable<String, String>(map);
}
@Override
public StateHelper getStateHelper() {
- return stateHelper;
+ return StateHelperImpl.getInstance();
}
+ /**
+ * @throws BundleException
+ */
@Override
public void commit(State state) throws BundleException {
throw new UnsupportedOperationException();
}
+ @Deprecated
@Override
public Resolver getResolver() {
return createResolver();
diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlyState.java
index d0bc359ae..be8a87637 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
+++ b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlyState.java
@@ -10,19 +10,20 @@
* Danail Nachev - ProSyst - bug 218625
* Rob Harrop - SpringSource Inc. (bug 247522)
*******************************************************************************/
-package org.eclipse.osgi.internal.resolver;
+package org.eclipse.osgi.compatibility.state;
import java.util.*;
+import org.eclipse.osgi.internal.resolver.StateHelperImpl;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
public final class ReadOnlyState implements State {
- private final State target;
+ private final PlatformAdminImpl platformAdmin;
- public ReadOnlyState(State target) {
- this.target = target;
+ public ReadOnlyState(PlatformAdminImpl platformAdmin) {
+ this.platformAdmin = platformAdmin;
}
public boolean addBundle(BundleDescription description) {
@@ -30,55 +31,55 @@ public final class ReadOnlyState implements State {
}
public StateDelta compare(State state) throws BundleException {
- return target.compare(state);
+ return platformAdmin.getSystemState().compare(state);
}
public BundleDescription getBundle(long id) {
- return target.getBundle(id);
+ return platformAdmin.getSystemState().getBundle(id);
}
public BundleDescription getBundle(String symbolicName, Version version) {
- return target.getBundle(symbolicName, version);
+ return platformAdmin.getSystemState().getBundle(symbolicName, version);
}
public BundleDescription getBundleByLocation(String location) {
- return target.getBundleByLocation(location);
+ return platformAdmin.getSystemState().getBundleByLocation(location);
}
public BundleDescription[] getBundles() {
- return target.getBundles();
+ return platformAdmin.getSystemState().getBundles();
}
public BundleDescription[] getBundles(String symbolicName) {
- return target.getBundles(symbolicName);
+ return platformAdmin.getSystemState().getBundles(symbolicName);
}
public StateDelta getChanges() {
- return target.getChanges();
+ return platformAdmin.getSystemState().getChanges();
}
public ExportPackageDescription[] getExportedPackages() {
- return target.getExportedPackages();
+ return platformAdmin.getSystemState().getExportedPackages();
}
public StateObjectFactory getFactory() {
- return target.getFactory();
+ return platformAdmin.getSystemState().getFactory();
}
public BundleDescription[] getResolvedBundles() {
- return target.getResolvedBundles();
+ return platformAdmin.getSystemState().getResolvedBundles();
}
public long getTimeStamp() {
- return target.getTimeStamp();
+ return platformAdmin.getTimeStamp();
}
public boolean isEmpty() {
- return target.isEmpty();
+ return platformAdmin.getSystemState().isEmpty();
}
public boolean isResolved() {
- return target.isResolved();
+ return platformAdmin.getSystemState().isResolved();
}
public boolean removeBundle(BundleDescription bundle) {
@@ -158,7 +159,7 @@ public final class ReadOnlyState implements State {
@SuppressWarnings("rawtypes")
public Dictionary[] getPlatformProperties() {
- return target.getPlatformProperties();
+ return platformAdmin.getSystemState().getPlatformProperties();
}
public ExportPackageDescription linkDynamicImport(BundleDescription importingBundle, String requestedPackage) {
@@ -170,7 +171,7 @@ public final class ReadOnlyState implements State {
}
public ExportPackageDescription[] getSystemPackages() {
- return target.getSystemPackages();
+ return platformAdmin.getSystemState().getSystemPackages();
}
public void addResolverError(BundleDescription bundle, int type, String data, VersionConstraint unsatisfied) {
@@ -178,7 +179,7 @@ public final class ReadOnlyState implements State {
}
public ResolverError[] getResolverErrors(BundleDescription bundle) {
- return target.getResolverErrors(bundle);
+ return platformAdmin.getSystemState().getResolverErrors(bundle);
}
public void removeResolverErrors(BundleDescription bundle) {
@@ -190,7 +191,7 @@ public final class ReadOnlyState implements State {
}
public long getHighestBundleId() {
- return target.getHighestBundleId();
+ return platformAdmin.getSystemState().getHighestBundleId();
}
public void setNativePathsInvalid(NativeCodeDescription nativeCodeDescription, boolean hasInvalidPaths) {
@@ -198,7 +199,7 @@ public final class ReadOnlyState implements State {
}
public BundleDescription[] getDisabledBundles() {
- return target.getDisabledBundles();
+ return platformAdmin.getSystemState().getDisabledBundles();
}
public void addDisabledInfo(DisabledInfo disabledInfo) {
@@ -206,11 +207,11 @@ public final class ReadOnlyState implements State {
}
public DisabledInfo[] getDisabledInfos(BundleDescription bundle) {
- return target.getDisabledInfos(bundle);
+ return platformAdmin.getSystemState().getDisabledInfos(bundle);
}
public DisabledInfo getDisabledInfo(BundleDescription bundle, String policyName) {
- return target.getDisabledInfo(bundle, policyName);
+ return platformAdmin.getSystemState().getDisabledInfo(bundle, policyName);
}
public void removeDisabledInfo(DisabledInfo disabledInfo) {
@@ -222,7 +223,7 @@ public final class ReadOnlyState implements State {
}
public Collection<BundleDescription> getDependencyClosure(Collection<BundleDescription> bundles) {
- return target.getDependencyClosure(bundles);
+ return platformAdmin.getSystemState().getDependencyClosure(bundles);
}
public void addDynamicImportPackages(BundleDescription importingBundle, ImportPackageSpecification[] dynamicImports) {
diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlySystemState.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlySystemState.java
deleted file mode 100644
index a2ff5a587..000000000
--- a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/ReadOnlySystemState.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.osgi.compatibility.state;
-
-import java.util.*;
-import org.eclipse.osgi.container.ModuleContainer;
-import org.eclipse.osgi.container.ModuleDatabase;
-import org.eclipse.osgi.service.resolver.*;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.framework.hooks.resolver.ResolverHookFactory;
-
-public class ReadOnlySystemState implements State {
-
- private final ModuleContainer container;
- private final ModuleDatabase database;
- private final StateDelta delta = new StateDelta() {
- @Override
- public State getState() {
- // TODO Auto-generated method stub
- return ReadOnlySystemState.this;
- }
-
- @Override
- public ResolverHookException getResovlerHookException() {
- return null;
- }
-
- @Override
- public BundleDelta[] getChanges(int mask, boolean exact) {
- return new BundleDelta[0];
- }
-
- @Override
- public BundleDelta[] getChanges() {
- return new BundleDelta[0];
- }
- };
-
- public ReadOnlySystemState(ModuleContainer container, ModuleDatabase database) {
- this.container = container;
- this.database = database;
- }
-
- @Override
- public boolean addBundle(BundleDescription description) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta compare(State baseState) throws BundleException {
- return delta;
- }
-
- @Override
- public BundleDescription removeBundle(long bundleId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean removeBundle(BundleDescription bundle) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean updateBundle(BundleDescription newDescription) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta getChanges() {
- return delta;
- }
-
- @Override
- public BundleDescription[] getBundles() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public BundleDescription getBundle(long id) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public BundleDescription getBundle(String symbolicName, Version version) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public BundleDescription getBundleByLocation(String location) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public long getTimeStamp() {
- return database.getRevisionsTimestamp();
- }
-
- @Override
- public void setTimeStamp(long newTimeStamp) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isResolved() {
- return true;
- }
-
- @Override
- public void resolveConstraint(VersionConstraint constraint, BaseDescription supplier) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities, Map<String, List<StateWire>> resolvedWires) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeBundleComplete(BundleDescription bundle) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addResolverError(BundleDescription bundle, int type, String data, VersionConstraint unsatisfied) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeResolverErrors(BundleDescription bundle) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ResolverError[] getResolverErrors(BundleDescription bundle) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Resolver getResolver() {
- return null;
- }
-
- @Override
- public void setResolver(Resolver value) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta resolve(boolean incremental) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta resolve() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta resolve(BundleDescription[] discard) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public StateDelta resolve(BundleDescription[] resolve, boolean discard) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setOverrides(Object value) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public BundleDescription[] getResolvedBundles() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public BundleDescription[] getRemovalPending() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Collection<BundleDescription> getDependencyClosure(Collection<BundleDescription> bundles) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public boolean isEmpty() {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public ExportPackageDescription[] getExportedPackages() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public BundleDescription[] getBundles(String symbolicName) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public StateObjectFactory getFactory() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ExportPackageDescription linkDynamicImport(BundleDescription importingBundle, String requestedPackage) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addDynamicImportPackages(BundleDescription importingBundle, ImportPackageSpecification[] dynamicImports) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public boolean setPlatformProperties(Dictionary<?, ?> platformProperties) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean setPlatformProperties(Dictionary<?, ?>[] platformProperties) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Dictionary[] getPlatformProperties() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ExportPackageDescription[] getSystemPackages() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public StateHelper getStateHelper() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public long getHighestBundleId() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setNativePathsInvalid(NativeCodeDescription nativeCodeDescription, boolean hasInvalidNativePaths) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public BundleDescription[] getDisabledBundles() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addDisabledInfo(DisabledInfo disabledInfo) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeDisabledInfo(DisabledInfo disabledInfo) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DisabledInfo[] getDisabledInfos(BundleDescription bundle) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DisabledInfo getDisabledInfo(BundleDescription bundle, String policyName) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setResolverHookFactory(ResolverHookFactory hookFactory) {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/StateConverter.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/StateConverter.java
new file mode 100644
index 000000000..7c6754e7d
--- /dev/null
+++ b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/StateConverter.java
@@ -0,0 +1,197 @@
+package org.eclipse.osgi.compatibility.state;
+
+import java.util.*;
+import java.util.Map.Entry;
+import org.eclipse.osgi.compatibility.state.FilterParser.FilterComponent;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.*;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.*;
+
+class StateConverter {
+ private final State state;
+
+ StateConverter(State state) {
+ this.state = state;
+ }
+
+ BundleDescription createDescription(BundleRevision resource) {
+
+ Collection<Capability> idList = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (idList.size() != 1)
+ throw new IllegalArgumentException("Bogus osgi.identity: " + idList); //$NON-NLS-1$
+ Capability id = idList.iterator().next();
+
+ Map<String, Object> idAttrs = new HashMap<String, Object>(id.getAttributes());
+
+ String symbolicName = (String) idAttrs.remove(IdentityNamespace.IDENTITY_NAMESPACE);
+ Version version = (Version) idAttrs.remove(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+
+ String symbolicNameSpecification = symbolicName + toString(idAttrs, "=", true) + toString(id.getDirectives(), ":=", true); //$NON-NLS-1$ //$NON-NLS-2$
+
+ List<ExportPackageDescription> exportPackages = new ArrayList<ExportPackageDescription>();
+ List<GenericDescription> provideCapabilities = new ArrayList<GenericDescription>();
+ List<ImportPackageSpecification> importPackages = new ArrayList<ImportPackageSpecification>();
+ List<GenericSpecification> requireCapabilities = new ArrayList<GenericSpecification>();
+ List<HostSpecification> fragmentHost = new ArrayList<HostSpecification>(0);
+ List<BundleSpecification> requireBundles = new ArrayList<BundleSpecification>();
+
+ Collection<Capability> capabilities = resource.getCapabilities(null);
+
+ Capability osgiIdentity = null;
+ for (Capability capability : capabilities) {
+ String namespace = capability.getNamespace();
+ if (IdentityNamespace.IDENTITY_NAMESPACE.equals(namespace)) {
+ osgiIdentity = capability;
+ } else if (BundleRevision.HOST_NAMESPACE.equals(namespace) || BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
+ continue;
+ } else if (BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+ exportPackages.addAll(creatExportPackage(capability));
+ } else {
+ provideCapabilities.addAll(createProvideCapability(capability));
+ }
+ }
+
+ Collection<Requirement> requirements = resource.getRequirements(null);
+ for (Requirement requirement : requirements) {
+ String namespace = requirement.getNamespace();
+ if (BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
+ requireBundles.addAll(createRequireBundle(requirement));
+ } else if (BundleRevision.HOST_NAMESPACE.equals(namespace)) {
+ fragmentHost.addAll(createFragmentHost(requirement));
+ } else if (BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+ importPackages.addAll(createImportPackage(requirement));
+ } else {
+ requireCapabilities.addAll(createRequireCapability(requirement));
+ }
+ }
+
+ BundleDescription result = state.getFactory().createBundleDescription(resource.getBundle().getBundleId(), symbolicNameSpecification, version, null, requireBundles.toArray(new BundleSpecification[requireBundles.size()]), fragmentHost.size() == 0 ? null : fragmentHost.get(0), importPackages.toArray(new ImportPackageSpecification[importPackages.size()]), exportPackages.toArray(new ExportPackageDescription[exportPackages.size()]), null, null, requireCapabilities.toArray(new GenericSpecification[requireCapabilities.size()]), provideCapabilities.toArray(new GenericDescription[provideCapabilities.size()]), null);
+ result.setUserObject(resource);
+ GenericDescription[] genericDescs = result.getGenericCapabilities();
+ for (GenericDescription genericDesc : genericDescs) {
+ if (IdentityNamespace.IDENTITY_NAMESPACE.equals(genericDesc.getType()))
+ genericDesc.setUserObject(osgiIdentity);
+ }
+ return result;
+
+ }
+
+ private List<ExportPackageDescription> creatExportPackage(Capability capability) {
+ Map<String, Object> attributes = new HashMap<String, Object>(capability.getAttributes());
+ Map<String, String> directives = capability.getDirectives();
+ String packageName = (String) attributes.remove(PackageNamespace.PACKAGE_NAMESPACE);
+ // remove invalid attributes
+ attributes.remove(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+ attributes.remove(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ String declaration = packageName + toString(attributes, "=", true) + toString(directives, ":=", true); //$NON-NLS-1$//$NON-NLS-2$
+ List<ExportPackageDescription> result = state.getFactory().createExportPackageDescriptions(declaration);
+ for (ExportPackageDescription export : result) {
+ export.setUserObject(capability);
+ }
+ return result;
+ }
+
+ private List<GenericDescription> createProvideCapability(Capability capability) {
+ Map<String, Object> attributes = capability.getAttributes();
+ Map<String, String> directives = capability.getDirectives();
+
+ String declaration = capability.getNamespace() + toString(attributes, "=", false) + toString(directives, ":=", true); //$NON-NLS-1$//$NON-NLS-2$
+ List<GenericDescription> result = state.getFactory().createGenericDescriptions(declaration);
+ for (GenericDescription genericDescription : result) {
+ genericDescription.setUserObject(capability);
+ }
+ return result;
+ }
+
+ private List<BundleSpecification> createRequireBundle(Requirement requirement) {
+ String declaration = createOSGiRequirement(requirement, BundleNamespace.BUNDLE_NAMESPACE, BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ List<BundleSpecification> result = state.getFactory().createBundleSpecifications(declaration);
+ for (BundleSpecification bundleSpecification : result) {
+ bundleSpecification.setUserObject(requirement);
+ }
+ return result;
+ }
+
+ private List<HostSpecification> createFragmentHost(Requirement requirement) {
+ String declaration = createOSGiRequirement(requirement, HostNamespace.HOST_NAMESPACE, HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ List<HostSpecification> result = state.getFactory().createHostSpecifications(declaration);
+ for (HostSpecification hostSpecification : result) {
+ hostSpecification.setUserObject(requirement);
+ }
+ return result;
+ }
+
+ private List<ImportPackageSpecification> createImportPackage(Requirement requirement) {
+ String declaration = createOSGiRequirement(requirement, PackageNamespace.PACKAGE_NAMESPACE, PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
+ List<ImportPackageSpecification> result = state.getFactory().createImportPackageSpecifications(declaration);
+ for (ImportPackageSpecification importPackageSpecification : result) {
+ importPackageSpecification.setUserObject(requirement);
+ }
+ return result;
+ }
+
+ private List<GenericSpecification> createRequireCapability(Requirement requirement) {
+ String declaration = requirement.getNamespace() + toString(requirement.getAttributes(), "=", false) + toString(requirement.getDirectives(), ":=", true); //$NON-NLS-1$ //$NON-NLS-2$
+ List<GenericSpecification> result = state.getFactory().createGenericSpecifications(declaration);
+ for (GenericSpecification genericSpecification : result) {
+ genericSpecification.setUserObject(requirement);
+ }
+ return result;
+ }
+
+ private String createOSGiRequirement(Requirement requirement, String namespace, String... versions) {
+ Map<String, String> directives = new HashMap<String, String>(requirement.getDirectives());
+ String filter = directives.remove(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
+ if (filter == null)
+ throw new IllegalArgumentException("No filter directive found:" + requirement); //$NON-NLS-1$
+ FilterParser parser = new FilterParser(filter);
+ FilterComponent component = null;
+ try {
+ component = parser.parse();
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Invalid filter directive", e); //$NON-NLS-1$
+ }
+ Map<String, String> matchingAttributes = component.getStandardOSGiAttributes(versions);
+ String name = matchingAttributes.remove(namespace);
+ if (name == null)
+ throw new IllegalArgumentException("Invalid requirement: " + requirement); //$NON-NLS-1$
+ return name + toString(matchingAttributes, "=", true) + toString(directives, ":=", true); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ static <V> String toString(Map<String, V> map, String assignment, boolean stringsOnly) {
+ if (map.isEmpty())
+ return ""; //$NON-NLS-1$
+ Set<Entry<String, V>> set = map.entrySet();
+ StringBuffer sb = new StringBuffer();
+ for (Entry<String, V> entry : set) {
+ sb.append("; "); //$NON-NLS-1$
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Object> list = (List<Object>) value;
+ if (list.size() == 0)
+ continue;
+ Object component = list.get(0);
+ String className = component.getClass().getName();
+ String type = className.substring(className.lastIndexOf('.') + 1);
+ sb.append(key).append(':').append("List<").append(type).append(">").append(assignment).append('"'); //$NON-NLS-1$ //$NON-NLS-2$
+ for (Object object : list)
+ sb.append(object).append(',');
+ sb.setLength(sb.length() - 1);
+ sb.append('"');
+ } else {
+ String type = ""; //$NON-NLS-1$
+ if (!(value instanceof String) && !stringsOnly) {
+ String className = value.getClass().getName();
+ type = ":" + className.substring(className.lastIndexOf('.') + 1); //$NON-NLS-1$
+ }
+ sb.append(key).append(type).append(assignment).append('"').append(value).append('"');
+ }
+ }
+ return sb.toString();
+ }
+}

Back to the top