| /******************************************************************************* |
| * 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.p2.metadata.generator; |
| |
| import java.io.*; |
| import java.util.*; |
| import org.eclipse.equinox.frameworkadmin.BundleInfo; |
| import org.eclipse.equinox.internal.p2.metadata.ArtifactKey; |
| import org.eclipse.equinox.internal.p2.metadata.generator.Activator; |
| import org.eclipse.equinox.p2.artifact.repository.ArtifactDescriptor; |
| import org.eclipse.equinox.p2.artifact.repository.IArtifactDescriptor; |
| import org.eclipse.equinox.p2.core.helpers.ServiceHelper; |
| import org.eclipse.equinox.p2.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[] 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 String CAPABILITY_TYPE_OSGI_PACKAGES = "osgi.packages"; //$NON-NLS-1$ |
| |
| private static final Version DEFAULT_JRE_VERSION = new Version("1.5"); //$NON-NLS-1$ |
| |
| private static final String ECLIPSE_ARTIFACT_CLASSIFIER = "plugin"; //$NON-NLS-1$ |
| private static final String ECLIPSE_ARTIFACT_NAMESPACE = "eclipse"; //$NON-NLS-1$ |
| |
| private static final String ECLIPSE_EXTENSIBLE_API = "Eclipse-ExtensibleAPI"; //$NON-NLS-1$ |
| |
| private static final String IU_NAMESPACE = IInstallableUnit.IU_NAMESPACE; |
| |
| private static final String LAUNCHER_ID_PREFIX = "org.eclipse.launcher"; //$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); |
| |
| private static final Version versionMax = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); |
| |
| public static final TouchpointType TOUCHPOINT_NATIVE = new TouchpointType("native", new Version(1, 0, 0)); //$NON-NLS-1$ |
| public static final TouchpointType TOUCHPOINT_ECLIPSE = new TouchpointType("eclipse", new Version(1, 0, 0)); //$NON-NLS-1$ |
| |
| 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())); |
| // 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; |
| } |
| |
| private static String createConfigScript(GeneratorBundleInfo configInfo, boolean isBundleFragment) { |
| if (configInfo == null) |
| return ""; |
| |
| String configScript = "";//$NON-NLS-1$ |
| if (!isBundleFragment && configInfo.getStartLevel() != BundleInfo.NO_LEVEL) { |
| configScript += "setStartLevel(startLevel:" + configInfo.getStartLevel() + ");"; |
| } |
| if (!isBundleFragment && configInfo.isMarkedAsStarted()) { |
| configScript += "markStarted(started: true);"; |
| } |
| |
| if (configInfo.getSpecialConfigCommands() != null) { |
| configScript += configInfo.getSpecialConfigCommands(); |
| } |
| |
| return configScript; |
| } |
| |
| private static String createDefaultConfigScript(GeneratorBundleInfo configInfo) { |
| return createConfigScript(configInfo, false); |
| } |
| |
| private static String createDefaultUnconfigScript(GeneratorBundleInfo unconfigInfo) { |
| return createUnconfigScript(unconfigInfo, false); |
| } |
| |
| public static IArtifactKey createEclipseArtifactKey(String bsn, String version) { |
| return new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, ECLIPSE_ARTIFACT_CLASSIFIER, bsn, new Version(version)); |
| } |
| |
| 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(TOUCHPOINT_ECLIPSE); //TODO Is this necessary? I think we get that from the IU |
| |
| Map touchpointData = new HashMap(); |
| touchpointData.put("install", "installBundle(bundle:${artifactId})"); |
| touchpointData.put("uninstall", "uninstallBundle(bundle:${artifactId})"); |
| touchpointData.put("configure", createConfigScript(configInfo, isBundleFragment)); |
| touchpointData.put("unconfigure", 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(TOUCHPOINT_ECLIPSE); //TODO Is this necessary? I think we get that from the IU |
| Map touchpointData = new HashMap(); |
| |
| touchpointData.put("install", "installBundle(bundle:${artifactId})"); |
| touchpointData.put("uninstall", "uninstallBundle(bundle:${artifactId})"); |
| touchpointData.put("configure", createDefaultConfigScript(configInfo)); |
| touchpointData.put("unconfigure", createDefaultUnconfigScript(unconfigInfo)); |
| |
| cu.setImmutableTouchpointData(new TouchpointData(touchpointData)); |
| return cu; |
| } |
| |
| 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(TOUCHPOINT_ECLIPSE); |
| |
| // 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 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; |
| } |
| |
| /** |
| * 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. |
| */ |
| public static IArtifactDescriptor createJREData(File jreLocation, Set resultantIUs) { |
| InstallableUnit iu = new InstallableUnit(); |
| iu.setSingleton(false); |
| iu.setId("a.jre"); //$NON-NLS-1$ |
| iu.setTouchpointType(TOUCHPOINT_NATIVE); |
| |
| 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(TOUCHPOINT_NATIVE); |
| Map touchpointData = new HashMap(); |
| |
| if (jreLocation == null || !jreLocation.exists()) { |
| //set some reasonable defaults |
| iu.setVersion(DEFAULT_JRE_VERSION); |
| iu.setCapabilities(generateJRECapability(null)); |
| resultantIUs.add(iu); |
| |
| touchpointData.put("install", ""); |
| cu.setImmutableTouchpointData(new TouchpointData(touchpointData)); |
| resultantIUs.add(cu); |
| return null; |
| } |
| generateJREIUData(iu, jreLocation); |
| |
| //Generate artifact for JRE |
| IArtifactKey key = new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, TOUCHPOINT_NATIVE.getId(), iu.getId(), iu.getVersion()); |
| iu.setArtifacts(new IArtifactKey[] {key}); |
| resultantIUs.add(iu); |
| |
| //Create config info for the CU |
| String configurationData = "unzip(source:@artifact, target:${installFolder});"; |
| touchpointData.put("install", configurationData); |
| cu.setImmutableTouchpointData(new TouchpointData(touchpointData)); |
| resultantIUs.add(cu); |
| |
| //Create the artifact descriptor |
| return createArtifactDescriptor(key, jreLocation, false, true); |
| } |
| |
| /** |
| * 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, Set resultantIUs) { |
| if (launcher == null || !launcher.exists()) |
| return null; |
| |
| //Create the IU |
| InstallableUnit iu = new InstallableUnit(); |
| 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.setTouchpointType(TOUCHPOINT_NATIVE); |
| 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(TOUCHPOINT_NATIVE); |
| Map touchpointData = new HashMap(); |
| String configurationData = "unzip(source:@artifact, target:${installFolder});"; |
| 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 += " chmod(targetDir:${installFolder}, targetFile:" + launcher.getName() + ", permissions:755);"; |
| touchpointData.put("install", configurationData); |
| cu.setImmutableTouchpointData(new TouchpointData(touchpointData)); |
| resultantIUs.add(cu); |
| |
| //Create the artifact descriptor |
| return createArtifactDescriptor(key, launcher, false, true); |
| } |
| |
| public static ArtifactKey createLauncherArtifactKey(String id, Version version) { |
| return new ArtifactKey(ECLIPSE_ARTIFACT_NAMESPACE, TOUCHPOINT_NATIVE.getId(), id, version); |
| } |
| |
| private static String createUnconfigScript(GeneratorBundleInfo unconfigInfo, boolean isBundleFragment) { |
| if (unconfigInfo == null) |
| return ""; |
| String unconfigScript = "";//$NON-NLS-1$ |
| if (!isBundleFragment && unconfigInfo.getStartLevel() != BundleInfo.NO_LEVEL) { |
| unconfigScript += "setStartLevel(startLevel:" + BundleInfo.NO_LEVEL + ");"; |
| } |
| if (!isBundleFragment && unconfigInfo.isMarkedAsStarted()) { |
| unconfigScript += "markStarted(started: false);"; |
| } |
| |
| if (unconfigInfo.getSpecialUnconfigCommands() != null) { |
| unconfigScript += unconfigInfo.getSpecialUnconfigCommands(); |
| } |
| return unconfigScript; |
| |
| } |
| |
| 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]; |
| } |
| |
| 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 |
| } |
| } |
| |
| 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 String getTransformedId(String original, boolean isPlugin) { |
| return isPlugin ? original : original + ".featureIU"; |
| } |
| |
| 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 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 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; |
| } |
| |
| 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(); |
| } |
| } |