/******************************************************************************* * Copyright (c) 2008, 2010 VMware Inc. * 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: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.kernel.userregion.internal.equinox; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.eclipse.osgi.framework.internal.core.FrameworkProperties; import org.eclipse.osgi.service.resolver.PlatformAdmin; import org.eclipse.osgi.service.resolver.State; import org.eclipse.virgo.kernel.osgi.framework.ManifestTransformer; import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkUtils; import org.eclipse.virgo.kernel.osgi.framework.OsgiServiceHolder; import org.eclipse.virgo.kernel.osgi.framework.support.AbstractOsgiFramework; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.PackageAdmin; /** * Implementation of <code>OsgiFramework</code> using Equinox. * */ @SuppressWarnings("deprecation") public class EquinoxOsgiFramework extends AbstractOsgiFramework { private static final String FILE_SCHEME = "file:"; private static final String REFERENCE_SCHEME = "reference:"; private final OsgiServiceHolder<PlatformAdmin> platformAdmin; private final EquinoxBootDelegationHelper bootDelegationHelper; private final TransformedManifestProvidingBundleFileWrapper bundleTransformationHandler; /** * Creates a new <code>EquinoxOsgiFramework</code>. * @param context execution context of bundle * @param packageAdmin framework service for access to {@link State} * @param bundleTransformationHandler wrapper for bundle manifest transformations */ public EquinoxOsgiFramework(BundleContext context, PackageAdmin packageAdmin, TransformedManifestProvidingBundleFileWrapper bundleTransformationHandler) { super(context, packageAdmin); this.bootDelegationHelper = new EquinoxBootDelegationHelper(FrameworkProperties.getProperty(org.osgi.framework.Constants.FRAMEWORK_BOOTDELEGATION)); this.platformAdmin = OsgiFrameworkUtils.getService(context, PlatformAdmin.class); this.bundleTransformationHandler = bundleTransformationHandler; } /** * {@inheritDoc} */ public void refresh(Bundle bundle) throws BundleException { ClassLoader cl = getBundleClassLoader(bundle); List<Bundle> refreshBundles = new ArrayList<Bundle>(); if (cl instanceof KernelBundleClassLoader) { KernelBundleClassLoader pbcl = (KernelBundleClassLoader) cl; if (pbcl.isInstrumented()) { Bundle[] dependencies = getDirectDependencies(bundle); for (Bundle dependency : dependencies) { if (OsgiFrameworkUtils.sameScope(bundle, dependency)) { dependency.update(); refreshBundles.add(dependency); } } } } bundle.update(); refreshBundles.add(bundle); Bundle[] toRefresh = refreshBundles.toArray(new Bundle[refreshBundles.size()]); getPackageAdmin().refreshPackages(toRefresh); } final void stop() { if (this.platformAdmin != null) { getBundleContext().ungetService(this.platformAdmin.getServiceReference()); } } /** * {@inheritDoc} */ public ClassLoader getBundleClassLoader(Bundle bundle) { return EquinoxUtils.getBundleClassLoader(bundle); } /** * {@inheritDoc} */ public boolean isBootDelegated(String className) { if (this.bootDelegationHelper != null) { return this.bootDelegationHelper.isBootDelegated(className); } throw new IllegalStateException("OsgiFramework must have been started prior to querying its boot delegation"); } /** * {@inheritDoc} */ public Bundle[] getDirectDependencies(Bundle bundle, boolean includeFragments) { BundleContext bundleContext = getBundleContext(); ServiceReference<PlatformAdmin> serviceRef = bundleContext.getServiceReference(PlatformAdmin.class); try { PlatformAdmin serverAdmin = (PlatformAdmin) bundleContext.getService(serviceRef); return EquinoxUtils.getDirectDependencies(bundle, bundleContext, serverAdmin, includeFragments); } finally { bundleContext.ungetService(serviceRef); } } /** * {@inheritDoc} */ public Bundle[] getDirectDependencies(Bundle bundle) { return getDirectDependencies(bundle, false); } /** * {@inheritDoc} */ public void update(Bundle bundle, ManifestTransformer manifestTransformer, File location) throws BundleException { this.bundleTransformationHandler.pushManifestTransformer(manifestTransformer); try { bundle.update(openBundleStream(location)); } finally { this.bundleTransformationHandler.popManifestTransformer(); } } private InputStream openBundleStream(File location) throws BundleException { String absoluteBundleUriString = getAbsoluteUriString(location); try { // Use the reference: scheme to obtain an InputStream for either a file or a directory. return new URL(REFERENCE_SCHEME + absoluteBundleUriString).openStream(); } catch (MalformedURLException e) { throw new BundleException("Invalid bundle URI '" + absoluteBundleUriString + "'", e); } catch (IOException e) { throw new BundleException("Invalid bundle at URI '" + absoluteBundleUriString + "'", e); } } private String getAbsoluteUriString(File location) throws BundleException { return FILE_SCHEME + location.getAbsolutePath(); } }