/******************************************************************************* * 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; } } } }