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