/*******************************************************************************
 * Copyright (c) 2003, 2010 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.internal.permadmin.SecurityAdmin;
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 && 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) {
				SecurityAdmin sa = framework.getCoreServicesFactory().getSecurityAdmin(this);
				domain = sa.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 && 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) {
					// add the bundle data to the list of removals
					framework.getPackageAdminImpl().addRemovalPending(bundledata);
					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) {
			SecurityAdmin sa = framework.getCoreServicesFactory().getSecurityAdmin(this);
			domain = sa.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 && 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 && 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) {
					// add the bundle data to the list of removals
					framework.getPackageAdminImpl().addRemovalPending(bundledata);
					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 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[] getBundleHosts() {
		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;
	}
}
