/********************************************************************** * 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.internal.model.pluginproject; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Iterator; import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.ant4eclipse.lib.core.Assure; import org.ant4eclipse.lib.core.logging.A4ELogging; import org.ant4eclipse.lib.pde.PdeExceptionCode; import org.ant4eclipse.lib.pde.model.pluginproject.BundleSource; import org.ant4eclipse.lib.pde.model.pluginproject.Constants; import org.ant4eclipse.lib.platform.model.resource.EclipseProject; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.StateObjectFactory; import org.osgi.framework.BundleException; public class BundleDescriptionLoader { /** - */ public static StateObjectFactory _factory = StateObjectFactory.defaultFactory; /** - */ // TODO: ueberarbeiten.. private static long COUNTER = 1l; /** * <p> * </p> * * @param project * @return * @throws IOException * @throws FileNotFoundException * @throws BundleException */ public static BundleDescription loadFromPluginProject(EclipseProject project) throws FileNotFoundException, IOException, BundleException { Assure.notNull("project", project); File manifestFile = project.getChild(Constants.OSGI_BUNDLE_MANIFEST); // TODO: handle projects with plugin.xml that may not have a MANIFEST-file Manifest manifest = new Manifest(new FileInputStream(manifestFile)); BundleDescription description = createBundleDescription(manifest, project.getFolder().getAbsolutePath(), project); BundleSource.getBundleSource(description); return description; } private static BundleDescription createBundleDescription(Manifest manifest, String path, Object source) throws BundleException { long counter = isSystemBundle(manifest) ? 0 : COUNTER++; Properties manifestProperties = convertManifest(manifest); BundleDescription bundleDescription = _factory.createBundleDescription(null, manifestProperties, path, counter); bundleDescription.setUserObject(new BundleSource(source, manifest)); return bundleDescription; } private static boolean isSystemBundle(Manifest manifest) { String isSystemBundle = manifest.getMainAttributes().getValue("Eclipse-SystemBundle"); return "true".equals(isSystemBundle); } /** * <p> * </p> * * @param manifest * @return */ @SuppressWarnings("rawtypes") private static Properties convertManifest(Manifest manifest) { Attributes attributes = manifest.getMainAttributes(); Iterator iter = attributes.keySet().iterator(); Properties result = new Properties(); while (iter.hasNext()) { Attributes.Name key = (Attributes.Name) iter.next(); result.put(key.toString(), attributes.get(key)); } return result; } /** * Parses the given plugin (which might be a jar-file or a directory) and returns its BundleDescription or null if the * Plugin doesn't contain a MANIFEST-File * * @param file * @return * @throws FileParserException */ public static BundleDescription parsePlugin(File file) { Assure.exists("file", file); BundleDescription description = null; try { if (file.isFile() && file.getName().endsWith(".jar")) { description = parsePluginJarFile(file); } else if (file.isDirectory()) { description = parsePluginDirectory(file); } if (description == null && A4ELogging.isDebuggingEnabled()) { A4ELogging.debug(PdeExceptionCode.WARNING_FILE_DOES_NOT_CONTAIN_BUNDLE_MANIFEST_FILE.getMessage(), file.getAbsoluteFile()); } } catch (FileNotFoundException e) { throw new RuntimeException(e.getMessage(), e); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } catch (BundleException e) { throw new RuntimeException(e.getMessage(), e); } return description; } private static BundleDescription parsePluginJarFile(File file) { Assure.isFile("file", file); try { // create jar file JarFile jarFile = new JarFile(file); // support for plugins based on the osgi bundle model Manifest manifest = jarFile.getManifest(); if ((manifest != null) && isBundleManifest(manifest)) { return createBundleDescription(manifest, file.getAbsolutePath(), file); } } catch (Exception e) { throw new RuntimeException("Exception while parsing plugin jar '" + file.getName() + "'!", e); } // throw FileParserException since jar is no valid plugin jar // TODO: Konfigurierbar machen!! // throw new FileParserException("Could not parse plugin jar '" + file.getAbsolutePath() // + "' since it contains neither a Bundle-Manifest nor a plugin.xml!"); return null; } /** * Returns the plugin descriptor for the given plugin directory. * * @param directory * the plugin directory. * @return the plugin descriptor for the given plugin directory. * @throws FileParserException * @throws IOException * @throws FileNotFoundException * @throws BundleException */ private static BundleDescription parsePluginDirectory(File directory) throws FileNotFoundException, IOException, BundleException { Assure.isDirectory("directory", directory); // support for plugins based on the osgi bundle model File bundleManifestFile = new File(directory, Constants.OSGI_BUNDLE_MANIFEST); if (bundleManifestFile.isFile()) { Manifest manifest = new Manifest(new FileInputStream(bundleManifestFile)); if (isBundleManifest(manifest)) { return createBundleDescription(manifest, directory.getAbsolutePath(), directory); } } // throw FileParserException since directory is no valid plugin // directory // throw new FileParserException("Could not parse plugin directory '" + directory.getAbsolutePath() // + "' since it contains neither a Bundle-Manifest nor a plugin.xml!"); return null; } /** * Returns whether or not the specified manifest is a bundle manifest. * * @param manifest * the manifest to test. * @return whether or not the specified manifest is a bundle manifest. */ private static boolean isBundleManifest(Manifest manifest) { return manifest.getMainAttributes().getValue("Bundle-SymbolicName") != null; } }