diff options
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/internal/core/BundleFragment.java')
-rw-r--r-- | bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/internal/core/BundleFragment.java | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/internal/core/BundleFragment.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/internal/core/BundleFragment.java new file mode 100644 index 000000000..98ca8ee24 --- /dev/null +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/internal/core/BundleFragment.java @@ -0,0 +1,334 @@ +/******************************************************************************* + * Copyright (c) 2003, 2011 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.osgi.framework.internal.core; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import org.eclipse.osgi.framework.adaptor.BundleData; +import org.eclipse.osgi.framework.debug.Debug; +import org.eclipse.osgi.internal.loader.BundleLoader; +import org.eclipse.osgi.util.NLS; +import org.osgi.framework.*; + +public class BundleFragment extends AbstractBundle { + + /** The resolved host that this fragment is attached to */ + protected BundleHost[] hosts; + + /** + * @param bundledata + * @param framework + * @throws BundleException + */ + public BundleFragment(BundleData bundledata, Framework framework) throws BundleException { + super(bundledata, framework); + hosts = null; + } + + /** + * Load the bundle. + */ + protected void load() { + if (Debug.DEBUG_GENERAL) { + if ((state & (INSTALLED)) == 0) { + Debug.println("Bundle.load called when state != INSTALLED: " + this); //$NON-NLS-1$ + Debug.printStackTrace(new Exception("Stack trace")); //$NON-NLS-1$ + } + } + + if (framework.isActive()) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null && framework.securityAdmin != null) { + domain = framework.securityAdmin.createProtectionDomain(this); + } + } + } + + /** + * Reload from a new bundle. + * This method must be called while holding the bundles lock. + * + * @param newBundle Dummy Bundle which contains new data. + * @return true if an exported package is "in use". i.e. it has been imported by a bundle + */ + protected boolean reload(AbstractBundle newBundle) { + if (Debug.DEBUG_GENERAL) { + if ((state & (INSTALLED | RESOLVED)) == 0) { + Debug.println("Bundle.reload called when state != INSTALLED | RESOLVED: " + this); //$NON-NLS-1$ + Debug.printStackTrace(new Exception("Stack trace")); //$NON-NLS-1$ + } + } + + boolean exporting = false; + if (framework.isActive()) { + if (hosts != null) { + if (state == RESOLVED) { + exporting = true; // if we have a host we cannot be removed until the host is refreshed + hosts = null; + state = INSTALLED; + } + } + } else { + /* close the outgoing jarfile */ + try { + this.bundledata.close(); + } catch (IOException e) { + // Do Nothing + } + } + if (!exporting) { + /* close the outgoing jarfile */ + try { + this.bundledata.close(); + } catch (IOException e) { + // Do Nothing + } + } + + this.bundledata = newBundle.bundledata; + this.bundledata.setBundle(this); + // create a new domain for the bundle because its signers/symbolic-name may have changed + if (framework.isActive() && System.getSecurityManager() != null && framework.securityAdmin != null) + domain = framework.securityAdmin.createProtectionDomain(this); + return (exporting); + } + + /** + * Refresh the bundle. This is called by Framework.refreshPackages. + * This method must be called while holding the bundles lock. + * this.loader.unimportPackages must have already been called before calling + * this method! + */ + protected void refresh() { + if (Debug.DEBUG_GENERAL) { + if ((state & (UNINSTALLED | INSTALLED | RESOLVED)) == 0) { + Debug.println("Bundle.refresh called when state != UNINSTALLED | INSTALLED | RESOLVED: " + this); //$NON-NLS-1$ + Debug.printStackTrace(new Exception("Stack trace")); //$NON-NLS-1$ + } + } + + if (state == RESOLVED) { + hosts = null; + state = INSTALLED; + // Do not publish UNRESOLVED event here. This is done by caller + // to resolve if appropriate. + } + manifestLocalization = null; + } + + /** + * Unload the bundle. + * This method must be called while holding the bundles lock. + * + * @return true if an exported package is "in use". i.e. it has been imported by a bundle + */ + protected boolean unload() { + if (Debug.DEBUG_GENERAL) { + if ((state & (UNINSTALLED | INSTALLED | RESOLVED)) == 0) { + Debug.println("Bundle.unload called when state != UNINSTALLED | INSTALLED | RESOLVED: " + this); //$NON-NLS-1$ + Debug.printStackTrace(new Exception("Stack trace")); //$NON-NLS-1$ + } + } + + boolean exporting = false; + if (framework.isActive()) { + if (hosts != null) { + if (state == RESOLVED) { + exporting = true; // if we have a host we cannot be removed until the host is refreshed + hosts = null; + state = INSTALLED; + } + domain = null; + } + } + if (!exporting) { + try { + this.bundledata.close(); + } catch (IOException e) { // Do Nothing. + } + } + + return (exporting); + } + + /** + * This method loads a class from the bundle. + * + * @param name the name of the desired Class. + * @param checkPermission indicates whether a permission check should be done. + * @return the resulting Class + * @exception java.lang.ClassNotFoundException if the class definition was not found. + */ + protected Class<?> loadClass(String name, boolean checkPermission) throws ClassNotFoundException { + if (checkPermission) { + try { + framework.checkAdminPermission(this, AdminPermission.CLASS); + } catch (SecurityException e) { + throw new ClassNotFoundException(name, e); + } + checkValid(); + } + // cannot load a class from a fragment because there is no classloader + // associated with fragments. + throw new ClassNotFoundException(NLS.bind(Msg.BUNDLE_FRAGMENT_CNFE, name)); + } + + /** + * Find the specified resource in this bundle. + * + * This bundle's class loader is called to search for the named resource. + * If this bundle's state is <tt>INSTALLED</tt>, then only this bundle will + * be searched for the specified resource. Imported packages cannot be searched + * when a bundle has not been resolved. + * + * @param name The name of the resource. + * See <tt>java.lang.ClassLoader.getResource</tt> for a description of + * the format of a resource name. + * @return a URL to the named resource, or <tt>null</tt> if the resource could + * not be found or if the caller does not have + * the <tt>AdminPermission</tt>, and the Java Runtime Environment supports permissions. + * + * @exception java.lang.IllegalStateException If this bundle has been uninstalled. + */ + public URL getResource(String name) { + checkValid(); + // cannot get a resource for a fragment because there is no classloader + // associated with fragments. + return (null); + + } + + public Enumeration<URL> getResources(String name) { + checkValid(); + // cannot get a resource for a fragment because there is no classloader + // associated with fragments. + return null; + } + + /** + * Internal worker to start a bundle. + * + * @param options + */ + protected void startWorker(int options) throws BundleException { + throw new BundleException(NLS.bind(Msg.BUNDLE_FRAGMENT_START, this), BundleException.INVALID_OPERATION); + } + + /** + * Internal worker to stop a bundle. + * + * @param options + */ + protected void stopWorker(int options) throws BundleException { + throw new BundleException(NLS.bind(Msg.BUNDLE_FRAGMENT_STOP, this), BundleException.INVALID_OPERATION); + } + + /** + * Provides a list of {@link ServiceReference}s for the services + * registered by this bundle + * or <code>null</code> if the bundle has no registered + * services. + * + * <p>The list is valid at the time + * of the call to this method, but the framework is a very dynamic + * environment and services can be modified or unregistered at anytime. + * + * @return An array of {@link ServiceReference} or <code>null</code>. + * @exception java.lang.IllegalStateException If the + * bundle has been uninstalled. + * @see ServiceRegistration + * @see ServiceReference + */ + public ServiceReference<?>[] getRegisteredServices() { + checkValid(); + // Fragments cannot have a BundleContext and therefore + // cannot have any services registered. + return null; + } + + /** + * Provides a list of {@link ServiceReference}s for the + * services this bundle is using, + * or <code>null</code> if the bundle is not using any services. + * A bundle is considered to be using a service if the bundle's + * use count for the service is greater than zero. + * + * <p>The list is valid at the time + * of the call to this method, but the framework is a very dynamic + * environment and services can be modified or unregistered at anytime. + * + * @return An array of {@link ServiceReference} or <code>null</code>. + * @exception java.lang.IllegalStateException If the + * bundle has been uninstalled. + * @see ServiceReference + */ + public ServiceReference<?>[] getServicesInUse() { + checkValid(); + // Fragments cannot have a BundleContext and therefore + // cannot have any services in use. + return null; + } + + synchronized BundleHost[] getHosts() { + return hosts; + } + + protected boolean isFragment() { + return true; + } + + /** + * Adds a host bundle for this fragment. + * @param host the BundleHost to add to the set of host bundles + */ + boolean addHost(BundleHost host) { + if (host == null) + return false; + try { + host.attachFragment(this); + } catch (BundleException be) { + framework.publishFrameworkEvent(FrameworkEvent.ERROR, host, be); + return false; + } + synchronized (this) { + if (hosts == null) { + hosts = new BundleHost[] {host}; + return true; + } + for (int i = 0; i < hosts.length; i++) { + if (host == hosts[i]) + return true; // already a host + } + BundleHost[] newHosts = new BundleHost[hosts.length + 1]; + System.arraycopy(hosts, 0, newHosts, 0, hosts.length); + newHosts[newHosts.length - 1] = host; + hosts = newHosts; + } + return true; + } + + protected BundleLoader getBundleLoader() { + // Fragments cannot have a BundleLoader. + return null; + } + + /** + * Return the current context for this bundle. + * + * @return BundleContext for this bundle. + */ + protected BundleContextImpl getContext() { + // Fragments cannot have a BundleContext. + return null; + } +} |