Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/prov/metadata/generator/MetadataGeneratorHelper.java')
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/prov/metadata/generator/MetadataGeneratorHelper.java504
1 files changed, 504 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/prov/metadata/generator/MetadataGeneratorHelper.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/prov/metadata/generator/MetadataGeneratorHelper.java
new file mode 100644
index 000000000..e315d5ba5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/prov/metadata/generator/MetadataGeneratorHelper.java
@@ -0,0 +1,504 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.prov.metadata.generator;
+
+import java.io.*;
+import java.util.*;
+import org.eclipse.equinox.frameworkadmin.BundleInfo;
+import org.eclipse.equinox.internal.prov.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.prov.metadata.generator.Activator;
+import org.eclipse.equinox.prov.artifact.repository.ArtifactDescriptor;
+import org.eclipse.equinox.prov.artifact.repository.IArtifactDescriptor;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.environment.EnvironmentInfo;
+import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.*;
+
+public class MetadataGeneratorHelper {
+ private static final String ECLIPSE_EXTENSIBLE_API = "Eclipse-ExtensibleAPI"; //$NON-NLS-1$
+
+ private static final String CAPABILITY_TYPE_OSGI_PACKAGES = "osgi.packages"; //$NON-NLS-1$
+
+ private static final Version versionMax = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ private static final String ECLIPSE_TOUCHPOINT = "eclipse"; //$NON-NLS-1$
+ private static final Version ECLIPSE_TOUCHPOINT_VERSION = new Version(1, 0, 0);
+
+ private static final String NATIVE_TOUCHPOINT = "native"; //$NON-NLS-1$
+ private static final Version NATIVE_TOUCHPOINT_VERSION = new Version(1, 0, 0);
+
+ private static final String ECLIPSE_ARTIFACT_NAMESPACE = "eclipse"; //$NON-NLS-1$
+ private static final String ECLIPSE_ARTIFACT_CLASSIFIER = "plugin"; //$NON-NLS-1$
+
+ private static final String ORG_ECLIPSE_EXECUTABLE = "org.eclipse.executable"; //$NON-NLS-1$
+ private static final Version ORG_ECLIPSE_EXECUTABLE_VERSION = new Version(1, 0, 0);
+ private static final String IU_NAMESPACE = IInstallableUnit.IU_NAMESPACE;
+
+ private static final String[] BUNDLE_IU_PROPERTY_MAP = {Constants.BUNDLE_NAME, IInstallableUnitConstants.NAME, Constants.BUNDLE_DESCRIPTION, IInstallableUnitConstants.DESCRIPTION, Constants.BUNDLE_VENDOR, IInstallableUnitConstants.PROVIDER, Constants.BUNDLE_CONTACTADDRESS, IInstallableUnitConstants.CONTACT, Constants.BUNDLE_COPYRIGHT, IInstallableUnitConstants.COPYRIGHT, Constants.BUNDLE_DOCURL, IInstallableUnitConstants.DOC_URL, Constants.BUNDLE_UPDATELOCATION, IInstallableUnitConstants.UPDATE_SITE};
+
+ private static final Version DEFAULT_JRE_VERSION = new Version("1.5"); //$NON-NLS-1$
+
+ /**
+ * Creates IUs and artifact descriptors for the JRE, and adds them to the given sets.
+ * if the jreLocation is <code>null</code>, default information is generated.
+ */
+ public static void createJREData(File jreLocation, Set resultantIUs, Set resultantArtifactDescriptors) {
+ InstallableUnit iu = new InstallableUnit();
+ iu.setSingleton(false);
+ iu.setId("a.jre"); //$NON-NLS-1$
+ iu.setTouchpointType(new TouchpointType(NATIVE_TOUCHPOINT, NATIVE_TOUCHPOINT_VERSION));
+ if (jreLocation == null || !jreLocation.exists()) {
+ //set some reasonable defaults
+ iu.setVersion(DEFAULT_JRE_VERSION);
+ iu.setCapabilities(generateJRECapability(null));
+ resultantIUs.add(iu);
+ return;
+ }
+ generateJREIUData(iu, jreLocation);
+
+ //Generate artifact for JRE
+ IArtifactKey key = new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, NATIVE_TOUCHPOINT, iu.getId(), iu.getVersion());
+ iu.setArtifacts(new IArtifactKey[] {key});
+ iu.setTouchpointType(new TouchpointType(NATIVE_TOUCHPOINT, new Version(1, 0, 0)));
+ resultantIUs.add(iu);
+
+ //Create the CU
+ InstallableUnitFragment cu = new InstallableUnitFragment();
+ cu.setId("config." + iu.getId()); //$NON-NLS-1$
+ cu.setVersion(iu.getVersion());
+ cu.setHost(iu.getId(), new VersionRange(iu.getVersion(), true, versionMax, true));
+
+ cu.setTouchpointType(new TouchpointType(NATIVE_TOUCHPOINT, NATIVE_TOUCHPOINT_VERSION));
+ Map touchpointData = new HashMap();
+ String configurationData = "Zip.unzip(artifact, currentDir, null);";
+ EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName());
+ touchpointData.put("configurationData", configurationData);
+ cu.setImmutableTouchpointData(new TouchpointData(touchpointData));
+ resultantIUs.add(cu);
+
+ //Create the artifact descriptor
+ IArtifactDescriptor descriptor = createArtifactDescriptor(key, jreLocation, false, true);
+ resultantArtifactDescriptors.add(descriptor);
+ }
+
+ private static void generateJREIUData(InstallableUnit iu, 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(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.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(new FileInputStream(profiles[0])));
+ } catch (FileNotFoundException e) {
+ //Shouldn't happen, but ignore and fall through to use default
+ }
+ }
+
+ /**
+ * Creates IUs and artifacts for the Eclipse executable, and adds them to the given
+ * sets.
+ */
+ public static void createLauncherData(File launcher, String configurationFlavor, Set resultantIUs, Set resultantArtifactDescriptors) {
+ if (launcher == null || !launcher.exists())
+ return;
+
+ //Create the IU
+ InstallableUnit iu = new InstallableUnit();
+ iu.setSingleton(true);
+ iu.setId(ORG_ECLIPSE_EXECUTABLE);
+ iu.setVersion(ORG_ECLIPSE_EXECUTABLE_VERSION);
+
+ IArtifactKey key = new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, NATIVE_TOUCHPOINT, ORG_ECLIPSE_EXECUTABLE, ORG_ECLIPSE_EXECUTABLE_VERSION);
+ iu.setArtifacts(new IArtifactKey[] {key});
+ iu.setTouchpointType(new TouchpointType(NATIVE_TOUCHPOINT, new Version(1, 0, 0)));
+ resultantIUs.add(iu);
+
+ //Create the CU
+ InstallableUnitFragment cu = new InstallableUnitFragment();
+ cu.setId(configurationFlavor + iu.getId());
+ cu.setVersion(iu.getVersion());
+ cu.setHost(iu.getId(), new VersionRange(iu.getVersion(), true, versionMax, true));
+
+ cu.setTouchpointType(new TouchpointType(NATIVE_TOUCHPOINT, NATIVE_TOUCHPOINT_VERSION));
+ Map touchpointData = new HashMap();
+ String configurationData = "Zip.unzip(artifact, currentDir, null);";
+ EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName());
+ if (!info.getOS().equals(org.eclipse.osgi.service.environment.Constants.OS_WIN32))
+ // FIXME: is this correct? do all non-Windows platforms need execute permissions on the launcher?
+ configurationData += " Permissions.chmod(currentDir, \"" + launcher.getName() + "\", 755);";
+ touchpointData.put("configurationData", configurationData);
+ cu.setImmutableTouchpointData(new TouchpointData(touchpointData));
+ resultantIUs.add(cu);
+
+ //Create the artifact descriptor
+ IArtifactDescriptor descriptor = createArtifactDescriptor(new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, NATIVE_TOUCHPOINT, ORG_ECLIPSE_EXECUTABLE, ORG_ECLIPSE_EXECUTABLE_VERSION), launcher, false, true);
+ resultantArtifactDescriptors.add(descriptor);
+ }
+
+ private static ProvidedCapability[] generateJRECapability(InputStream profileStream) {
+ if (profileStream == null) {
+ //use the 1.5 profile stored in the generator bundle
+ try {
+ profileStream = Activator.getContext().getBundle().getEntry("J2SE-1.5.profile").openStream();
+ } 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"));
+ ProvidedCapability[] exportedPackageAsCapabilities = new ProvidedCapability[jrePackages.length];
+ for (int i = 0; i < jrePackages.length; i++) {
+ exportedPackageAsCapabilities[i] = new ProvidedCapability("osgi.packages", jrePackages[i].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];
+ }
+
+ public static IInstallableUnit createEclipseConfigurationUnit(String iuId, Version iuVersion, boolean isBundleFragment, GeneratorBundleInfo configInfo, String configurationFlavor) {
+ if (configInfo == null)
+ return null;
+
+ InstallableUnitFragment cu = new InstallableUnitFragment();
+ cu.setId(configurationFlavor + iuId);
+ cu.setVersion(iuVersion);
+
+ //Indicate the IU to which this CU apply
+ cu.setHost(iuId, new VersionRange(iuVersion, true, versionMax, true));
+
+ //Add a capability describing the flavor supported
+ cu.setCapabilities(new ProvidedCapability[] {new ProvidedCapability(IInstallableUnit.FLAVOR_NAMESPACE, configurationFlavor, Version.emptyVersion)});
+
+ cu.setTouchpointType(new TouchpointType(ECLIPSE_TOUCHPOINT, ECLIPSE_TOUCHPOINT_VERSION)); //TODO Is this necessary? I think we get that from the IU
+
+ Map touchpointData = new HashMap();
+ touchpointData.put("configurationData", createConfigScript(configInfo, isBundleFragment));
+ touchpointData.put("unconfigurationData", createUnconfigScript(configInfo, isBundleFragment));
+ cu.setImmutableTouchpointData(new TouchpointData(touchpointData));
+
+ return cu;
+ }
+
+ public static IInstallableUnit createEclipseDefaultConfigurationUnit(GeneratorBundleInfo configInfo, GeneratorBundleInfo unconfigInfo, String configurationFlavor) {
+ InstallableUnitFragment cu = new InstallableUnitFragment();
+ cu.setId(configurationFlavor + "default");
+ cu.setVersion(new Version(1, 0, 0));
+
+ //Add a capability describing the flavor supported
+ cu.setCapabilities(new ProvidedCapability[] {new ProvidedCapability(IInstallableUnit.FLAVOR_NAMESPACE, configurationFlavor, Version.emptyVersion)});
+
+ //Create a capability on bundles
+ RequiredCapability[] reqs = new RequiredCapability[] {new RequiredCapability(IInstallableUnit.CAPABILITY_ECLIPSE_TYPES, IInstallableUnit.CAPABILITY_ECLIPSE_BUNDLE, VersionRange.emptyRange, null, false, true)};
+ cu.setRequiredCapabilities(reqs);
+ cu.setTouchpointType(new TouchpointType(ECLIPSE_TOUCHPOINT, ECLIPSE_TOUCHPOINT_VERSION)); //TODO Is this necessary? I think we get that from the IU
+ Map touchpointData = new HashMap();
+
+ touchpointData.put("configurationData", createDefaultConfigScript(configInfo));
+ touchpointData.put("unconfigurationData", createDefaultUnconfigScript(unconfigInfo));
+
+ cu.setImmutableTouchpointData(new TouchpointData(touchpointData));
+ return cu;
+ }
+
+ private static String createDefaultConfigScript(GeneratorBundleInfo configInfo) {
+ String configScript = "";//$NON-NLS-1$
+ if (configInfo != null) {
+ if (configInfo.getStartLevel() != BundleInfo.NO_LEVEL) {
+ configScript += "bundleToInstall.setStartLevel(" + configInfo.getStartLevel() + ");";
+ }
+ if (configInfo.isMarkedAsStarted()) {
+ configScript += "bundleToInstall.setMarkedAsStarted(true);";
+ }
+ if (configInfo.getSpecialConfigCommands() != null) {
+ configScript += configInfo.getSpecialConfigCommands();
+ }
+ }
+ return configScript;
+ }
+
+ private static String createDefaultUnconfigScript(GeneratorBundleInfo unconfigInfo) {
+ String unconfigScript = ""; //$NON-NLS-1$
+ if (unconfigInfo != null) {
+ if (unconfigInfo.getSpecialConfigCommands() != null) {
+ unconfigScript += unconfigInfo.getSpecialConfigCommands();
+ }
+ }
+ return unconfigScript;
+ }
+
+ private static String createConfigScript(GeneratorBundleInfo configInfo, boolean isBundleFragment) {
+ String configScript = "manipulator.getConfigData().addBundle(bundleToInstall);";
+ if (configInfo != null) {
+ if (!isBundleFragment && configInfo.getStartLevel() != BundleInfo.NO_LEVEL) {
+ configScript += "bundleToInstall.setStartLevel(" + configInfo.getStartLevel() + ");";
+ }
+ if (!isBundleFragment && configInfo.isMarkedAsStarted()) {
+ configScript += "bundleToInstall.setMarkedAsStarted(true);";
+ }
+ if (configInfo.getSpecialConfigCommands() != null) {
+ configScript += configInfo.getSpecialConfigCommands();
+ }
+ }
+ return configScript;
+ }
+
+ private static String createUnconfigScript(GeneratorBundleInfo configInfo, boolean isBundleFragment) {
+ String unconfigScript = "";
+ if (configInfo != null) {
+ if (!isBundleFragment && configInfo.getStartLevel() != BundleInfo.NO_LEVEL) {
+ unconfigScript += "bundleToRemove.setStartLevel(" + BundleInfo.NO_LEVEL + ");";
+ }
+ if (!isBundleFragment && configInfo.isMarkedAsStarted()) {
+ unconfigScript += "bundleToRemove.setMarkedAsStarted(false);";
+ }
+ if (configInfo.getSpecialConfigCommands() != null) {
+ // TODO: how should special config commands be removed
+ // unconfigScript += "foobar.remove(" + configInfo.getSpecialConfigCommands() + ");";
+ }
+ }
+ unconfigScript += "manipulator.getConfigData().removeBundle(bundleToRemove);";
+ return unconfigScript;
+ }
+
+ private static boolean requireAFragment(BundleDescription bd, Map manifest) {
+ if (manifest == null)
+ return false;
+ if (manifest.get(ECLIPSE_EXTENSIBLE_API) == null)
+ return false;
+ if (bd.getSymbolicName().equals("org.eclipse.osgi")) //Special case for OSGi
+ return false;
+ String classpath = (String) ((Map) bd.getUserObject()).get(Constants.BUNDLE_CLASSPATH);
+ if (classpath == null)
+ return true;
+ ManifestElement[] classpathEntries;
+ try {
+ classpathEntries = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, classpath);
+ if (classpathEntries.length != 0 && classpathEntries[0].getValue().equals("."))
+ return true;
+ } catch (BundleException e) {
+ //If we are here, it is that we have already parsed the bundle manifest and it contains no error
+ }
+ return false;
+ }
+
+ public static IInstallableUnit createEclipseIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key) {
+ InstallableUnit iu = new InstallableUnit();
+ iu.setSingleton(bd.isSingleton());
+ iu.setId(bd.getSymbolicName());
+ iu.setVersion(bd.getVersion());
+ iu.setFilter(bd.getPlatformFilter());
+ iu.setProperty(IInstallableUnitConstants.UPDATE_FROM, bd.getSymbolicName());
+ iu.setProperty(IInstallableUnitConstants.UPDATE_RANGE, VersionRange.emptyRange.toString());
+
+ 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(new RequiredCapability("fragment", iu.getId(), VersionRange.emptyRange, null, false, false));
+ if (isFragment)
+ reqsDeps.add(RequiredCapability.createRequiredCapabilityForName(bd.getHost().getName(), bd.getHost().getVersionRange(), false));
+ for (int j = 0; j < requiredBundles.length; j++)
+ reqsDeps.add(RequiredCapability.createRequiredCapabilityForName(requiredBundles[j].getName(), requiredBundles[j].getVersionRange() == VersionRange.emptyRange ? null : requiredBundles[j].getVersionRange(), requiredBundles[j].isOptional()));
+
+ //Process the import package
+ 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(new RequiredCapability(CAPABILITY_TYPE_OSGI_PACKAGES, importPackageName, versionRange, null, isOptional(importSpec), false));
+ }
+ iu.setRequiredCapabilities((RequiredCapability[]) reqsDeps.toArray(new RequiredCapability[reqsDeps.size()]));
+
+ //Process the export package
+ ExportPackageDescription exports[] = bd.getExportPackages();
+ ProvidedCapability[] exportedPackageAsCapabilities = new ProvidedCapability[exports.length + 1 + (isFragment ? 1 : 0)];
+ exportedPackageAsCapabilities[exports.length] = new ProvidedCapability(IInstallableUnit.CAPABILITY_ECLIPSE_TYPES, IInstallableUnit.CAPABILITY_ECLIPSE_BUNDLE, new Version(1, 0, 0)); //Here we add a bundle capability to identify bundles
+ for (int i = 0; i < exports.length; i++) {
+ exportedPackageAsCapabilities[i] = new ProvidedCapability(CAPABILITY_TYPE_OSGI_PACKAGES, exports[i].getName(), exports[i].getVersion() == Version.emptyVersion ? null : exports[i].getVersion()); //TODO make sure that we support all the refinement on the exports
+ }
+ if (isFragment)
+ exportedPackageAsCapabilities[exportedPackageAsCapabilities.length - 1] = new ProvidedCapability("fragment", bd.getHost().getName(), bd.getVersion());
+ iu.setCapabilities(exportedPackageAsCapabilities);
+ iu.setApplicabilityFilter("");
+
+ iu.setArtifacts(new IArtifactKey[] {key});
+
+ iu.setTouchpointType(new TouchpointType(ECLIPSE_TOUCHPOINT, ECLIPSE_TOUCHPOINT_VERSION));
+
+ // Set IU properties from the manifest header attributes
+ // TODO The values of the attributes may be localized. Metadata generation
+ // should construct property files for the IU based on the bundle/plug-in
+ // property files in whatever locales are provided.
+ 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) {
+ 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");
+ touchpointData.put("manifest", toManifestString(manifest));
+ iu.setImmutableTouchpointData(new TouchpointData(touchpointData));
+ return iu;
+ }
+
+ public static VersionRange getVersionRange(FeatureEntry entry) {
+ String versionSpec = entry.getVersion();
+ if (versionSpec == null)
+ // TODO should really be returning VersionRange.emptyRange here...
+ return null;
+ Version version = new Version(versionSpec);
+ if (!entry.isRequires())
+ return new VersionRange(version, true, version, true);
+ String match = entry.getMatch();
+ if (match == null)
+ // TODO should really be returning VersionRange.emptyRange here...
+ return null;
+ if (match.equals("perfect"))
+ return new VersionRange(version, true, version, true);
+ if (match.equals("equivalent")) {
+ Version upper = new Version(version.getMajor(), version.getMinor() + 1, 0);
+ return new VersionRange(version, true, upper, false);
+ }
+ if (match.equals("compatible")) {
+ Version upper = new Version(version.getMajor() + 1, 0, 0);
+ return new VersionRange(version, true, upper, false);
+ }
+ if (match.equals("greaterOrEqual"))
+ return new VersionRange(version, true, new VersionRange(null).getMaximum(), true);
+ return null;
+ }
+
+ private static String getTransformedId(String original, boolean isPlugin) {
+ return isPlugin ? original : original + ".featureIU";
+ }
+
+ public static IInstallableUnit createGroupIU(Feature feature) {
+ InstallableUnit iu = new InstallableUnit();
+ iu.setId(getTransformedId(feature.getId(), false));
+ iu.setVersion(new Version(feature.getVersion()));
+ iu.setProperty(IInstallableUnitConstants.UPDATE_FROM, iu.getId());
+ iu.setProperty(IInstallableUnitConstants.UPDATE_RANGE, VersionRange.emptyRange.toString());
+
+ FeatureEntry entries[] = feature.getEntries();
+ RequiredCapability[] required = new RequiredCapability[entries.length];
+ for (int i = 0; i < entries.length; i++) {
+ VersionRange range = getVersionRange(entries[i]);
+ required[i] = new RequiredCapability(IU_NAMESPACE, getTransformedId(entries[i].getId(), entries[i].isPlugin()), range, getFilter(entries[i]), entries[i].isOptional(), false);
+ }
+ iu.setRequiredCapabilities(required);
+ iu.setTouchpointType(TouchpointType.NONE);
+ ProvidedCapability groupCapability = new ProvidedCapability(IInstallableUnit.IU_KIND_NAMESPACE, "group", new Version("1.0.0"));
+ iu.setCapabilities(new ProvidedCapability[] {groupCapability});
+ return iu;
+ }
+
+ 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();
+ }
+
+ 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;
+ }
+
+ 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();
+ result.append(aProperty.getKey()).append(": ").append(aProperty.getValue()).append('\n');
+ }
+ return result.toString();
+ }
+
+ public static IArtifactKey createEclipseArtifactKey(String bsn, String version) {
+ return new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, ECLIPSE_ARTIFACT_CLASSIFIER, bsn, new Version(version));
+ }
+
+ public static IArtifactDescriptor createArtifactDescriptor(IArtifactKey key, File pathOnDisk, boolean asIs, boolean recurse) {
+ //TODO this size calculation is bogus
+ ArtifactDescriptor result = new ArtifactDescriptor(key);
+ if (pathOnDisk != null)
+ result.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, Long.toString(pathOnDisk.length()));
+ return result;
+ }
+}

Back to the top