diff options
author | Thomas Watson | 2011-05-24 21:25:17 +0000 |
---|---|---|
committer | Thomas Watson | 2011-05-24 21:25:17 +0000 |
commit | 66d30f7ccf9c22d2be4fcc41de5e71ef84d85d38 (patch) | |
tree | 43f69ac90a67d10f2a0d490761d1d634c9b1d12e | |
parent | f648924ddddbd66f637a9180769218121e1cd615 (diff) | |
download | rt.equinox.framework-66d30f7ccf9c22d2be4fcc41de5e71ef84d85d38.tar.gz rt.equinox.framework-66d30f7ccf9c22d2be4fcc41de5e71ef84d85d38.tar.xz rt.equinox.framework-66d30f7ccf9c22d2be4fcc41de5e71ef84d85d38.zip |
5 files changed, 135 insertions, 33 deletions
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java index 630313186..71bdc2fe8 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java @@ -102,27 +102,34 @@ public class BundleSpecificationImpl extends VersionConstraintImpl implements Bu result.put(Constants.VISIBILITY_DIRECTIVE, Constants.VISIBILITY_REEXPORT); if (optional) result.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL); - return Collections.unmodifiableMap(result); + result.put(Constants.FILTER_DIRECTIVE, createFilterDirective()); + return result; } } - @Override - protected Map<String, Object> getInteralAttributes() { - Map<String, Object> result = new HashMap<String, Object>(2); + private String createFilterDirective() { + StringBuffer filter = new StringBuffer(); + filter.append("(&"); //$NON-NLS-1$ synchronized (this.monitor) { - if (attributes != null) - result.putAll(attributes); - result.put(BundleRevision.BUNDLE_NAMESPACE, getName()); + addFilterAttribute(filter, BundleRevision.BUNDLE_NAMESPACE, getName()); VersionRange range = getVersionRange(); - if (range != null) - result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, range.toString()); - return Collections.unmodifiableMap(result); + if (range != null && range != VersionRange.emptyRange) + addFilterAttribute(filter, Constants.BUNDLE_VERSION_ATTRIBUTE, range); + if (attributes != null) + addFilterAttributes(filter, attributes); } + filter.append(')'); + return filter.toString(); + } + + @SuppressWarnings("unchecked") + @Override + protected Map<String, Object> getInteralAttributes() { + return Collections.EMPTY_MAP; } @Override protected String getInternalNameSpace() { - // TODO Auto-generated method stub return BundleRevision.BUNDLE_NAMESPACE; } } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java index 2afacb7e5..43aae96f1 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java @@ -139,12 +139,13 @@ public class GenericSpecificationImpl extends VersionConstraintImpl implements G result.put(Constants.FILTER_DIRECTIVE, matchingFilter.toString()); } } - return Collections.unmodifiableMap(result); + return result; } @SuppressWarnings("unchecked") @Override protected Map<String, Object> getInteralAttributes() { + // TODO this needs to return all specified attributes from the Require-Capability header. return Collections.EMPTY_MAP; } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java index e433fa74c..08a9d0ace 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java @@ -114,22 +114,35 @@ public class HostSpecificationImpl extends VersionConstraintImpl implements Host } @SuppressWarnings("unchecked") + @Override protected Map<String, String> getInternalDirectives() { // TODO this does not handle extension directive; but we do not support bootclasspath anyway - return Collections.EMPTY_MAP; + Map<String, String> result = new HashMap<String, String>(2); + synchronized (this.monitor) { + result.put(Constants.FILTER_DIRECTIVE, createFilterDirective()); + return result; + } } - protected Map<String, Object> getInteralAttributes() { - Map<String, Object> result = new HashMap<String, Object>(2); + private String createFilterDirective() { + StringBuffer filter = new StringBuffer(); + filter.append("(&"); //$NON-NLS-1$ synchronized (this.monitor) { - if (attributes != null) - result.putAll(attributes); - result.put(BundleRevision.HOST_NAMESPACE, getName()); + addFilterAttribute(filter, BundleRevision.HOST_NAMESPACE, getName()); VersionRange range = getVersionRange(); - if (range != null) - result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, range.toString()); - return Collections.unmodifiableMap(result); + if (range != null && range != VersionRange.emptyRange) + addFilterAttribute(filter, Constants.BUNDLE_VERSION_ATTRIBUTE, range); + if (attributes != null) + addFilterAttributes(filter, attributes); } + filter.append(')'); + return filter.toString(); + } + + @SuppressWarnings("unchecked") + @Override + protected Map<String, Object> getInteralAttributes() { + return Collections.EMPTY_MAP; } @Override diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java index 6d34edd7f..ac21cbe68 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java @@ -185,26 +185,36 @@ public class ImportPackageSpecificationImpl extends VersionConstraintImpl implem } @SuppressWarnings({"unchecked", "rawtypes"}) + @Override protected Map<String, String> getInternalDirectives() { Map raw = getDirectives(); - return Collections.unmodifiableMap(raw); + raw.put(Constants.FILTER_DIRECTIVE, createFilterDirective()); + return raw; } - protected Map<String, Object> getInteralAttributes() { - Map<String, Object> result = new HashMap<String, Object>(2); + private String createFilterDirective() { + StringBuffer filter = new StringBuffer(); + filter.append("(&"); //$NON-NLS-1$ synchronized (this.monitor) { - if (attributes != null) - result.putAll(attributes); - result.put(BundleRevision.PACKAGE_NAMESPACE, getName()); + addFilterAttribute(filter, BundleRevision.PACKAGE_NAMESPACE, getName(), false); VersionRange range = getVersionRange(); - if (range != null) - result.put(Constants.VERSION_ATTRIBUTE, range.toString()); + if (range != null && range != VersionRange.emptyRange) + addFilterAttribute(filter, Constants.VERSION_ATTRIBUTE, range); if (symbolicName != null) - result.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symbolicName); + addFilterAttribute(filter, Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symbolicName); if (bundleVersionRange != null) - result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersionRange.toString()); - return Collections.unmodifiableMap(result); + addFilterAttribute(filter, Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersionRange); + if (attributes != null) + addFilterAttributes(filter, attributes); } + filter.append(')'); + return filter.toString(); + } + + @SuppressWarnings("unchecked") + @Override + protected Map<String, Object> getInteralAttributes() { + return Collections.EMPTY_MAP; } @Override diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java index d3c8df191..c7949b792 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java @@ -17,6 +17,7 @@ import java.util.Map; import org.eclipse.osgi.framework.internal.core.Constants; import org.eclipse.osgi.internal.resolver.BaseDescriptionImpl.BaseCapability; import org.eclipse.osgi.service.resolver.*; +import org.osgi.framework.Version; import org.osgi.framework.wiring.*; abstract class VersionConstraintImpl implements VersionConstraint { @@ -125,7 +126,7 @@ abstract class VersionConstraintImpl implements VersionConstraint { @SuppressWarnings("unchecked") public Map<String, Object> getAttributes() { - return getInteralAttributes(); + return Collections.unmodifiableMap(getInteralAttributes()); } public BundleRevision getRevision() { @@ -156,4 +157,74 @@ abstract class VersionConstraintImpl implements VersionConstraint { return getNamespace() + BaseDescriptionImpl.toString(getAttributes(), false); } } + + static StringBuffer addFilterAttributes(StringBuffer filter, Map<String, ?> attributes) { + for (Map.Entry<String, ?> entry : attributes.entrySet()) { + addFilterAttribute(filter, entry.getKey(), entry.getValue()); + } + return filter; + } + + static StringBuffer addFilterAttribute(StringBuffer filter, String attr, Object value) { + return addFilterAttribute(filter, attr, value, true); + } + + static private final Version MAX_VERSION = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + + // TODO this is coupled to the implementation detail of version range for open range check + // TODO we need to create a new method on VersionRange to get a filter string and likely should add a FilterBuilder. + static StringBuffer addFilterAttribute(StringBuffer filter, String attr, Object value, boolean escapeWildCard) { + if (value instanceof VersionRange) { + VersionRange range = (VersionRange) value; + if (range.getIncludeMinimum()) { + filter.append('(').append(attr).append(">=").append(escapeValue(range.getMinimum(), escapeWildCard)).append(')'); //$NON-NLS-1$ + } else { + filter.append("(!(").append(attr).append("<=").append(escapeValue(range.getMinimum(), escapeWildCard)).append("))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + // only include the maximum check if this is not an open range + // this check is a bit hacky because we have no method on VersionRange to check if the range really is open + if (!(MAX_VERSION.equals(range.getMaximum()) && range.getIncludeMaximum())) { + if (range.getIncludeMaximum()) { + filter.append('(').append(attr).append("<=").append(escapeValue(range.getMaximum(), escapeWildCard)).append(')'); //$NON-NLS-1$ + } else { + filter.append("(!(").append(attr).append(">=").append(escapeValue(range.getMaximum(), escapeWildCard)).append("))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + } else { + filter.append('(').append(attr).append('=').append(escapeValue(value, escapeWildCard)).append(')'); + } + return filter; + } + + private static String escapeValue(Object o, boolean escapeWildCard) { + String value = o.toString(); + boolean escaped = false; + int inlen = value.length(); + int outlen = inlen << 1; /* inlen * 2 */ + + char[] output = new char[outlen]; + value.getChars(0, inlen, output, inlen); + + int cursor = 0; + for (int i = inlen; i < outlen; i++) { + char c = output[i]; + switch (c) { + case '*' : + if (!escapeWildCard) + break; + case '\\' : + case '(' : + case ')' : + output[cursor] = '\\'; + cursor++; + escaped = true; + break; + } + + output[cursor] = c; + cursor++; + } + + return escaped ? new String(output, 0, cursor) : value; + } } |