Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2014-02-17 15:26:41 +0000
committerThomas Watson2014-02-17 19:23:15 +0000
commit1eabbd02085722c331e805b868894ac3022078ee (patch)
tree0465e2a8d1b6864867818a5eb6f3deba91d86ae3
parent87138c2bce46ece8c89bd465a6e00e99eee3cbe8 (diff)
downloadrt.equinox.framework-1eabbd02085722c331e805b868894ac3022078ee.tar.gz
rt.equinox.framework-1eabbd02085722c331e805b868894ac3022078ee.tar.xz
rt.equinox.framework-1eabbd02085722c331e805b868894ac3022078ee.zip
Bug 426492 - Missing dependency message from Equinox got worseI20140218-0800
-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/StateConverter.java11
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java63
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java8
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java143
6 files changed, 214 insertions, 431 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
deleted file mode 100644
index 8a9251d05..000000000
--- a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/FilterParser.java
+++ /dev/null
@@ -1,416 +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 - 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/StateConverter.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/compatibility/state/StateConverter.java
index dbf45aba4..426607bef 100644
--- 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2013, 2014 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
@@ -11,7 +11,7 @@ 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.internal.framework.FilterImpl;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
@@ -156,14 +156,13 @@ class StateConverter {
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;
+ FilterImpl parser;
try {
- component = parser.parse();
+ parser = FilterImpl.newInstance(filter);
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException("Invalid filter directive", e); //$NON-NLS-1$
}
- Map<String, String> matchingAttributes = component.getStandardOSGiAttributes(versions);
+ Map<String, String> matchingAttributes = parser.getStandardOSGiAttributes(versions);
String name = matchingAttributes.remove(namespace);
if (name == null)
throw new IllegalArgumentException("Invalid requirement: " + requirement); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
index bc5f295ac..bc21bbd3e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * Copyright (c) 2012, 2014 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
@@ -421,7 +421,7 @@ public abstract class Module implements BundleReference, BundleStartLevel, Compa
return;
if (getState().equals(State.INSTALLED)) {
String reportMessage = report.getResolutionReportMessage(getCurrentRevision());
- throw new BundleException(Msg.Module_ResolveError + reportMessage, BundleException.RESOLVE_ERROR, e);
+ throw new BundleException(Msg.Module_ResolveError + reportMessage, BundleException.RESOLVE_ERROR);
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java
index 3e66c4f0e..359d9db75 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2014 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
@@ -11,8 +11,12 @@
package org.eclipse.osgi.container;
import java.util.*;
+import org.eclipse.osgi.internal.framework.FilterImpl;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.report.resolution.ResolutionReport;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.namespace.*;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.*;
import org.osgi.service.resolver.ResolutionException;
@@ -112,7 +116,7 @@ public class ModuleResolutionReport implements ResolutionReport {
private static void printResolutionEntry(StringBuilder result, String prepend, ResolutionReport.Entry entry, Map<Resource, List<ResolutionReport.Entry>> reportEntries, Set<BundleRevision> visited) {
switch (entry.getType()) {
case MISSING_CAPABILITY :
- result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(entry.getData()).append('\n');
+ result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(printRequirement(entry.getData())).append('\n');
break;
case SINGLETON_SELECTION :
result.append(prepend).append(Msg.ModuleResolutionReport_AnotherSingleton).append(entry.getData()).append('\n');
@@ -127,8 +131,8 @@ public class ModuleResolutionReport implements ResolutionReport {
Capability unresolvedCapability = unresolvedCapabilities.iterator().next();
// make sure this is not a case of importing and exporting the same package
if (!unresolvedRequirement.getKey().getResource().equals(unresolvedCapability.getResource())) {
- result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(unresolvedRequirement.getKey()).append('\n');
- result.append(prepend).append(" -> ").append(unresolvedCapability).append('\n'); //$NON-NLS-1$
+ result.append(prepend).append(Msg.ModuleResolutionReport_UnresolvedReq).append(printRequirement(unresolvedRequirement.getKey())).append('\n');
+ result.append(prepend).append(" -> ").append(printCapability(unresolvedCapability)).append('\n'); //$NON-NLS-1$
result.append(getResolutionReport0(prepend + " ", (ModuleRevision) unresolvedCapability.getResource(), reportEntries, visited)); //$NON-NLS-1$
}
}
@@ -147,6 +151,57 @@ public class ModuleResolutionReport implements ResolutionReport {
}
}
+ private static Object printCapability(Capability cap) {
+ if (PackageNamespace.PACKAGE_NAMESPACE.equals(cap.getNamespace())) {
+ return Constants.EXPORT_PACKAGE + ": " + createOSGiCapability(cap); //$NON-NLS-1$
+ } else if (BundleNamespace.BUNDLE_NAMESPACE.equals(cap.getNamespace())) {
+ return Constants.BUNDLE_SYMBOLICNAME + ": " + createOSGiCapability(cap); //$NON-NLS-1$
+ } else if (HostNamespace.HOST_NAMESPACE.equals(cap.getNamespace())) {
+ return Constants.BUNDLE_SYMBOLICNAME + ": " + createOSGiCapability(cap); //$NON-NLS-1$
+ }
+ return Constants.PROVIDE_CAPABILITY + ": " + cap.toString(); //$NON-NLS-1$
+ }
+
+ private static String createOSGiCapability(Capability cap) {
+ Map<String, Object> attributes = new HashMap<String, Object>(cap.getAttributes());
+ Map<String, String> directives = cap.getDirectives();
+ String name = (String) attributes.remove(cap.getNamespace());
+ return name + ModuleRevision.toString(attributes, false, true) + ModuleRevision.toString(directives, true, true);
+ }
+
+ private static String printRequirement(Object data) {
+ if (!(data instanceof Requirement)) {
+ return String.valueOf(data);
+ }
+ Requirement req = (Requirement) data;
+ if (PackageNamespace.PACKAGE_NAMESPACE.equals(req.getNamespace())) {
+ return Constants.IMPORT_PACKAGE + ": " + createOSGiRequirement(req, PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
+ } else if (BundleNamespace.BUNDLE_NAMESPACE.equals(req.getNamespace())) {
+ return Constants.REQUIRE_BUNDLE + ": " + createOSGiRequirement(req, BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
+ } else if (HostNamespace.HOST_NAMESPACE.equals(req.getNamespace())) {
+ return Constants.FRAGMENT_HOST + ": " + createOSGiRequirement(req, HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
+ }
+ return Constants.REQUIRE_CAPABILITY + ": " + req.toString(); //$NON-NLS-1$
+ }
+
+ private static String createOSGiRequirement(Requirement requirement, 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$
+ FilterImpl filterImpl;
+ try {
+ filterImpl = FilterImpl.newInstance(filter);
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Invalid filter directive", e); //$NON-NLS-1$
+ }
+ Map<String, String> matchingAttributes = filterImpl.getStandardOSGiAttributes(versions);
+ String name = matchingAttributes.remove(requirement.getNamespace());
+ if (name == null)
+ throw new IllegalArgumentException("Invalid requirement: " + requirement); //$NON-NLS-1$
+ return name + ModuleRevision.toString(matchingAttributes, false, true) + ModuleRevision.toString(directives, true, true);
+ }
+
@Override
public String getResolutionReportMessage(Resource resource) {
return getResolutionReport0(null, (ModuleRevision) resource, getEntries(), null);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java
index 5951e5e4f..b8e452fc4 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * Copyright (c) 2012, 2014 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
@@ -197,6 +197,10 @@ public final class ModuleRevision implements BundleRevision {
}
static <V> String toString(Map<String, V> map, boolean directives) {
+ return toString(map, directives, false);
+ }
+
+ static <V> String toString(Map<String, V> map, boolean directives, boolean stringsOnly) {
if (map.size() == 0)
return ""; //$NON-NLS-1$
String assignment = directives ? ":=" : "="; //$NON-NLS-1$ //$NON-NLS-2$
@@ -221,7 +225,7 @@ public final class ModuleRevision implements BundleRevision {
sb.append('"');
} else {
String type = ""; //$NON-NLS-1$
- if (!(value instanceof String)) {
+ if (!(value instanceof String) && !stringsOnly) {
String className = value.getClass().getName();
type = ":" + className.substring(className.lastIndexOf('.') + 1); //$NON-NLS-1$
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
index 1977c3426..4e012d889 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * Copyright (c) 2003, 2014 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
@@ -1765,4 +1765,145 @@ public class FilterImpl implements Filter /* since Framework 1.1 */{
return null;
}
}
+
+ 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 Map<String, String> getStandardOSGiAttributes(String... versions) {
+ if (op != AND && op != EQUAL && op != SUBSTRING && op != PRESENT)
+ throw new IllegalArgumentException("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, (String) 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 form of the filter, e.g.:
+ // [1.0,2.0) -> (&(version>=1.0)(version<=2.0)(!(version=2.0)))
+ currentRange.addExclude(new Version((String) value));
+ } else {
+ throw new IllegalStateException("Invalid range for: " + attr); //$NON-NLS-1$
+ }
+ } else {
+ currentRange = new Range();
+ Version version = new Version((String) value);
+ currentRange.setLeft('[', version);
+ currentRange.setRight(']', version);
+ versionAttrs.put(attr, currentRange);
+ }
+ }
+ } else if (op == SUBSTRING || op == PRESENT) {
+ if (value == null) {
+ attributes.put(attr, "*"); //$NON-NLS-1$
+ } else {
+ StringBuilder builder = new StringBuilder();
+ for (String component : (String[]) value) {
+ if (component == null) {
+ builder.append('*');
+ } else {
+ builder.append(component);
+ }
+ }
+ attributes.put(attr, builder.toString());
+ }
+
+ } 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((String) 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((String) 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((String) 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((String) value)))
+ throw new IllegalStateException("range start is already processed for attribute: " + attr); //$NON-NLS-1$
+ }
+ } else if (op == AND) {
+ for (FilterImpl component : (FilterImpl[]) value) {
+ component.addAttributes(attributes, versionAttrs, false);
+ }
+ } else if (op == NOT) {
+ ((FilterImpl) value).addAttributes(attributes, versionAttrs, true);
+ } else {
+ throw new IllegalStateException("Invalid filter for standard OSGi requirements: " + op); //$NON-NLS-1$
+ }
+ }
}

Back to the top