diff options
3 files changed, 62 insertions, 26 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java index 60ce2aca2..90b5fa7a5 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/builders/OSGiManifestBuilderFactory.java @@ -740,14 +740,15 @@ public final class OSGiManifestBuilderFactory { boolean optional = elements.length > 0 && elements[elements.length - 1].getValue().equals("*"); //$NON-NLS-1$ - List<String> allSelectionFilters = new ArrayList<String>(0); AliasMapper aliasMapper = new AliasMapper(); - StringBuilder allFilters = new StringBuilder(); - allFilters.append("(|"); //$NON-NLS-1$ + List<List<String>> allNativePaths = new ArrayList<List<String>>(); + List<String> allSelectionFilters = new ArrayList<String>(0); + StringBuilder allNativeFilters = new StringBuilder(); + allNativeFilters.append("(|"); //$NON-NLS-1$ for (ManifestElement nativeCode : elements) { - List<String> nativePaths = new ArrayList<String>(Arrays.asList(nativeCode.getValueComponents())); - StringBuilder filter = new StringBuilder(); + allNativePaths.add(new ArrayList<String>(Arrays.asList(nativeCode.getValueComponents()))); + StringBuilder filter = new StringBuilder(); filter.append("(&"); //$NON-NLS-1$ addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_OSNAME, aliasMapper); addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_PROCESSOR, aliasMapper); @@ -755,36 +756,42 @@ public final class OSGiManifestBuilderFactory { addToNativeCodeFilter(filter, nativeCode, Constants.BUNDLE_NATIVECODE_LANGUAGE, aliasMapper); filter.append(')'); - allFilters.append(filter.toString()); - Map<String, String> directives = new HashMap<String, String>(3); - directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString()); - directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, EquinoxNativeEnvironmentNamespace.RESOLUTION_OPTIONAL); + allNativeFilters.append(filter.toString()); String selectionFilter = nativeCode.getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE); if (selectionFilter != null) { allSelectionFilters.add(selectionFilter); - directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_SELECTION_FILTER_DIRECTIVE, selectionFilter); } + } + allNativeFilters.append(')'); - Map<String, Object> attributes = new HashMap<String, Object>(2); - attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE, nativePaths); - builder.addRequirement(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE, directives, attributes); + Map<String, String> directives = new HashMap<String, String>(2); + directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, allNativeFilters.toString()); + if (optional) { + directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, EquinoxNativeEnvironmentNamespace.RESOLUTION_OPTIONAL); } - allFilters.append(')'); - if (!optional) { - Map<String, String> directives = new HashMap<String, String>(2); - directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, allFilters.toString()); - if (!allSelectionFilters.isEmpty()) { - StringBuilder selectionFilter = new StringBuilder(); - selectionFilter.append("(|"); //$NON-NLS-1$ - for (String filter : allSelectionFilters) { - selectionFilter.append(filter); - } - selectionFilter.append(")"); //$NON-NLS-1$ - directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_SELECTION_FILTER_DIRECTIVE, selectionFilter.toString()); + Map<String, Object> attributes = new HashMap<String, Object>(0); + int i = 0; + int numNativePaths = allNativePaths.size(); + for (List<String> nativePaths : allNativePaths) { + if (numNativePaths == 0) { + attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE, nativePaths); + } else { + attributes.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE + '.' + i, nativePaths); + } + i++; + } + + if (!allSelectionFilters.isEmpty()) { + StringBuilder selectionFilter = new StringBuilder(); + selectionFilter.append("(|"); //$NON-NLS-1$ + for (String filter : allSelectionFilters) { + selectionFilter.append(filter); } - builder.addRequirement(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE, directives, Collections.<String, Object> emptyMap()); + selectionFilter.append(")"); //$NON-NLS-1$ + directives.put(EquinoxNativeEnvironmentNamespace.REQUIREMENT_SELECTION_FILTER_DIRECTIVE, selectionFilter.toString()); } + builder.addRequirement(EquinoxNativeEnvironmentNamespace.NATIVE_ENVIRONMENT_NAMESPACE, directives, attributes); } private static void addToNativeCodeFilter(StringBuilder filter, ManifestElement nativeCode, String attribute, AliasMapper aliasMapper) { 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 032391dc8..d0995a9c2 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 @@ -1357,6 +1357,13 @@ public class FilterImpl implements Filter /* since Framework 1.1 */{ return null; } + public List<FilterImpl> getChildren() { + if (value instanceof FilterImpl[]) { + return new ArrayList<FilterImpl>(Arrays.asList((FilterImpl[]) value)); + } + return Collections.emptyList(); + } + /** * Returns all the attributes contained within this filter * @return all the attributes contained within this filter diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/NativeCodeFinder.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/NativeCodeFinder.java index 1708f5d74..7bdb62cab 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/NativeCodeFinder.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/NativeCodeFinder.java @@ -16,10 +16,12 @@ import java.util.*; import org.eclipse.osgi.container.*; import org.eclipse.osgi.container.namespaces.EquinoxNativeEnvironmentNamespace; import org.eclipse.osgi.internal.debug.Debug; +import org.eclipse.osgi.internal.framework.FilterImpl; import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook; import org.eclipse.osgi.storage.BundleInfo.Generation; import org.eclipse.osgi.storage.bundlefile.BundleEntry; import org.eclipse.osgi.storage.bundlefile.BundleFile; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.namespace.HostNamespace; import org.osgi.framework.wiring.BundleRevision; @@ -175,6 +177,26 @@ public class NativeCodeFinder { List<String> result = (List<String>) nativeCode.get(0).getRequirement().getAttributes().get(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE); if (result != null) return result; + // this must be a multi-clause Bundle-NativeCode header, need to check for the correct one in the index + try { + FilterImpl filter = FilterImpl.newInstance(moduleWire.getRequirement().getDirectives().get(EquinoxNativeEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE)); + int index = -1; + Map<String, Object> capabilityAttrs = moduleWire.getCapability().getAttributes(); + for (FilterImpl child : filter.getChildren()) { + index++; + if (child.matches(capabilityAttrs)) { + break; + } + } + if (index != -1) { + @SuppressWarnings("unchecked") + List<String> indexResult = (List<String>) nativeCode.get(0).getRequirement().getAttributes().get(EquinoxNativeEnvironmentNamespace.REQUIREMENT_NATIVE_PATHS_ATTRIBUTE + '.' + index); + if (indexResult != null) + return indexResult; + } + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } } } return Collections.emptyList(); |