/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* 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:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package org.ant4eclipse.lib.pde.model.pluginproject;
import org.ant4eclipse.lib.core.Assure;
import org.ant4eclipse.lib.platform.model.resource.EclipseProject;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Constants;
import java.io.File;
import java.util.jar.Manifest;
/**
* The {@link BundleSource} wraps the source of a bundle (e.g. an eclipse plug-in project, a jared bundle or an exploded
* bundle).
*
* @author Gerd Wütherich (gerd@gerd-wuetherich.de)
*/
public class BundleSource {
/**
* <p>
* Extracts the {@link BundleSource} for the given {@link BundleDescription}. If the bundle source is not set, a
* {@link RuntimeException} will be thrown.
* </p>
*
* @param bundleDescription
* the bundle description.
* @return the bundle source.
*/
public static BundleSource getBundleSource(BundleDescription bundleDescription) {
Assure.notNull("bundleDescription", bundleDescription);
// retrieve the user object (that is always an instance of type BundleSource in our case)
BundleSource bundleSource = (BundleSource) bundleDescription.getUserObject();
// throw RuntimeException if the bundle source is not set
if (bundleSource == null) {
throw new RuntimeException("Bundle '" + bundleDescription + "' doesn't have a user object!");
}
// return result
return bundleSource;
}
/** the bundle source */
private Object _source;
/** The properties read from the manifest (=headers) */
private Manifest _bundleManifest;
/** The file or directory to load classes from. This might point to a directory. */
private File _classpathRoot;
/**
* <p>
* Creates a new instance of type {@link BundleSource}.
* </p>
*
* @param source
* the bundle source (e.g. an eclipse plug-in project, a jared bundle or an exploded bundle)
* @param bundleManifest
* the bundle manifest
*/
public BundleSource(Object source, Manifest bundleManifest) {
Assure.notNull("source", source);
Assure.notNull("bundleManifest", bundleManifest);
this._source = source;
this._bundleManifest = bundleManifest;
if (source instanceof File) {
this._classpathRoot = (File) source;
} else if (source instanceof EclipseProject) {
this._classpathRoot = ((EclipseProject) source).getFolder();
}
}
/**
* <p>
* Returns the bundle source. The result type can be {@link EclipseProject} or {@link File}.
* </p>
*
* @return the bundle source.
*/
public Object getSource() {
return this._source;
}
/**
* <p>
* Returns <code>true</code>, if the bundle source is of type {@link EclipseProject}.
* </p>
*
* @return <code>true</code>, if the bundle source is of type {@link EclipseProject}.
*/
public boolean isEclipseProject() {
return this._source instanceof EclipseProject;
}
/**
* <p>
* Returns the bundle source as an {@link EclipseProject}. If the bundle source is not an instance of type
* {@link EclipseProject}, a {@link RuntimeException} will be thrown.
* </p>
*
* @return the bundle source.
*/
public EclipseProject getAsEclipseProject() {
Assure.assertTrue(isEclipseProject(), "Bundle source has to be instance of Eclipse Project");
return (EclipseProject) this._source;
}
/**
* <p>
* Returns the bundle source as an {@link File}. If the bundle source is not an instance of type {@link File}, a
* {@link RuntimeException} will be thrown.
* </p>
*
* @return the bundle source.
*/
public File getAsFile() {
Assure.assertTrue(this._source instanceof File, "Bundle source has to be instance of File");
return (File) this._source;
}
/**
* <p>
* Returns the bundle manifest.
* </p>
*
* @return the bundle manifest.
*/
public Manifest getBundleManifest() {
return this._bundleManifest;
}
/**
* <p>
* Returns <code>true</code> if a class path root has already been set. If this methods returns <code>false</code> it
* indicates that the {@link JarUtilities} hasn't run on this bundle yet.
* </p>
*
* @return <code>true</code> if a class path root has already been set.
*/
public boolean hasClasspathRoot() {
return this._classpathRoot != null;
}
/**
* <p>
* Returns the class path root or <code>null</code>. The class path root is set through the {@link JarUtilities}.
* </p>
*
* @return the class path root or <code>null</code>.
*/
public File getClasspathRoot() {
return this._classpathRoot;
}
/**
* <p>
* Sets the class path root.
* </p>
* <p>
* Note: this method should only be called through the {@link JarUtilities}.
* </p>
*
* @param classpathRoot
* the class path root
*/
public void setClasspathRoot(File classpathRoot) {
Assure.notNull("classpathRoot", classpathRoot);
Assure.assertTrue(!hasClasspathRoot(), "Classpath root already set!");
this._classpathRoot = classpathRoot;
}
/**
* <p>
* Returns the 'Bundle-Classpath' entries or <code>.</code> if no 'Bundle-Classpath' has been specified (default
* value).
* </p>
*
* @return the 'Bundle-Classpath' entries or <code>.</code> if no 'Bundle-Classpath' has been specified.
*/
public String[] getBundleClasspath() {
// parse the 'Bundle-Classpath' manifest entry
String[] bundleClasspath = ManifestElement.getArrayFromList(this._bundleManifest.getMainAttributes().getValue(
Constants.BUNDLE_CLASSPATH));
// set default if necessary
if ((bundleClasspath == null) || (bundleClasspath.length < 1)) {
bundleClasspath = new String[] { "." };
}
// return result
return bundleClasspath;
}
/**
* <p>
* Returns the name of the bundle as specified in the 'Bundle-Name' header or the bundles Symbolic-Name if no
* 'Bundle-Name' header is specified.
* </p>
*
* @return the name of the bundle as specified in the 'Bundle-Name' header or the bundles Symbolic-Name if no
* 'Bundle-Name' header is specified.
*/
public String getBundleName() {
// retrieve the bundle name
String bundleName = this._bundleManifest.getMainAttributes().getValue(Constants.BUNDLE_NAME);
// retrieve the bundle symbolic name if necessary
if (bundleName == null) {
bundleName = this._bundleManifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
}
// return result
return bundleName;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[BundleSource:");
buffer.append(" _source: ");
buffer.append(this._source);
buffer.append(" _bundleManifest: ");
buffer.append(this._bundleManifest);
buffer.append(" _classpathRoot: ");
buffer.append(this._classpathRoot);
buffer.append("]");
return buffer.toString();
}
}