diff options
author | Jeff McAffer | 2008-07-19 12:18:25 +0000 |
---|---|---|
committer | Jeff McAffer | 2008-07-19 12:18:25 +0000 |
commit | c4ae24cecc25e86bc0d67de0949516081b9cd4a9 (patch) | |
tree | bfbeb51e47c1b0e76936161c0d466a2a69418f61 /bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher | |
parent | 3170c07e538f505a7713cc7d11c59e92eb75cf59 (diff) | |
download | rt.equinox.p2-c4ae24cecc25e86bc0d67de0949516081b9cd4a9.tar.gz rt.equinox.p2-c4ae24cecc25e86bc0d67de0949516081b9cd4a9.tar.xz rt.equinox.p2-c4ae24cecc25e86bc0d67de0949516081b9cd4a9.zip |
Major refactoring of the Publisher packages
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher')
2 files changed, 1684 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/LocalizationHelper.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/LocalizationHelper.java new file mode 100644 index 000000000..4dcf75669 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/LocalizationHelper.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2008 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.equinox.spi.p2.publisher; + +import java.io.*; +import java.net.URL; +import java.net.URLConnection; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * Helper functions supporting the processing of localized + * property files. + * + */ +public final class LocalizationHelper { + + private static final String PROPERTIES_FILE_EXTENSION = ".properties"; //$NON-NLS-1$ + private static final Locale DEFAULT_LOCALE = new Locale("df", "LT"); //$NON-NLS-1$//$NON-NLS-2$ + private static LocalizationHelper instance = new LocalizationHelper(); + + // Extract the locale string from the properties file with the given filename + // where the locale string follows the given prefix. For example, return "zh_HK" + // from filename == "plugin_zh_HK.properties" and prefix == "plugin". + static public String getLocaleString(String filename, String prefix) { + String localeString = null; + if (filename.startsWith(prefix) && filename.endsWith(PROPERTIES_FILE_EXTENSION)) { + if (filename.length() > prefix.length() + PROPERTIES_FILE_EXTENSION.length()) { + localeString = filename.substring(prefix.length() + 1, filename.length() - PROPERTIES_FILE_EXTENSION.length()); + } else { + localeString = ""; //$NON-NLS-1$ + } + } + return localeString; + } + + // Get the locale corresponding to the given locale string + static public Locale getLocale(String localeString) { + Locale locale = DEFAULT_LOCALE; + if (localeString.length() == 5 && localeString.indexOf('_') == 2) { + locale = new Locale(localeString.substring(0, 2), localeString.substring(3, 5)); + } else if (localeString.length() == 2) { + locale = new Locale(localeString.substring(0, 2)); + } + return locale; + } + + // For the given root directory and path to localization files within that directory + // get a map from locale to property set for the localization property files. + public static Map getDirPropertyLocalizations(File root, String localizationPath, Locale defaultLocale, String[] propertyKeys) { + File fullPath = new File(root, localizationPath); + File localizationDir = fullPath.getParentFile(); + final String localizationFile = fullPath.getName(); + String[] localizationFiles = LocalizationHelper.getLocalizationFiles(localizationDir, localizationFile); + + HashMap localizations = null; + + if (localizationFiles != null) { + localizations = new HashMap(localizationFiles.length); + for (int i = 0; i < localizationFiles.length; i++) { + String nextFile = localizationFiles[i]; + Locale nextLocale = getLocale(LocalizationHelper.getLocaleString(nextFile, localizationFile)); + + try { + Properties properties = loadProperties(root, nextFile); + Properties localizedStrings = getLocalizedProperties(propertyKeys, properties); + if (localizedStrings.size() > 0) { + localizations.put(nextLocale, localizedStrings); + if (DEFAULT_LOCALE.equals(nextLocale) && defaultLocale != null) { + localizations.put(nextLocale, localizedStrings); + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + + return localizations; + } + + public static Map getJarPropertyLocalizations(File root, String localizationPath, Locale defaultLocale, String[] propertyKeys) { + ZipFile jarFile = null; + Map localizations = new HashMap(4); + try { + jarFile = new ZipFile(root, ZipFile.OPEN_READ); + for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) { + ZipEntry nextEntry = (ZipEntry) entries.nextElement(); + String nextName = nextEntry.getName(); + String localeString = LocalizationHelper.getLocaleString(nextName, localizationPath); + + if (!nextEntry.isDirectory() && localeString != null) { + Locale nextLocale = LocalizationHelper.getLocale(localeString); + InputStream stream = null; + try { + stream = jarFile.getInputStream(nextEntry); + Properties properties = new Properties(); + properties.load(stream); + Properties localizedStrings = LocalizationHelper.getLocalizedProperties(propertyKeys, properties); + if (localizedStrings.size() > 0) { + localizations.put(nextLocale, localizedStrings); + if (DEFAULT_LOCALE.equals(nextLocale) && defaultLocale != null) { + localizations.put(nextLocale, localizedStrings); + } + } + } finally { + if (stream != null) + stream.close(); + } + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } finally { + if (jarFile != null) { + try { + jarFile.close(); + } catch (IOException ioe) { + // do nothing + } + } + } + + return localizations; + } + + // Load a property set from given root and file with the given name + private static Properties loadProperties(File root, String propertyFilename) throws IOException { + Properties result = new Properties(); + InputStream propertyStream = null; + try { + try { + if (root.isDirectory()) + propertyStream = new FileInputStream(new File(root, propertyFilename)); + else { + URLConnection connection = new URL("jar:" + root.toURL().toExternalForm() + "!/" + propertyFilename).openConnection(); //$NON-NLS-1$ //$NON-NLS-2$ + connection.setUseCaches(false); + propertyStream = connection.getInputStream(); + } + } catch (FileNotFoundException e) { + // if there is no messages file then just return; + return result; + } + result.load(propertyStream); + } finally { + if (propertyStream != null) + propertyStream.close(); + } + return result; + } + + // Given a list of keys and the corresponding localized property set, + // return a new property set with those keys and the localized values. + static public Properties getLocalizedProperties(String[] propertyKeys, Properties properties) { + Properties localizedProperties = new Properties(); + for (int i = 0; i < propertyKeys.length; i++) { + String key = propertyKeys[i]; + if (key != null) { + String localizedValue = properties.getProperty(key); + if (localizedValue != null) + localizedProperties.put(key, localizedValue); + } + } + return localizedProperties; + } + + public static String[] getLocalizationFiles(File localizationDir, final String filenamePrefix) { + return localizationDir.list(instance.new FileFilter() { + public boolean accept(File directory, String filename) { + return (getLocaleString(filename, filenamePrefix) != null ? true : false); + } + }); + } + + private abstract class FileFilter implements FilenameFilter { + + public FileFilter() { + // Nothing to do + } + + /* (non-Javadoc) + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) + */ + public abstract boolean accept(File directory, String filename); + } + + private LocalizationHelper() { + // + } + +} diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java new file mode 100644 index 000000000..ee0f63332 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java @@ -0,0 +1,1484 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 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 + * Genuitec, LLC - added license support + * Code 9 - Ongoing development + *******************************************************************************/ +package org.eclipse.equinox.spi.p2.publisher; + +import java.io.*; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.eclipse.core.runtime.Path; +import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; +import org.eclipse.equinox.internal.p2.metadata.ArtifactKey; +import org.eclipse.equinox.internal.p2.metadata.InstallableUnit; +import org.eclipse.equinox.internal.p2.publisher.Activator; +import org.eclipse.equinox.internal.p2.publisher.FileSetDescriptor; +import org.eclipse.equinox.internal.p2.publisher.eclipse.GeneratorBundleInfo; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.ArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactDescriptor; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStepDescriptor; +import org.eclipse.equinox.internal.provisional.p2.metadata.*; +import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.*; +import org.eclipse.equinox.p2.publisher.AbstractPublisherAction; +import org.eclipse.equinox.p2.publisher.IPublisherResult; +import org.eclipse.equinox.p2.publisher.eclipse.*; +import org.eclipse.osgi.service.environment.EnvironmentInfo; +import org.eclipse.osgi.service.resolver.*; +import org.eclipse.osgi.util.ManifestElement; +import org.osgi.framework.*; + +/** + * This class was originally the MetadataGeneratorHelper from the Generator. + * Much of the code has been deprecated and will be removed. + * + */ +// TODO remove the deprecated code and see if there is much left +public class PublisherHelper { + /** + * A capability namespace representing the type of Eclipse resource (bundle, feature, source bundle, etc) + * @see RequiredCapability#getNamespace() + * @see ProvidedCapability#getNamespace() + */ + public static final String NAMESPACE_ECLIPSE_TYPE = "org.eclipse.equinox.p2.eclipse.type"; //$NON-NLS-1$ + + /** + * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace + * representing and OSGi bundle resource + * @see RequiredCapability#getName() + * @see ProvidedCapability#getName() + */ + public static final String TYPE_ECLIPSE_BUNDLE = "bundle"; //$NON-NLS-1$ + /** + * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace + * representing a feature + * @see RequiredCapability#getName() + */ + public static final String TYPE_ECLIPSE_FEATURE = "feature"; //$NON-NLS-1$ + + /** + * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace + * representing a source bundle + * @see RequiredCapability#getName() + */ + public static final String TYPE_ECLIPSE_SOURCE = "source"; //$NON-NLS-1$ + + /** + * A capability namespace representing the localization (translation) + * of strings from a specified IU in a specified locale + * @see RequiredCapability#getNamespace() + * @see ProvidedCapability#getNamespace() + * TODO: this should be in API, probably in IInstallableUnit + */ + public static final String NAMESPACE_IU_LOCALIZATION = "org.eclipse.equinox.p2.localization"; //$NON-NLS-1$ + + // Only certain properties in the bundle manifest are assumed to be localized. + public static final String[] BUNDLE_LOCALIZED_PROPERTIES = {Constants.BUNDLE_NAME, Constants.BUNDLE_DESCRIPTION, Constants.BUNDLE_VENDOR, Constants.BUNDLE_CONTACTADDRESS, Constants.BUNDLE_DOCURL, Constants.BUNDLE_UPDATELOCATION}; + public static final int BUNDLE_LOCALIZATION_INDEX = BUNDLE_LOCALIZED_PROPERTIES.length; + + private static final String[] BUNDLE_IU_PROPERTY_MAP = {Constants.BUNDLE_NAME, IInstallableUnit.PROP_NAME, Constants.BUNDLE_DESCRIPTION, IInstallableUnit.PROP_DESCRIPTION, Constants.BUNDLE_VENDOR, IInstallableUnit.PROP_PROVIDER, Constants.BUNDLE_CONTACTADDRESS, IInstallableUnit.PROP_CONTACT, Constants.BUNDLE_DOCURL, IInstallableUnit.PROP_DOC_URL}; + + public static final String CAPABILITY_NS_JAVA_PACKAGE = "java.package"; //$NON-NLS-1$ + private static final String CAPABILITY_NS_OSGI_BUNDLE = "osgi.bundle"; //$NON-NLS-1$ + private static final String CAPABILITY_NS_OSGI_FRAGMENT = "osgi.fragment"; //$NON-NLS-1$ + + public static final String CAPABILITY_NS_UPDATE_FEATURE = "org.eclipse.update.feature"; //$NON-NLS-1$ + + private static final Version DEFAULT_JRE_VERSION = new Version("1.6"); //$NON-NLS-1$ + + public static final String ECLIPSE_FEATURE_CLASSIFIER = "org.eclipse.update.feature"; //$NON-NLS-1$ + public static final String OSGI_BUNDLE_CLASSIFIER = "osgi.bundle"; //$NON-NLS-1$ + public static final String BINARY_ARTIFACT_CLASSIFIER = "binary"; //$NON-NLS-1$ + + public static final String INSTALL_FEATURES_FILTER = "(org.eclipse.update.install.features=true)"; //$NON-NLS-1$ + + public static final String IU_NAMESPACE = IInstallableUnit.NAMESPACE_IU_ID; + + private static final String LAUNCHER_ID_PREFIX = "org.eclipse.launcher"; //$NON-NLS-1$ + + public static final String ECLIPSE_INSTALL_HANDLER_PROP = "org.eclipse.update.installHandler"; //$NON-NLS-1$ + private static final String UPDATE_FEATURE_APPLICATION_PROP = "org.eclipse.update.feature.application"; //$NON-NLS-1$ + private static final String UPDATE_FEATURE_PLUGIN_PROP = "org.eclipse.update.feature.plugin"; //$NON-NLS-1$ + private static final String UPDATE_FEATURE_EXCLUSIVE_PROP = "org.eclipse.update.feature.exclusive"; //$NON-NLS-1$ + private static final String UPDATE_FEATURE_PRIMARY_PROP = "org.eclipse.update.feature.primary"; //$NON-NLS-1$ + + //TODO - need to come up with a way to infer launcher version + private static final Version LAUNCHER_VERSION = new Version(1, 0, 0); + + public static final Version versionMax = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + + public static final TouchpointType TOUCHPOINT_NATIVE = MetadataFactory.createTouchpointType("org.eclipse.equinox.p2.native", new Version(1, 0, 0)); //$NON-NLS-1$ + public static final TouchpointType TOUCHPOINT_OSGI = MetadataFactory.createTouchpointType("org.eclipse.equinox.p2.osgi", new Version(1, 0, 0)); //$NON-NLS-1$ + + public static final ProvidedCapability BUNDLE_CAPABILITY = MetadataFactory.createProvidedCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_BUNDLE, new Version(1, 0, 0)); + public static final ProvidedCapability FEATURE_CAPABILITY = MetadataFactory.createProvidedCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_FEATURE, new Version(1, 0, 0)); + public static final ProvidedCapability SOURCE_BUNDLE_CAPABILITY = MetadataFactory.createProvidedCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_SOURCE, new Version(1, 0, 0)); + + static final String DEFAULT_BUNDLE_LOCALIZATION = "plugin"; //$NON-NLS-1$ + static final String PROPERTIES_FILE_EXTENSION = ".properties"; //$NON-NLS-1$ + + static final String BUNDLE_ADVICE_FILE = "META-INF/p2.inf"; //$NON-NLS-1$ + static final String ADVICE_INSTRUCTIONS_PREFIX = "instructions."; //$NON-NLS-1$ + + static final Locale DEFAULT_LOCALE = new Locale("df", "LT"); //$NON-NLS-1$//$NON-NLS-2$ + static final Locale PSEUDO_LOCALE = new Locale("zz", "ZZ"); //$NON-NLS-1$//$NON-NLS-2$ + + public static IArtifactDescriptor createArtifactDescriptor(IArtifactKey key, File pathOnDisk) { + //TODO this size calculation is bogus + ArtifactDescriptor result = new ArtifactDescriptor(key); + if (pathOnDisk != null) { + result.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, Long.toString(pathOnDisk.length())); + // TODO - this is wrong but I'm testing a work-around for bug 205842 + result.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(pathOnDisk.length())); + } + return result; + } + + /** + * @deprecated moved to AbstractPublishingAction + */ + public static IArtifactDescriptor createPack200ArtifactDescriptor(IArtifactKey key, File pathOnDisk, String installSize) { + final String PACKED_FORMAT = "packed"; //$NON-NLS-1$ + //TODO this size calculation is bogus + ArtifactDescriptor result = new ArtifactDescriptor(key); + if (pathOnDisk != null) { + result.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, installSize); + // TODO - this is wrong but I'm testing a work-around for bug 205842 + result.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(pathOnDisk.length())); + } + ProcessingStepDescriptor[] steps = new ProcessingStepDescriptor[] {new ProcessingStepDescriptor("org.eclipse.equinox.p2.processing.Pack200Unpacker", null, true)}; //$NON-NLS-1$ + result.setProcessingSteps(steps); + result.setProperty(IArtifactDescriptor.FORMAT, PACKED_FORMAT); + return result; + } + + /** + * @deprecated moved to BundlesAction + */ + public static IArtifactKey createBundleArtifactKey(String bsn, String version) { + return new ArtifactKey(OSGI_BUNDLE_CLASSIFIER, bsn, new Version(version)); + } + + public static IInstallableUnit createIUFragment(String id, String version, String flavor, String configSpec, Map touchpointData) { + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String resultId = flavor + AbstractPublisherAction.createIdString(configSpec) + id; + cu.setId(resultId); + Version resultVersion = new Version(version); + cu.setVersion(resultVersion); + + cu.setFilter(AbstractPublisherAction.createFilterSpec(configSpec)); + cu.setHost(new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, id, new VersionRange(resultVersion, true, resultVersion, true), null, false, false)}); + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {PublisherHelper.createSelfCapability(resultId, resultVersion)}); + + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + return MetadataFactory.createInstallableUnit(cu); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createBundleConfigurationUnit(String hostId, Version hostVersion, boolean isBundleFragment, GeneratorBundleInfo configInfo, String configurationFlavor, String filter) { + if (configInfo == null) + return null; + + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configUnitId = configurationFlavor + hostId; + cu.setId(configUnitId); + cu.setVersion(hostVersion); + + //Indicate the IU to which this CU apply + cu.setHost(new RequiredCapability[] { // + MetadataFactory.createRequiredCapability(CAPABILITY_NS_OSGI_BUNDLE, hostId, new VersionRange(hostVersion, true, versionMax, true), null, false, false, true), // + MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_BUNDLE, new VersionRange(new Version(1, 0, 0), true, new Version(2, 0, 0), false), null, false, false, false)}); + + //Adds capabilities for fragment, self, and describing the flavor supported + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configUnitId, hostVersion), MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_FLAVOR, configurationFlavor, new Version(1, 0, 0))}); + + Map touchpointData = new HashMap(); + touchpointData.put("install", "installBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("uninstall", "uninstallBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("configure", createConfigScript(configInfo, isBundleFragment)); //$NON-NLS-1$ + touchpointData.put("unconfigure", createUnconfigScript(configInfo, isBundleFragment)); //$NON-NLS-1$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + cu.setFilter(filter); + return MetadataFactory.createInstallableUnit(cu); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key) { + return createBundleIU(bd, manifest, isFolderPlugin, key, false); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, boolean useNestedAdvice) { + Map manifestLocalizations = null; + if (manifest != null && bd.getLocation() != null) { + manifestLocalizations = getManifestLocalizations(manifest, new File(bd.getLocation())); + } + + return createBundleIU(bd, manifest, isFolderPlugin, key, manifestLocalizations, useNestedAdvice); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Map manifestLocalizations) { + return createBundleIU(bd, manifest, isFolderPlugin, key, manifestLocalizations, false); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Map manifestLocalizations, boolean useNestedAdvice) { + boolean isBinaryBundle = true; + if (manifest != null && manifest.containsKey("Eclipse-SourceBundle")) { //$NON-NLS-1$ + isBinaryBundle = false; + } + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + iu.setSingleton(bd.isSingleton()); + iu.setId(bd.getSymbolicName()); + iu.setVersion(bd.getVersion()); + iu.setFilter(bd.getPlatformFilter()); + + iu.setUpdateDescriptor(MetadataFactory.createUpdateDescriptor(bd.getSymbolicName(), new VersionRange(new Version(0, 0, 0), true, bd.getVersion(), false), IUpdateDescriptor.NORMAL, null)); + + boolean isFragment = bd.getHost() != null; + // boolean requiresAFragment = isFragment ? false : requireAFragment(bd, manifest); + + //Process the required bundles + BundleSpecification requiredBundles[] = bd.getRequiredBundles(); + ArrayList reqsDeps = new ArrayList(); + // if (requiresAFragment) + // reqsDeps.add(MetadataFactory.createRequiredCapability(CAPABILITY_TYPE_OSGI_FRAGMENTS, bd.getSymbolicName(), VersionRange.emptyRange, null, false, false)); + if (isFragment) + reqsDeps.add(MetadataFactory.createRequiredCapability(CAPABILITY_NS_OSGI_BUNDLE, bd.getHost().getName(), bd.getHost().getVersionRange(), null, false, false)); + for (int j = 0; j < requiredBundles.length; j++) + reqsDeps.add(MetadataFactory.createRequiredCapability(CAPABILITY_NS_OSGI_BUNDLE, requiredBundles[j].getName(), requiredBundles[j].getVersionRange() == VersionRange.emptyRange ? null : requiredBundles[j].getVersionRange(), null, requiredBundles[j].isOptional(), false)); + + // Process the import packages + ImportPackageSpecification osgiImports[] = bd.getImportPackages(); + for (int i = 0; i < osgiImports.length; i++) { + // TODO we need to sort out how we want to handle wild-carded dynamic imports - for now we ignore them + ImportPackageSpecification importSpec = osgiImports[i]; + String importPackageName = importSpec.getName(); + if (importPackageName.indexOf('*') != -1) + continue; + + VersionRange versionRange = importSpec.getVersionRange() == VersionRange.emptyRange ? null : importSpec.getVersionRange(); + + //TODO this needs to be refined to take into account all the attribute handled by imports + reqsDeps.add(MetadataFactory.createRequiredCapability(CAPABILITY_NS_JAVA_PACKAGE, importPackageName, versionRange, null, isOptional(importSpec), false)); + } + iu.setRequiredCapabilities((RequiredCapability[]) reqsDeps.toArray(new RequiredCapability[reqsDeps.size()])); + + // Create set of provided capabilities + ArrayList providedCapabilities = new ArrayList(); + providedCapabilities.add(createSelfCapability(bd.getSymbolicName(), bd.getVersion())); + providedCapabilities.add(MetadataFactory.createProvidedCapability(CAPABILITY_NS_OSGI_BUNDLE, bd.getSymbolicName(), bd.getVersion())); + + // Process the export package + ExportPackageDescription exports[] = bd.getExportPackages(); + for (int i = 0; i < exports.length; i++) { + //TODO make sure that we support all the refinement on the exports + providedCapabilities.add(MetadataFactory.createProvidedCapability(CAPABILITY_NS_JAVA_PACKAGE, exports[i].getName(), exports[i].getVersion() == Version.emptyVersion ? null : exports[i].getVersion())); + } + // Here we add a bundle capability to identify bundles + if (isBinaryBundle) + providedCapabilities.add(BUNDLE_CAPABILITY); + else + providedCapabilities.add(SOURCE_BUNDLE_CAPABILITY); + + if (isFragment) + providedCapabilities.add(MetadataFactory.createProvidedCapability(CAPABILITY_NS_OSGI_FRAGMENT, bd.getHost().getName(), bd.getVersion())); + + if (manifestLocalizations != null) { + for (Iterator iter = manifestLocalizations.keySet().iterator(); iter.hasNext();) { + Locale locale = (Locale) iter.next(); + Properties translatedStrings = (Properties) manifestLocalizations.get(locale); + Enumeration propertyKeys = translatedStrings.propertyNames(); + while (propertyKeys.hasMoreElements()) { + String nextKey = (String) propertyKeys.nextElement(); + iu.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + } + providedCapabilities.add(makeTranslationCapability(bd.getSymbolicName(), locale)); + } + } + + iu.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + + iu.setArtifacts(new IArtifactKey[] {key}); + + iu.setTouchpointType(TOUCHPOINT_OSGI); + + // Set certain properties from the manifest header attributes as IU properties. + // The values of these attributes may be localized (strings starting with '%') + // with the translated values appearing in the localization IU fragments + // associated with the bundle IU. + if (manifest != null) { + int i = 0; + while (i < BUNDLE_IU_PROPERTY_MAP.length) { + if (manifest.containsKey(BUNDLE_IU_PROPERTY_MAP[i])) { + String value = (String) manifest.get(BUNDLE_IU_PROPERTY_MAP[i]); + if (value != null && value.length() > 0) { + iu.setProperty(BUNDLE_IU_PROPERTY_MAP[i + 1], value); + } + } + i += 2; + } + } + + // Define the immutable metadata for this IU. In this case immutable means + // that this is something that will not impact the configuration. + Map touchpointData = new HashMap(); + if (isFolderPlugin) + touchpointData.put("zipped", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("manifest", toManifestString(manifest)); //$NON-NLS-1$ + + if (useNestedAdvice) + mergeInstructionsAdvice(touchpointData, getBundleAdvice(bd.getLocation())); + + iu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + + return MetadataFactory.createInstallableUnit(iu); + } + + // TODO need to figure out a mapping of this onto real advice and make this generic + /** + * @deprecated moved to BundlesAction + */ + private static void mergeInstructionsAdvice(Map touchpointData, Map bundleAdvice) { + if (touchpointData == null || bundleAdvice == null) + return; + + for (Iterator iterator = bundleAdvice.keySet().iterator(); iterator.hasNext();) { + String key = (String) iterator.next(); + if (key.startsWith(ADVICE_INSTRUCTIONS_PREFIX)) { + String phase = key.substring(ADVICE_INSTRUCTIONS_PREFIX.length()); + String instructions = touchpointData.containsKey(phase) ? (String) touchpointData.get(phase) : ""; //$NON-NLS-1$ + if (instructions.length() > 0) + instructions += ";"; //$NON-NLS-1$ + instructions += ((String) bundleAdvice.get(key)).trim(); + touchpointData.put(phase, instructions); + } + } + } + + /** + * @deprecated moved to BundlesAction + */ + public static void createHostLocalizationFragment(IInstallableUnit bundleIU, BundleDescription bd, String hostId, String[] hostBundleManifestValues, Set localizationIUs) { + Map hostLocalizations = getHostLocalizations(new File(bd.getLocation()), hostBundleManifestValues); + if (hostLocalizations != null) { + IInstallableUnitFragment localizationFragment = createLocalizationFragmentOfHost(bd, hostId, hostBundleManifestValues, hostLocalizations); + localizationIUs.add(localizationFragment); + } + } + + /* + * @param hostId + * @param bd + * @param locale + * @param localizedStrings + * @return installableUnitFragment + */ + /** + * @deprecated moved to BundlesAction + */ + private static IInstallableUnitFragment createLocalizationFragmentOfHost(BundleDescription bd, String hostId, String[] hostManifestValues, Map hostLocalizations) { + InstallableUnitFragmentDescription fragment = new MetadataFactory.InstallableUnitFragmentDescription(); + String fragmentId = makeHostLocalizationFragmentId(bd.getSymbolicName()); + fragment.setId(fragmentId); + fragment.setVersion(bd.getVersion()); // TODO: is this a meaningful version? + + HostSpecification hostSpec = bd.getHost(); + RequiredCapability[] hostReqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, hostSpec.getName(), hostSpec.getVersionRange(), null, false, false, false)}; + fragment.setHost(hostReqs); + + fragment.setSingleton(true); + fragment.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + + // Create a provided capability for each locale and add the translated properties. + ArrayList providedCapabilities = new ArrayList(hostLocalizations.keySet().size()); + for (Iterator iter = hostLocalizations.keySet().iterator(); iter.hasNext();) { + Locale locale = (Locale) iter.next(); + Properties translatedStrings = (Properties) hostLocalizations.get(locale); + + Enumeration propertyKeys = translatedStrings.propertyNames(); + while (propertyKeys.hasMoreElements()) { + String nextKey = (String) propertyKeys.nextElement(); + fragment.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + } + providedCapabilities.add(makeTranslationCapability(hostId, locale)); + } + fragment.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + + return MetadataFactory.createInstallableUnitFragment(fragment); + } + + /** + * @param id + * @return the id for the iu fragment containing the localized properties + * for the bundle with the given id + */ + // private static String makeBundleLocalizationFragmentId(String id) { + // return id + ".translated_properties"; //$NON-NLS-1$ + // } + /** + * @param id + * @return the id for the iu fragment containing localized properties + * for the fragment with the given id. + */ + /** + * @deprecated moved to BundlesAction + */ + private static String makeHostLocalizationFragmentId(String id) { + return id + ".translated_host_properties"; //$NON-NLS-1$ + } + + public static ProvidedCapability makeTranslationCapability(String hostId, Locale locale) { + return MetadataFactory.createProvidedCapability(NAMESPACE_IU_LOCALIZATION, locale.toString(), new Version(1, 0, 0)); + } + + /** + * Creates an IU corresponding to an update site category + * @param category The category descriptor + * @param featureIUs The IUs of the features that belong to the category + * @param parentCategory The parent category, or <code>null</code> + * @return an IU representing the category + * @deprecated moved to SiteXMLAction + */ + // public static IInstallableUnit createCategoryIU(SiteCategory category, Set featureIUs, IInstallableUnit parentCategory) { + // InstallableUnitDescription cat = new MetadataFactory.InstallableUnitDescription(); + // cat.setSingleton(true); + // String categoryId = category.getName(); + // cat.setId(categoryId); + // cat.setVersion(Version.emptyVersion); + // cat.setProperty(IInstallableUnit.PROP_NAME, category.getLabel()); + // cat.setProperty(IInstallableUnit.PROP_DESCRIPTION, category.getDescription()); + // + // ArrayList reqsConfigurationUnits = new ArrayList(featureIUs.size()); + // for (Iterator iterator = featureIUs.iterator(); iterator.hasNext();) { + // IInstallableUnit iu = (IInstallableUnit) iterator.next(); + // VersionRange range = new VersionRange(iu.getVersion(), true, iu.getVersion(), true); + // reqsConfigurationUnits.add(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, iu.getId(), range, iu.getFilter(), false, false)); + // } + // //note that update sites don't currently support nested categories, but it may be useful to add in the future + // if (parentCategory != null) { + // reqsConfigurationUnits.add(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, parentCategory.getId(), VersionRange.emptyRange, parentCategory.getFilter(), false, false)); + // } + // cat.setRequiredCapabilities((RequiredCapability[]) reqsConfigurationUnits.toArray(new RequiredCapability[reqsConfigurationUnits.size()])); + // + // // Create set of provided capabilities + // ArrayList providedCapabilities = new ArrayList(); + // providedCapabilities.add(createSelfCapability(categoryId, Version.emptyVersion)); + // + // Map localizations = category.getLocalizations(); + // if (localizations != null) { + // for (Iterator iter = localizations.keySet().iterator(); iter.hasNext();) { + // Locale locale = (Locale) iter.next(); + // Properties translatedStrings = (Properties) localizations.get(locale); + // Enumeration propertyKeys = translatedStrings.propertyNames(); + // while (propertyKeys.hasMoreElements()) { + // String nextKey = (String) propertyKeys.nextElement(); + // cat.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + // } + // providedCapabilities.add(makeTranslationCapability(categoryId, locale)); + // } + // } + // + // cat.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + // + // cat.setArtifacts(new IArtifactKey[0]); + // cat.setProperty(IInstallableUnit.PROP_TYPE_CATEGORY, "true"); //$NON-NLS-1$ + // return MetadataFactory.createInstallableUnit(cat); + // } + { + } + + /** + * @deprecated moved to BundlesAction + */ + private static String createConfigScript(GeneratorBundleInfo configInfo, boolean isBundleFragment) { + if (configInfo == null) + return ""; //$NON-NLS-1$ + + String configScript = "";//$NON-NLS-1$ + if (!isBundleFragment && configInfo.getStartLevel() != BundleInfo.NO_LEVEL) { + configScript += "setStartLevel(startLevel:" + configInfo.getStartLevel() + ");"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (!isBundleFragment && configInfo.isMarkedAsStarted()) { + configScript += "markStarted(started: true);"; //$NON-NLS-1$ + } + + if (configInfo.getSpecialConfigCommands() != null) { + configScript += configInfo.getSpecialConfigCommands(); + } + + return configScript; + } + + /** + * @deprecated moved to BundlesAction + */ + private static String createDefaultBundleConfigScript(GeneratorBundleInfo configInfo) { + return createConfigScript(configInfo, false); + } + + /** + * @deprecated moved to BundlesAction + */ + public static IInstallableUnit createDefaultBundleConfigurationUnit(GeneratorBundleInfo configInfo, GeneratorBundleInfo unconfigInfo, String configurationFlavor) { + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configUnitId = createDefaultConfigUnitId(OSGI_BUNDLE_CLASSIFIER, configurationFlavor); + cu.setId(configUnitId); + Version configUnitVersion = new Version(1, 0, 0); + cu.setVersion(configUnitVersion); + + // Add capabilities for fragment, self, and describing the flavor supported + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configUnitId, configUnitVersion), MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_FLAVOR, configurationFlavor, new Version(1, 0, 0))}); + + // Create a required capability on bundles + RequiredCapability[] reqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_BUNDLE, VersionRange.emptyRange, null, false, true, false)}; + cu.setHost(reqs); + Map touchpointData = new HashMap(); + + touchpointData.put("install", "installBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("uninstall", "uninstallBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("configure", createDefaultBundleConfigScript(configInfo)); //$NON-NLS-1$ + touchpointData.put("unconfigure", createDefaultBundleUnconfigScript(unconfigInfo)); //$NON-NLS-1$ + + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + return MetadataFactory.createInstallableUnit(cu); + } + + /** + * @deprecated moved to BundlesAction + */ + private static String createDefaultBundleUnconfigScript(GeneratorBundleInfo unconfigInfo) { + return createUnconfigScript(unconfigInfo, false); + } + + public static String createDefaultConfigUnitId(String classifier, String configurationFlavor) { + return configurationFlavor + "." + classifier + ".default"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static IInstallableUnit createDefaultFeatureConfigurationUnit(String configurationFlavor) { + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configUnitId = createDefaultConfigUnitId(ECLIPSE_FEATURE_CLASSIFIER, configurationFlavor); + cu.setId(configUnitId); + Version configUnitVersion = new Version(1, 0, 0); + cu.setVersion(configUnitVersion); + + // Add capabilities for fragment, self, and describing the flavor supported + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configUnitId, configUnitVersion), MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_FLAVOR, configurationFlavor, new Version(1, 0, 0))}); + + // Create a required capability on features + RequiredCapability[] reqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_FEATURE, VersionRange.emptyRange, null, true, true, false)}; + cu.setHost(reqs); + + cu.setFilter(INSTALL_FEATURES_FILTER); + Map touchpointData = new HashMap(); + touchpointData.put("install", "installFeature(feature:${artifact},featureId:default,featureVersion:default)"); //$NON-NLS-1$//$NON-NLS-2$ + touchpointData.put("uninstall", "uninstallFeature(feature:${artifact},featureId:default,featureVersion:default)"); //$NON-NLS-1$//$NON-NLS-2$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + + return MetadataFactory.createInstallableUnit(cu); + } + + public static IInstallableUnit createDefaultConfigurationUnitForSourceBundles(String configurationFlavor) { + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configUnitId = createDefaultConfigUnitId("source", configurationFlavor); //$NON-NLS-1$ + cu.setId(configUnitId); + Version configUnitVersion = new Version(1, 0, 0); + cu.setVersion(configUnitVersion); + + // Add capabilities for fragment, self, and describing the flavor supported + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configUnitId, configUnitVersion), MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_FLAVOR, configurationFlavor, new Version(1, 0, 0))}); + + // Create a required capability on source providers + RequiredCapability[] reqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_SOURCE, VersionRange.emptyRange, null, true, true, false)}; + cu.setHost(reqs); + Map touchpointData = new HashMap(); + + touchpointData.put("install", "addSourceBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + touchpointData.put("uninstall", "removeSourceBundle(bundle:${artifact})"); //$NON-NLS-1$ //$NON-NLS-2$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + return MetadataFactory.createInstallableUnit(cu); + } + + private static void addExtraProperties(IInstallableUnit iiu, Properties extraProperties) { + if (iiu instanceof InstallableUnit) { + InstallableUnit iu = (InstallableUnit) iiu; + + for (Enumeration e = extraProperties.propertyNames(); e.hasMoreElements();) { + String name = (String) e.nextElement(); + iu.setProperty(name, extraProperties.getProperty(name)); + } + } + } + + public static IInstallableUnit[] createEclipseIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Properties extraProperties) { + ArrayList iusCreated = new ArrayList(1); + + IInstallableUnit iu = createBundleIU(bd, manifest, isFolderPlugin, key); + addExtraProperties(iu, extraProperties); + iusCreated.add(iu); + + return (IInstallableUnit[]) (iusCreated.toArray(new IInstallableUnit[iusCreated.size()])); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static IArtifactKey createFeatureArtifactKey(String fsn, String version) { + return new ArtifactKey(ECLIPSE_FEATURE_CLASSIFIER, fsn, new Version(version)); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static IInstallableUnit createFeatureJarIU(Feature feature, boolean isExploded) { + return createFeatureJarIU(feature, isExploded, null); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static IInstallableUnit createFeatureJarIU(Feature feature, boolean isExploded, Properties extraProperties) { + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + String id = getTransformedId(feature.getId(), /*isPlugin*/false, /*isGroup*/false); + iu.setId(id); + Version version = new Version(feature.getVersion()); + iu.setVersion(version); + iu.setUpdateDescriptor(MetadataFactory.createUpdateDescriptor(id, new VersionRange(new Version(0, 0, 0), true, new Version(feature.getVersion()), false), IUpdateDescriptor.NORMAL, null)); + iu.setProperty(IInstallableUnit.PROP_NAME, feature.getLabel()); + if (feature.getDescription() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION, feature.getDescription()); + if (feature.getDescriptionURL() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION_URL, feature.getDescriptionURL()); + if (feature.getProviderName() != null) + iu.setProperty(IInstallableUnit.PROP_PROVIDER, feature.getProviderName()); + if (feature.getLicense() != null) + iu.setLicense(new License(feature.getLicenseURL(), feature.getLicense())); + if (feature.getCopyright() != null) + iu.setCopyright(new Copyright(feature.getCopyrightURL(), feature.getCopyright())); + if (feature.getApplication() != null) + iu.setProperty(UPDATE_FEATURE_APPLICATION_PROP, feature.getApplication()); + if (feature.getPlugin() != null) + iu.setProperty(UPDATE_FEATURE_PLUGIN_PROP, feature.getPlugin()); + if (feature.isExclusive()) + iu.setProperty(UPDATE_FEATURE_EXCLUSIVE_PROP, Boolean.TRUE.toString()); + if (feature.isPrimary()) + iu.setProperty(UPDATE_FEATURE_PRIMARY_PROP, Boolean.TRUE.toString()); + + // The required capabilities are not specified at this level because we don't want the feature jar to be attractive to install. + + iu.setTouchpointType(TOUCHPOINT_OSGI); + iu.setFilter(INSTALL_FEATURES_FILTER); + iu.setSingleton(true); + + if (feature.getInstallHandler() != null && feature.getInstallHandler().trim().length() > 0) { + String installHandlerProperty = "handler=" + feature.getInstallHandler(); //$NON-NLS-1$ + + if (feature.getInstallHandlerLibrary() != null) + installHandlerProperty += ", library=" + feature.getInstallHandlerLibrary(); //$NON-NLS-1$ + + if (feature.getInstallHandlerURL() != null) + installHandlerProperty += ", url=" + feature.getInstallHandlerURL(); //$NON-NLS-1$ + + iu.setProperty(ECLIPSE_INSTALL_HANDLER_PROP, installHandlerProperty); + } + + // Create set of provided capabilities + ArrayList providedCapabilities = new ArrayList(); + providedCapabilities.add(createSelfCapability(id, version)); + providedCapabilities.add(FEATURE_CAPABILITY); + providedCapabilities.add(MetadataFactory.createProvidedCapability(CAPABILITY_NS_UPDATE_FEATURE, feature.getId(), version)); + + iu.setArtifacts(new IArtifactKey[] {createFeatureArtifactKey(feature.getId(), version.toString())}); + + if (isExploded) { + // Define the immutable metadata for this IU. In this case immutable means + // that this is something that will not impact the configuration. + Map touchpointData = new HashMap(); + touchpointData.put("zipped", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + iu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + } + + Map localizations = feature.getLocalizations(); + if (localizations != null) { + for (Iterator iter = localizations.keySet().iterator(); iter.hasNext();) { + Locale locale = (Locale) iter.next(); + Properties translatedStrings = (Properties) localizations.get(locale); + Enumeration propertyKeys = translatedStrings.propertyNames(); + while (propertyKeys.hasMoreElements()) { + String nextKey = (String) propertyKeys.nextElement(); + iu.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + } + providedCapabilities.add(makeTranslationCapability(id, locale)); + } + } + + iu.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + + if (extraProperties != null) { + Enumeration e = extraProperties.propertyNames(); + while (e.hasMoreElements()) { + String name = (String) e.nextElement(); + iu.setProperty(name, extraProperties.getProperty(name)); + } + } + + return MetadataFactory.createInstallableUnit(iu); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static IInstallableUnit createGroupIU(Feature feature, IInstallableUnit featureIU) { + return createGroupIU(feature, featureIU, null); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static IInstallableUnit createGroupIU(Feature feature, IInstallableUnit featureIU, Properties extraProperties) { + return createGroupIU(feature, featureIU, extraProperties, true); + } + + public static IInstallableUnit createGroupIU(Feature feature, IInstallableUnit featureIU, Properties extraProperties, boolean transformIds) { + if (isPatch(feature)) + return createPatchIU(feature, featureIU, extraProperties); + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + String id = feature.getId(); + if (transformIds) + id = getTransformedId(id, /*isPlugin*/false, /*isGroup*/true); + iu.setId(id); + Version version = new Version(feature.getVersion()); + iu.setVersion(version); + iu.setProperty(IInstallableUnit.PROP_NAME, feature.getLabel()); + if (feature.getDescription() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION, feature.getDescription()); + if (feature.getDescriptionURL() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION_URL, feature.getDescriptionURL()); + if (feature.getProviderName() != null) + iu.setProperty(IInstallableUnit.PROP_PROVIDER, feature.getProviderName()); + if (feature.getLicense() != null) + iu.setLicense(new License(feature.getLicenseURL(), feature.getLicense())); + if (feature.getCopyright() != null) + iu.setCopyright(new Copyright(feature.getCopyrightURL(), feature.getCopyright())); + iu.setUpdateDescriptor(MetadataFactory.createUpdateDescriptor(id, new VersionRange(new Version(0, 0, 0), true, new Version(feature.getVersion()), false), IUpdateDescriptor.NORMAL, null)); + + FeatureEntry entries[] = feature.getEntries(); + RequiredCapability[] required = new RequiredCapability[entries.length + (featureIU == null ? 0 : 1)]; + for (int i = 0; i < entries.length; i++) { + VersionRange range = getVersionRange(entries[i]); + String requiredId = entries[i].getId(); + if (transformIds) + requiredId = getTransformedId(entries[i].getId(), entries[i].isPlugin(), /*isGroup*/true); + required[i] = MetadataFactory.createRequiredCapability(IU_NAMESPACE, requiredId, range, getFilter(entries[i]), entries[i].isOptional(), false); + } + // the feature IU could be null if we are just generating a feature structure rather than + // actual features. + if (featureIU != null) + required[entries.length] = MetadataFactory.createRequiredCapability(IU_NAMESPACE, featureIU.getId(), new VersionRange(featureIU.getVersion(), true, featureIU.getVersion(), true), INSTALL_FEATURES_FILTER, false, false); + iu.setRequiredCapabilities(required); + iu.setTouchpointType(TouchpointType.NONE); + iu.setProperty(IInstallableUnit.PROP_TYPE_GROUP, Boolean.TRUE.toString()); + // TODO: shouldn't the filter for the group be constructed from os, ws, arch, nl + // of the feature? + // iu.setFilter(filter); + + // Create set of provided capabilities + ArrayList providedCapabilities = new ArrayList(); + providedCapabilities.add(createSelfCapability(id, version)); + + Map localizations = feature.getLocalizations(); + if (localizations != null) { + for (Iterator iter = localizations.keySet().iterator(); iter.hasNext();) { + Locale locale = (Locale) iter.next(); + Properties translatedStrings = (Properties) localizations.get(locale); + Enumeration propertyKeys = translatedStrings.propertyNames(); + while (propertyKeys.hasMoreElements()) { + String nextKey = (String) propertyKeys.nextElement(); + iu.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + } + providedCapabilities.add(makeTranslationCapability(id, locale)); + } + } + + iu.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + + if (extraProperties != null) { + Enumeration e = extraProperties.propertyNames(); + while (e.hasMoreElements()) { + String name = (String) e.nextElement(); + iu.setProperty(name, extraProperties.getProperty(name)); + } + } + + return MetadataFactory.createInstallableUnit(iu); + } + + public static IInstallableUnit createPatchIU(Feature feature, IInstallableUnit featureIU, Properties extraProperties) { + InstallableUnitPatchDescription iu = new MetadataFactory.InstallableUnitPatchDescription(); + String id = getTransformedId(feature.getId(), /*isPlugin*/false, /*isGroup*/true); + iu.setId(id); + Version version = new Version(feature.getVersion()); + iu.setVersion(version); + iu.setProperty(IInstallableUnit.PROP_NAME, feature.getLabel()); + if (feature.getDescription() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION, feature.getDescription()); + if (feature.getDescriptionURL() != null) + iu.setProperty(IInstallableUnit.PROP_DESCRIPTION_URL, feature.getDescriptionURL()); + if (feature.getProviderName() != null) + iu.setProperty(IInstallableUnit.PROP_PROVIDER, feature.getProviderName()); + if (feature.getLicense() != null) + iu.setLicense(new License(feature.getLicenseURL(), feature.getLicense())); + if (feature.getCopyright() != null) + iu.setCopyright(new Copyright(feature.getCopyrightURL(), feature.getCopyright())); + iu.setUpdateDescriptor(MetadataFactory.createUpdateDescriptor(id, new VersionRange(new Version(0, 0, 0), true, new Version(feature.getVersion()), false), IUpdateDescriptor.NORMAL, null)); + + FeatureEntry entries[] = feature.getEntries(); + ArrayList applicabilityScope = new ArrayList(); + ArrayList patchRequirements = new ArrayList(); + ArrayList requirementChanges = new ArrayList(); + for (int i = 0; i < entries.length; i++) { + VersionRange range = getVersionRange(entries[i]); + RequiredCapability req = MetadataFactory.createRequiredCapability(IU_NAMESPACE, getTransformedId(entries[i].getId(), entries[i].isPlugin(), /*isGroup*/true), range, getFilter(entries[i]), entries[i].isOptional(), false); + if (entries[i].isRequires()) { + applicabilityScope.add(req); + continue; + } + if (entries[i].isPlugin()) { + RequiredCapability from = MetadataFactory.createRequiredCapability(IU_NAMESPACE, getTransformedId(entries[i].getId(), entries[i].isPlugin(), /*isGroup*/true), VersionRange.emptyRange, getFilter(entries[i]), entries[i].isOptional(), false); + requirementChanges.add(new RequirementChange(from, req)); + continue; + } + patchRequirements.add(req); + } + //Always add a requirement on the IU containing the feature jar + patchRequirements.add(MetadataFactory.createRequiredCapability(IU_NAMESPACE, featureIU.getId(), new VersionRange(featureIU.getVersion(), true, featureIU.getVersion(), true), INSTALL_FEATURES_FILTER, false, false)); + iu.setRequiredCapabilities((RequiredCapability[]) patchRequirements.toArray(new RequiredCapability[patchRequirements.size()])); + iu.setApplicabilityScope(new RequiredCapability[][] {(RequiredCapability[]) applicabilityScope.toArray(new RequiredCapability[applicabilityScope.size()])}); + iu.setRequirementChanges((RequirementChange[]) requirementChanges.toArray(new RequirementChange[requirementChanges.size()])); + + //Generate lifecycle + RequiredCapability lifeCycle = null; + if (applicabilityScope.size() > 0) { + RequiredCapability req = (RequiredCapability) applicabilityScope.get(0); + lifeCycle = MetadataFactory.createRequiredCapability(req.getNamespace(), req.getName(), req.getRange(), null, false, false, false); + iu.setLifeCycle(lifeCycle); + } + + iu.setTouchpointType(TouchpointType.NONE); + iu.setProperty(IInstallableUnit.PROP_TYPE_GROUP, Boolean.TRUE.toString()); + iu.setProperty(IInstallableUnit.PROP_TYPE_PATCH, Boolean.TRUE.toString()); + // TODO: shouldn't the filter for the group be constructed from os, ws, arch, nl + // of the feature? + // iu.setFilter(filter); + + // Create set of provided capabilities + ArrayList providedCapabilities = new ArrayList(); + providedCapabilities.add(createSelfCapability(id, version)); + + Map localizations = feature.getLocalizations(); + if (localizations != null) { + for (Iterator iter = localizations.keySet().iterator(); iter.hasNext();) { + Locale locale = (Locale) iter.next(); + Properties translatedStrings = (Properties) localizations.get(locale); + Enumeration propertyKeys = translatedStrings.propertyNames(); + while (propertyKeys.hasMoreElements()) { + String nextKey = (String) propertyKeys.nextElement(); + iu.setProperty(locale.toString() + '.' + nextKey, translatedStrings.getProperty(nextKey)); + } + providedCapabilities.add(makeTranslationCapability(id, locale)); + } + } + + iu.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()])); + + if (extraProperties != null) { + Enumeration e = extraProperties.propertyNames(); + while (e.hasMoreElements()) { + String name = (String) e.nextElement(); + iu.setProperty(name, extraProperties.getProperty(name)); + } + } + + return MetadataFactory.createInstallableUnitPatch(iu); + } + + private static boolean isPatch(Feature feature) { + FeatureEntry[] entries = feature.getEntries(); + for (int i = 0; i < entries.length; i++) { + if (entries[i].isPatch()) + return true; + } + return false; + } + + /** + * Creates IUs and artifact descriptors for the JRE. The resulting IUs are added + * to the given set, and the resulting artifact descriptor, if any, is returned. + * If the jreLocation is <code>null</code>, default information is generated. + */ + /** + * @deprecated moved to JREAction + */ + public static IArtifactDescriptor createJREData(File jreLocation, IPublisherResult results) { + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + iu.setSingleton(false); + String id = "a.jre"; //$NON-NLS-1$ + Version version = DEFAULT_JRE_VERSION; + iu.setId(id); + iu.setVersion(version); + iu.setTouchpointType(TOUCHPOINT_NATIVE); + + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configId = "config." + id;//$NON-NLS-1$ + cu.setId(configId); + cu.setVersion(version); + cu.setHost(new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, id, new VersionRange(version, true, versionMax, true), null, false, false)}); + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configId, version)}); + cu.setTouchpointType(TOUCHPOINT_NATIVE); + Map touchpointData = new HashMap(); + + if (jreLocation == null || !jreLocation.exists()) { + // set some reasonable defaults + iu.setVersion(version); + iu.setCapabilities(generateJRECapability(id, version, null)); + results.addIU(MetadataFactory.createInstallableUnit(iu), IPublisherResult.ROOT); + + touchpointData.put("install", ""); //$NON-NLS-1$ //$NON-NLS-2$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + results.addIU(MetadataFactory.createInstallableUnit(cu), IPublisherResult.ROOT); + return null; + } + generateJREIUData(iu, id, version, jreLocation); + + //Generate artifact for JRE + IArtifactKey key = new ArtifactKey(BINARY_ARTIFACT_CLASSIFIER, id, version); + iu.setArtifacts(new IArtifactKey[] {key}); + results.addIU(MetadataFactory.createInstallableUnit(iu), IPublisherResult.ROOT); + + //Create config info for the CU + String configurationData = "unzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + touchpointData.put("install", configurationData); //$NON-NLS-1$ + String unConfigurationData = "cleanupzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + touchpointData.put("uninstall", unConfigurationData); //$NON-NLS-1$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + results.addIU(MetadataFactory.createInstallableUnit(cu), IPublisherResult.ROOT); + + //Create the artifact descriptor + return createArtifactDescriptor(key, jreLocation); + } + + public static ArtifactKey createLauncherArtifactKey(String id, Version version) { + return new ArtifactKey(BINARY_ARTIFACT_CLASSIFIER, id, version); + } + + /** + * Creates IUs and artifacts for the Launcher executable. The resulting IUs are added + * to the given set, and the resulting artifact descriptor is returned. + */ + public static IArtifactDescriptor createLauncherIU(File launcher, String configurationFlavor, IPublisherResult resultantIUs) { + if (launcher == null || !launcher.exists()) + return null; + + //Create the IU + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + iu.setSingleton(true); + String launcherId = LAUNCHER_ID_PREFIX + '_' + launcher.getName(); + iu.setId(launcherId); + iu.setVersion(LAUNCHER_VERSION); + + IArtifactKey key = createLauncherArtifactKey(launcherId, LAUNCHER_VERSION); + iu.setArtifacts(new IArtifactKey[] {key}); + iu.setCapabilities(new ProvidedCapability[] {createSelfCapability(launcherId, LAUNCHER_VERSION)}); + iu.setTouchpointType(TOUCHPOINT_NATIVE); + resultantIUs.addIU(MetadataFactory.createInstallableUnit(iu), IPublisherResult.ROOT); + + //Create the CU + InstallableUnitFragmentDescription cu = new InstallableUnitFragmentDescription(); + String configUnitId = configurationFlavor + launcherId; + cu.setId(configUnitId); + cu.setVersion(LAUNCHER_VERSION); + cu.setHost(new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, launcherId, new VersionRange(LAUNCHER_VERSION, true, versionMax, true), null, false, false)}); + cu.setProperty(IInstallableUnit.PROP_TYPE_FRAGMENT, Boolean.TRUE.toString()); + cu.setCapabilities(new ProvidedCapability[] {createSelfCapability(configUnitId, LAUNCHER_VERSION)}); + cu.setTouchpointType(TOUCHPOINT_NATIVE); + Map touchpointData = new HashMap(); + String configurationData = "unzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName()); + if (!info.getOS().equals(org.eclipse.osgi.service.environment.Constants.OS_WIN32)) { + if (info.getOS().equals(org.eclipse.osgi.service.environment.Constants.OS_MACOSX)) { + configurationData += " chmod(targetDir:${installFolder}/Eclipse.app/Contents/MacOS, targetFile:eclipse, permissions:755);"; //$NON-NLS-1$ + String config = AbstractPublisherAction.createConfigSpec(null, "macosx", null); + generateLauncherSetter("Eclipse", launcherId, LAUNCHER_VERSION, config, resultantIUs); + } else + configurationData += " chmod(targetDir:${installFolder}, targetFile:" + launcher.getName() + ", permissions:755);"; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + String config = AbstractPublisherAction.createConfigSpec(null, "win32", null); + generateLauncherSetter("eclipse", launcherId, LAUNCHER_VERSION, config, resultantIUs); + } + touchpointData.put("install", configurationData); //$NON-NLS-1$ + String unConfigurationData = "cleanupzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + touchpointData.put("uninstall", unConfigurationData); //$NON-NLS-1$ + cu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + resultantIUs.addIU(MetadataFactory.createInstallableUnitFragment(cu), IPublisherResult.ROOT); + + //Create the artifact descriptor + return createArtifactDescriptor(key, launcher); + } + + public static void generateLauncherSetter(String launcherName, String iuId, Version version, String configSpec, IPublisherResult result) { + InstallableUnitDescription iud = new MetadataFactory.InstallableUnitDescription(); + String id = iuId + '.' + launcherName; + iud.setId(id); + iud.setVersion(version); + iud.setTouchpointType(PublisherHelper.TOUCHPOINT_OSGI); + iud.setCapabilities(new ProvidedCapability[] {PublisherHelper.createSelfCapability(id, version)}); + + String filter = AbstractPublisherAction.createFilterSpec(configSpec); + if (filter.length() > 0) + iud.setFilter(filter); + Map touchpointData = new HashMap(); + touchpointData.put("configure", "setLauncherName(name:" + launcherName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + touchpointData.put("unconfigure", "setLauncherName()"); //$NON-NLS-1$ //$NON-NLS-2$ + iud.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + result.addIU(MetadataFactory.createInstallableUnit(iud), IPublisherResult.ROOT); + } + + public static ProvidedCapability createSelfCapability(String installableUnitId, Version installableUnitVersion) { + return MetadataFactory.createProvidedCapability(IU_NAMESPACE, installableUnitId, installableUnitVersion); + } + + /** + * @deprecated moved to BundlesAction + */ + private static String createUnconfigScript(GeneratorBundleInfo unconfigInfo, boolean isBundleFragment) { + if (unconfigInfo == null) + return ""; //$NON-NLS-1$ + String unconfigScript = "";//$NON-NLS-1$ + if (!isBundleFragment && unconfigInfo.getStartLevel() != BundleInfo.NO_LEVEL) { + unconfigScript += "setStartLevel(startLevel:" + BundleInfo.NO_LEVEL + ");"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (!isBundleFragment && unconfigInfo.isMarkedAsStarted()) { + unconfigScript += "markStarted(started: false);"; //$NON-NLS-1$ + } + + if (unconfigInfo.getSpecialUnconfigCommands() != null) { + unconfigScript += unconfigInfo.getSpecialUnconfigCommands(); + } + return unconfigScript; + + } + + /** + * @deprecated moved to JREAction + */ + private static ProvidedCapability[] generateJRECapability(String installableUnitId, Version installableUnitVersion, InputStream profileStream) { + if (profileStream == null) { + //use the 1.6 profile stored in the generator bundle + try { + profileStream = Activator.getContext().getBundle().getEntry("/profiles/JavaSE-1.6.profile").openStream(); //$NON-NLS-1$ + } catch (IOException e) { + throw new RuntimeException(e); + } + } + Properties p = new Properties(); + try { + p.load(profileStream); + ManifestElement[] jrePackages = ManifestElement.parseHeader("org.osgi.framework.system.packages", (String) p.get("org.osgi.framework.system.packages")); //$NON-NLS-1$ //$NON-NLS-2$ + ProvidedCapability[] exportedPackageAsCapabilities = new ProvidedCapability[jrePackages.length + 1]; + exportedPackageAsCapabilities[0] = createSelfCapability(installableUnitId, installableUnitVersion); + for (int i = 1; i <= jrePackages.length; i++) { + exportedPackageAsCapabilities[i] = MetadataFactory.createProvidedCapability(CAPABILITY_NS_JAVA_PACKAGE, jrePackages[i - 1].getValue(), null); + } + return exportedPackageAsCapabilities; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BundleException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + if (profileStream != null) { + try { + profileStream.close(); + } catch (IOException e) { + //ignore secondary failure + } + } + } + return new ProvidedCapability[0]; + } + + /** + * @deprecated moved to JREAction + */ + private static void generateJREIUData(InstallableUnitDescription iu, String installableUnitId, Version installableUnitVersion, File jreLocation) { + //Look for a JRE profile file to set version and capabilities + File[] profiles = jreLocation.listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.getAbsolutePath().endsWith(".profile"); //$NON-NLS-1$ + } + }); + if (profiles.length != 1) { + iu.setVersion(DEFAULT_JRE_VERSION); + iu.setCapabilities(generateJRECapability(installableUnitId, installableUnitVersion, null)); + return; + } + String profileName = profiles[0].getAbsolutePath().substring(profiles[0].getAbsolutePath().lastIndexOf('/')); + Version version = DEFAULT_JRE_VERSION; + //TODO Find a better way to determine JRE version + if (profileName.indexOf("1.6") > 0) { //$NON-NLS-1$ + version = new Version("1.6"); //$NON-NLS-1$ + } else if (profileName.indexOf("1.5") > 0) { //$NON-NLS-1$ + version = new Version("1.5"); //$NON-NLS-1$ + } else if (profileName.indexOf("1.4") > 0) { //$NON-NLS-1$ + version = new Version("1.4"); //$NON-NLS-1$ + } + iu.setVersion(version); + try { + iu.setCapabilities(generateJRECapability(installableUnitId, installableUnitVersion, new FileInputStream(profiles[0]))); + } catch (FileNotFoundException e) { + //Shouldn't happen, but ignore and fall through to use default + } + } + + // moved to FeatureAction + public static String getFilter(FeatureEntry entry) { + StringBuffer result = new StringBuffer(); + result.append("(&"); //$NON-NLS-1$ + if (entry.getFilter() != null) + result.append(entry.getFilter()); + if (entry.getOS() != null) + result.append("(osgi.os=" + entry.getOS() + ')');//$NON-NLS-1$ + if (entry.getWS() != null) + result.append("(osgi.ws=" + entry.getWS() + ')');//$NON-NLS-1$ + if (entry.getArch() != null) + result.append("(osgi.arch=" + entry.getArch() + ')');//$NON-NLS-1$ + if (entry.getNL() != null) + result.append("(osgi.nl=" + entry.getNL() + ')');//$NON-NLS-1$ + if (result.length() == 2) + return null; + result.append(')'); + return result.toString(); + } + + /** + * @deprecated moved to FeaturesAction + */ + public static String getTransformedId(String original, boolean isPlugin, boolean isGroup) { + return (isPlugin ? original : original + (isGroup ? ".feature.group" : ".feature.jar")); //$NON-NLS-1$//$NON-NLS-2$ + } + + /** + * @deprecated moved to FeaturesAction + */ + public static VersionRange getVersionRange(FeatureEntry entry) { + String versionSpec = entry.getVersion(); + if (versionSpec == null || versionSpec.length() == 0) + // TODO should really be returning VersionRange.emptyRange here... + return null; + Version version = new Version(versionSpec); + if (!entry.isRequires()) { + if ("0.0.0".equals(entry.getVersion())) //$NON-NLS-1$ + return VersionRange.emptyRange; + return new VersionRange(version, true, version, true); + } + String match = entry.getMatch(); + if (match == null || match.equals("compatible")) { //$NON-NLS-1$ + Version upper = new Version(version.getMajor() + 1, 0, 0); + return new VersionRange(version, true, upper, false); + } + if (match.equals("perfect")) //$NON-NLS-1$ + return new VersionRange(version, true, version, true); + if (match.equals("equivalent")) { //$NON-NLS-1$ + Version upper = new Version(version.getMajor(), version.getMinor() + 1, 0); + return new VersionRange(version, true, upper, false); + } + if (match.equals("greaterOrEqual")) //$NON-NLS-1$ + return new VersionRange(version, true, new VersionRange(null).getMaximum(), true); + return null; + } + + /** + * @deprecated moved to BundlesAction + */ + public static Map getBundleAdvice(String bundleLocation) { + if (bundleLocation == null) + return Collections.EMPTY_MAP; + + File bundle = new File(bundleLocation); + if (!bundle.exists()) + return Collections.EMPTY_MAP; + + ZipFile jar = null; + InputStream stream = null; + if (bundle.isDirectory()) { + File adviceFile = new File(bundle, BUNDLE_ADVICE_FILE); + if (adviceFile.exists()) { + try { + stream = new BufferedInputStream(new FileInputStream(adviceFile)); + } catch (IOException e) { + return Collections.EMPTY_MAP; + } + } + } else if (bundle.isFile()) { + try { + jar = new ZipFile(bundle); + ZipEntry entry = jar.getEntry(BUNDLE_ADVICE_FILE); + if (entry != null) + stream = new BufferedInputStream(jar.getInputStream(entry)); + } catch (IOException e) { + if (jar != null) + try { + jar.close(); + } catch (IOException e1) { + //boo + } + return Collections.EMPTY_MAP; + } + } + + Properties advice = null; + if (stream != null) { + try { + advice = new Properties(); + advice.load(stream); + } catch (IOException e) { + return Collections.EMPTY_MAP; + } finally { + try { + stream.close(); + } catch (IOException e) { + //boo + } + } + } + + if (jar != null) { + try { + jar.close(); + } catch (IOException e) { + // boo + } + } + + return advice != null ? advice : Collections.EMPTY_MAP; + } + + /** + * @deprecated moved to BundlesAction + */ + private static boolean isOptional(ImportPackageSpecification importedPackage) { + if (importedPackage.getDirective(Constants.RESOLUTION_DIRECTIVE).equals(ImportPackageSpecification.RESOLUTION_DYNAMIC) || importedPackage.getDirective(Constants.RESOLUTION_DIRECTIVE).equals(ImportPackageSpecification.RESOLUTION_OPTIONAL)) + return true; + return false; + } + + /** + * @deprecated moved to BundlesAction + */ + private static String toManifestString(Map p) { + if (p == null) + return null; + Collection properties = p.entrySet(); + StringBuffer result = new StringBuffer(); + for (Iterator iterator = properties.iterator(); iterator.hasNext();) { + Map.Entry aProperty = (Map.Entry) iterator.next(); + if (aProperty.getKey().equals(BundlesAction.BUNDLE_SHAPE)) + continue; + result.append(aProperty.getKey()).append(": ").append(aProperty.getValue()).append('\n'); //$NON-NLS-1$ + } + return result.toString(); + } + + // Return a map from locale to property set for the manifest localizations + // from the given bundle directory and given bundle localization path/name + // manifest property value. + /** + * @deprecated moved to BundlesAction + */ + private static Map getManifestLocalizations(Map manifest, File bundleLocation) { + Map localizations; + Locale defaultLocale = null; // = Locale.ENGLISH; // TODO: get this from GeneratorInfo + String[] bundleManifestValues = getManifestCachedValues(manifest); + String bundleLocalization = bundleManifestValues[BUNDLE_LOCALIZATION_INDEX]; + + if ("jar".equalsIgnoreCase(new Path(bundleLocation.getName()).getFileExtension()) && //$NON-NLS-1$ + bundleLocation.isFile()) { + localizations = LocalizationHelper.getJarPropertyLocalizations(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues); + //localizations = getJarManifestLocalization(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues); + } else { + localizations = LocalizationHelper.getDirPropertyLocalizations(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues); + // localizations = getDirManifestLocalization(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues); + } + + return localizations; + } + + /** + * @deprecated moved to BundlesAction + */ + public static String[] getManifestCachedValues(Map manifest) { + String[] cachedValues = new String[BUNDLE_LOCALIZED_PROPERTIES.length + 1]; + for (int j = 0; j < PublisherHelper.BUNDLE_LOCALIZED_PROPERTIES.length; j++) { + String value = (String) manifest.get(BUNDLE_LOCALIZED_PROPERTIES[j]); + if (value != null && value.length() > 1 && value.charAt(0) == '%') { + cachedValues[j] = value.substring(1); + } + } + String localizationFile = (String) manifest.get(org.osgi.framework.Constants.BUNDLE_LOCALIZATION); + cachedValues[BUNDLE_LOCALIZATION_INDEX] = (localizationFile != null ? localizationFile : DEFAULT_BUNDLE_LOCALIZATION); + return cachedValues; + } + + // Return a map from locale to property set for the manifest localizations + // from the given bundle directory and given bundle localization path/name + // manifest property value. + /** + * @deprecated moved to BundlesAction + */ + public static Map getHostLocalizations(File bundleLocation, String[] hostBundleManifestValues) { + Map localizations; + Locale defaultLocale = null; // = Locale.ENGLISH; // TODO: get this from GeneratorInfo + String hostBundleLocalization = hostBundleManifestValues[BUNDLE_LOCALIZATION_INDEX]; + + if ("jar".equalsIgnoreCase(new Path(bundleLocation.getName()).getFileExtension()) && //$NON-NLS-1$ + bundleLocation.isFile()) { + localizations = LocalizationHelper.getJarPropertyLocalizations(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues); + //localizations = getJarManifestLocalization(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues); + } else { + localizations = LocalizationHelper.getDirPropertyLocalizations(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues); + // localizations = getDirManifestLocalization(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues); + } + + return localizations; + } + + // TODO this does not appear to be used... + static public String getLocaleString(String filename, String filenamePrefix) { + String localeString = null; + if (filename.startsWith(filenamePrefix) && filename.endsWith(PROPERTIES_FILE_EXTENSION)) { + if (filename.length() > filenamePrefix.length() + PROPERTIES_FILE_EXTENSION.length()) { + localeString = filename.substring(filenamePrefix.length() + 1, filename.length() - PROPERTIES_FILE_EXTENSION.length()); + } else { + localeString = ""; //$NON-NLS-1$ + } + } + return localeString; + } + + /** + * @deprecated moved to FeaturesAction + */ + public static Object[] createFeatureRootFileIU(String featureId, String featureVersion, File location, FileSetDescriptor descriptor) { + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + iu.setSingleton(true); + String id = featureId + '_' + descriptor.getKey(); + iu.setId(id); + Version version = new Version(featureVersion); + iu.setVersion(version); + iu.setCapabilities(new ProvidedCapability[] {createSelfCapability(id, version)}); + iu.setTouchpointType(TOUCHPOINT_NATIVE); + String configSpec = descriptor.getConfigSpec(); + if (configSpec != null) + iu.setFilter(AbstractPublisherAction.createFilterSpec(configSpec)); + File[] fileResult = attachFiles(iu, descriptor, location); + setupLinks(iu, descriptor); + setupPermissions(iu, descriptor); + + IInstallableUnit iuResult = MetadataFactory.createInstallableUnit(iu); + // need to return both the iu and any files. + return new Object[] {iuResult, fileResult}; + } + + // attach the described files from the given location to the given iu description. Return + // the list of files identified. + /** + * @deprecated moved to FeaturesAction + */ + private static File[] attachFiles(InstallableUnitDescription iu, FileSetDescriptor descriptor, File location) { + String fileList = descriptor.getFiles(); + String[] fileSpecs = getArrayFromString(fileList, ","); //$NON-NLS-1$ + File[] files = new File[fileSpecs.length]; + if (fileSpecs.length > 0) { + for (int i = 0; i < fileSpecs.length; i++) { + String spec = fileSpecs[i]; + if (spec.startsWith("file:")) + spec = spec.substring(5); + files[i] = new File(location, spec); + } + } + // add touchpoint actions to unzip and cleanup as needed + // TODO need to support fancy root file location specs + Map touchpointData = new HashMap(2); + String configurationData = "unzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + touchpointData.put("install", configurationData); //$NON-NLS-1$ + String unConfigurationData = "cleanupzip(source:@artifact, target:${installFolder});"; //$NON-NLS-1$ + touchpointData.put("uninstall", unConfigurationData); //$NON-NLS-1$ + iu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + + // prime the IU with an artifact key that will correspond to the zipped up root files. + IArtifactKey key = createLauncherArtifactKey(iu.getId(), iu.getVersion()); + iu.setArtifacts(new IArtifactKey[] {key}); + return files; + } + + /** + * @deprecated moved to FeaturesAction + */ + private static void setupPermissions(InstallableUnitDescription iu, FileSetDescriptor descriptor) { + Map touchpointData = new HashMap(); + String[][] permsList = descriptor.getPermissions(); + for (int i = 0; i < permsList.length; i++) { + String[] permSpec = permsList[i]; + String configurationData = " chmod(targetDir:${installFolder}, targetFile:" + permSpec[1] + ", permissions:" + permSpec[0] + ");"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + touchpointData.put("install", configurationData); //$NON-NLS-1$ + iu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData)); + } + } + + /** + * @deprecated moved to FeaturesAction + */ + private static void setupLinks(InstallableUnitDescription iu, FileSetDescriptor descriptor) { + // TODO setup the link support. + } + + public static String[] getArrayFromString(String list, String separator) { + if (list == null || list.trim().equals("")) //$NON-NLS-1$ + return new String[0]; + List result = new ArrayList(); + for (StringTokenizer tokens = new StringTokenizer(list, separator); tokens.hasMoreTokens();) { + String token = tokens.nextToken().trim(); + if (!token.equals("")) //$NON-NLS-1$ + result.add(token); + } + return (String[]) result.toArray(new String[result.size()]); + } + +} |