diff options
author | Thomas Watson | 2013-06-27 13:59:57 +0000 |
---|---|---|
committer | John Arthorne | 2013-06-27 13:59:57 +0000 |
commit | 14de0249b7f2694efabfd190653eb9436fec2de6 (patch) | |
tree | eada2c9750985d50653f8825eb000c1fa7d71d43 | |
parent | 370347c6e8151af475c2c8eb230dab9dc1bd6e86 (diff) | |
download | rt.equinox.p2-14de0249b7f2694efabfd190653eb9436fec2de6.tar.gz rt.equinox.p2-14de0249b7f2694efabfd190653eb9436fec2de6.tar.xz rt.equinox.p2-14de0249b7f2694efabfd190653eb9436fec2de6.zip |
Bug 411046 - Remove usage of equinox resolver API from simple
configurator
4 files changed, 106 insertions, 89 deletions
diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF index 59c67e474..0dec7d92e 100644 --- a/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.equinox.simpleconfigurator;singleton:=true -Bundle-Version: 1.0.400.qualifier +Bundle-Version: 1.1.0.qualifier Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -9,8 +9,10 @@ Bundle-Activator: org.eclipse.equinox.internal.simpleconfigurator.Activator Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.osgi.framework.console;version="1.0.0";resolution:=optional, org.eclipse.osgi.service.datalocation;version="1.0.0";resolution:=optional, - org.eclipse.osgi.service.resolver;version="1.2.0";resolution:=optional, org.osgi.framework;version="1.3.0", + org.osgi.framework.namespace;version="1.0.0", + org.osgi.framework.wiring;version="1.1.0", + org.osgi.resource;version="1.0.0", org.osgi.service.packageadmin;version="1.2.0", org.osgi.service.startlevel;version="1.0.0", org.osgi.util.tracker;version="1.3.0" diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml b/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml index d06a0b5dd..3d8c6bb1b 100644 --- a/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml +++ b/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml @@ -9,6 +9,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.simpleconfigurator</artifactId> - <version>1.0.400-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/ConfigApplier.java b/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/ConfigApplier.java index dc3ca9693..d17f8cca7 100644 --- a/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/ConfigApplier.java +++ b/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/ConfigApplier.java @@ -14,6 +14,10 @@ import java.net.URL; import java.util.*; import org.eclipse.equinox.internal.simpleconfigurator.utils.*; import org.osgi.framework.*; +import org.osgi.framework.namespace.*; +import org.osgi.framework.wiring.*; +import org.osgi.resource.Namespace; +import org.osgi.resource.Requirement; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.startlevel.StartLevel; @@ -24,6 +28,7 @@ class ConfigApplier { private final BundleContext manipulatingContext; private final PackageAdmin packageAdminService; private final StartLevel startLevelService; + private final FrameworkWiring frameworkWiring; private final boolean runningOnEquinox; private final boolean inDevMode; @@ -46,6 +51,8 @@ class ConfigApplier { if (startLevelRef == null) throw new IllegalStateException("No StartLevelService service is available."); //$NON-NLS-1$ startLevelService = (StartLevel) manipulatingContext.getService(startLevelRef); + + frameworkWiring = (FrameworkWiring) manipulatingContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class); } void install(URL url, boolean exclusiveMode) throws IOException { @@ -94,20 +101,103 @@ class ConfigApplier { toRefresh.addAll(uninstallBundles(toUninstall)); } refreshPackages((Bundle[]) toRefresh.toArray(new Bundle[toRefresh.size()]), manipulatingContext); - if (toRefresh.size() > 0) - try { - manipulatingContext.getBundle().loadClass("org.eclipse.osgi.service.resolver.PlatformAdmin"); //$NON-NLS-1$ - // now see if there are any currently resolved bundles with option imports which could be resolved or - // if there are fragments with additional constraints which conflict with an already resolved host - Bundle[] additionalRefresh = StateResolverUtils.getAdditionalRefresh(prevouslyResolved, manipulatingContext); - if (additionalRefresh.length > 0) - refreshPackages(additionalRefresh, manipulatingContext); - } catch (ClassNotFoundException cnfe) { - // do nothing; no resolver package available - } + if (toRefresh.size() > 0) { + Bundle[] additionalRefresh = getAdditionalRefresh(prevouslyResolved, toRefresh); + if (additionalRefresh.length > 0) + refreshPackages(additionalRefresh, manipulatingContext); + } startBundles((Bundle[]) toStart.toArray(new Bundle[toStart.size()])); } + private Bundle[] getAdditionalRefresh(Collection previouslyResolved, Collection toRefresh) { + // This is the luna equinox framework or a non-equinox framework. + // Use standard OSGi API. + final Set additionalRefresh = new HashSet(); + final Set originalRefresh = new HashSet(toRefresh); + for (Iterator iToRefresh = toRefresh.iterator(); iToRefresh.hasNext();) { + Bundle bundle = (Bundle) iToRefresh.next(); + BundleRevision revision = (BundleRevision) bundle.adapt(BundleRevision.class); + if (bundle.getState() == Bundle.INSTALLED && revision != null && (revision.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { + // this is an unresolved fragment; look to see if it has additional payload requirements + boolean foundPayLoadReq = false; + BundleRequirement hostReq = null; + Collection requirements = revision.getRequirements(null); + for (Iterator iReqs = requirements.iterator(); iReqs.hasNext();) { + BundleRequirement req = (BundleRequirement) iReqs.next(); + if (HostNamespace.HOST_NAMESPACE.equals(req.getNamespace())) { + hostReq = req; + } + if (!HostNamespace.HOST_NAMESPACE.equals(req.getNamespace()) && !ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(req.getNamespace())) { + // found a payload requirement + foundPayLoadReq = true; + } + } + if (foundPayLoadReq) { + Collection candidates = frameworkWiring.findProviders(hostReq); + for (Iterator iCandidates = candidates.iterator(); iCandidates.hasNext();) { + BundleCapability candidate = (BundleCapability) iCandidates.next(); + if (!originalRefresh.contains(candidate.getRevision().getBundle())) { + additionalRefresh.add(candidate.getRevision().getBundle()); + } + } + } + } + } + + for (Iterator iPreviouslyResolved = previouslyResolved.iterator(); iPreviouslyResolved.hasNext();) { + Bundle bundle = (Bundle) iPreviouslyResolved.next(); + BundleRevision revision = (BundleRevision) bundle.adapt(BundleRevision.class); + BundleWiring wiring = revision == null ? null : revision.getWiring(); + if (wiring != null) { + Collection reqs = revision.getDeclaredRequirements(null); + Set optionalReqs = new HashSet(); + for (Iterator iReqs = reqs.iterator(); iReqs.hasNext();) { + BundleRequirement req = (BundleRequirement) iReqs.next(); + String namespace = req.getNamespace(); + // only do this for package and bundle namespaces + if (PackageNamespace.PACKAGE_NAMESPACE.equals(namespace) || BundleNamespace.BUNDLE_NAMESPACE.equals(namespace)) { + if (Namespace.RESOLUTION_OPTIONAL.equals(req.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE))) { + optionalReqs.add(req); + } + } + } + if (!optionalReqs.isEmpty()) { + wiring = getFragmentWiring(wiring); + // check that all optional requirements are wired + Collection requiredWires = wiring.getRequiredWires(null); + for (Iterator iRequiredWires = requiredWires.iterator(); iRequiredWires.hasNext();) { + BundleWire requiredWire = (BundleWire) iRequiredWires.next(); + optionalReqs.remove(requiredWire.getRequirement()); + } + if (!optionalReqs.isEmpty()) { + // there are a number of optional requirements not wired + for (Iterator iOptionalReqs = optionalReqs.iterator(); iOptionalReqs.hasNext();) { + Collection candidates = frameworkWiring.findProviders((Requirement) iOptionalReqs.next()); + if (!candidates.isEmpty()) { + additionalRefresh.add(wiring.getBundle()); + } + } + } + } + } + } + return (Bundle[]) additionalRefresh.toArray(new Bundle[additionalRefresh.size()]); + } + + private BundleWiring getFragmentWiring(BundleWiring wiring) { + if ((wiring.getRevision().getTypes() & BundleRevision.TYPE_FRAGMENT) == 0) { + // not a fragment + return wiring; + } + Collection hostWires = wiring.getRequiredWires(HostNamespace.HOST_NAMESPACE); + // just use the first host wiring + if (hostWires.isEmpty()) { + return wiring; + } + BundleWire hostWire = (BundleWire) hostWires.iterator().next(); + return hostWire.getProviderWiring(); + } + private Collection getResolvedBundles() { Collection resolved = new HashSet(); Bundle[] allBundles = manipulatingContext.getBundles(); diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/utils/StateResolverUtils.java b/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/utils/StateResolverUtils.java deleted file mode 100644 index 0b1b5f935..000000000 --- a/bundles/org.eclipse.equinox.simpleconfigurator/src/org/eclipse/equinox/internal/simpleconfigurator/utils/StateResolverUtils.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 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.equinox.internal.simpleconfigurator.utils; - -import java.util.*; -import org.eclipse.osgi.service.resolver.*; -import org.osgi.framework.*; - -public class StateResolverUtils { - - public static Bundle[] getAdditionalRefresh(Collection currentResolved, BundleContext context) { - ServiceReference ref = context.getServiceReference(PlatformAdmin.class.getName()); - if (ref == null) - return new Bundle[0]; - PlatformAdmin platformAdmin = (PlatformAdmin) context.getService(ref); - if (platformAdmin == null) - return new Bundle[0]; - try { - State state = platformAdmin.getState(false); - BundleDescription[] bundles = state.getBundles(); - HashSet results = new HashSet(bundles.length); - getAdditionRefresh(bundles, state, currentResolved, results, context); - return (Bundle[]) results.toArray(new Bundle[results.size()]); - } finally { - context.ungetService(ref); - } - } - - private static void getAdditionRefresh(BundleDescription[] bundleDescriptions, State state, Collection currentResolved, Set results, BundleContext context) { - bundles: for (int i = 0; i < bundleDescriptions.length; i++) { - Bundle bundle = context.getBundle(bundleDescriptions[i].getBundleId()); - if (bundle == null) - continue bundles; - // look for a fragment which adds a conflicted constraint to an already resolved host - if (!bundleDescriptions[i].isResolved() && bundleDescriptions[i].getHost() != null) { - ResolverError[] errors = state.getResolverErrors(bundleDescriptions[i]); - for (int j = 0; j < errors.length; j++) { - if ((errors[j].getType() & ResolverError.FRAGMENT_CONFLICT) != 0) { - BundleDescription[] possibleHosts = state.getBundles(bundleDescriptions[i].getHost().getName()); - for (int k = 0; k < possibleHosts.length; k++) { - Bundle hostBundle = context.getBundle(possibleHosts[k].getBundleId()); - if (hostBundle != null && currentResolved.contains(hostBundle) && bundleDescriptions[i].getHost().isSatisfiedBy(possibleHosts[k])) - results.add(hostBundle); - } - } - } - continue bundles; - } - if (!currentResolved.contains(bundle) || !bundleDescriptions[i].isResolved()) - continue bundles; - // look for optional imports which are unresolved but are resolvable - ImportPackageSpecification[] imports = bundleDescriptions[i].getImportPackages(); - for (int j = 0; j < imports.length; j++) - if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(imports[j].getDirective(Constants.RESOLUTION_DIRECTIVE)) && !imports[j].isResolved() && state.getStateHelper().isResolvable(imports[j])) { - results.add(bundle); - continue bundles; - } - // look for optional requires which are unresolved but are resolvable - BundleSpecification[] requires = bundleDescriptions[i].getRequiredBundles(); - for (int j = 0; j < requires.length; j++) - if (requires[j].isOptional() && !requires[j].isResolved() && state.getStateHelper().isResolvable(requires[j])) { - results.add(bundle); - continue bundles; - } - } - } -} |