Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Stevenson2008-02-29 04:36:50 +0000
committerDave Stevenson2008-02-29 04:36:50 +0000
commit51a2bfa8b583635605d25876d36bd0cb32514ff0 (patch)
tree1c8be86c46d93be2fb97b8f5ef1467e44d203e5b /bundles
parenteaeff13c27c437032c4df30fa14e165a9757899a (diff)
downloadrt.equinox.p2-51a2bfa8b583635605d25876d36bd0cb32514ff0.tar.gz
rt.equinox.p2-51a2bfa8b583635605d25876d36bd0cb32514ff0.tar.xz
rt.equinox.p2-51a2bfa8b583635605d25876d36bd0cb32514ff0.zip
Implementation of fragments for localization of bundle manifests.
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java15
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/BundleDescriptionFactory.java236
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java96
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java399
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/directorywatcher/RepositoryListenerTest.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/IUGeneralInfoPropertyPage.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/query/IUPropertyUtils.java71
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java6
8 files changed, 737 insertions, 100 deletions
diff --git a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java
index 1ae0db781..ce64b6f49 100644
--- a/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java
+++ b/bundles/org.eclipse.equinox.p2.directorywatcher/src/org/eclipse/equinox/internal/provisional/p2/directorywatcher/RepositoryListener.java
@@ -306,9 +306,12 @@ public class RepositoryListener extends DirectoryChangeListener {
if (featureIUs != null)
ius.addAll(Arrays.asList(featureIUs));
} else {
- IInstallableUnit bundleIU = generateBundleIU(candidate, props);
- if (bundleIU != null)
- ius.add(bundleIU);
+ IInstallableUnit[] bundleIUs = generateBundleIU(candidate, props);
+ if (bundleIUs != null) {
+ for (int i = 0; i < bundleIUs.length; i++) {
+ ius.add(bundleIUs[i]);
+ }
+ }
}
}
return (IInstallableUnit[]) ius.toArray(new IInstallableUnit[ius.size()]);
@@ -328,15 +331,15 @@ public class RepositoryListener extends DirectoryChangeListener {
return new IInstallableUnit[] {featureIU, groupIU};
}
- private IInstallableUnit generateBundleIU(File bundleFile, Properties props) {
+ private IInstallableUnit[] generateBundleIU(File bundleFile, Properties props) {
BundleDescription bundleDescription = bundleDescriptionFactory.getBundleDescription(bundleFile);
if (bundleDescription == null)
return null;
IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(bundleDescription.getSymbolicName(), bundleDescription.getVersion().toString());
- IInstallableUnit iu = MetadataGeneratorHelper.createEclipseIU(bundleDescription, (Map) bundleDescription.getUserObject(), false, key, props);
- return iu;
+ IInstallableUnit[] ius = MetadataGeneratorHelper.createEclipseIU(bundleDescription, (Map) bundleDescription.getUserObject(), false, key, props);
+ return ius;
}
public IMetadataRepository getMetadataRepository() {
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/BundleDescriptionFactory.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/BundleDescriptionFactory.java
index 582167579..33c4c5c92 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/BundleDescriptionFactory.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/BundleDescriptionFactory.java
@@ -11,8 +11,6 @@
package org.eclipse.equinox.internal.provisional.p2.metadata.generator;
import java.io.*;
-import java.net.URL;
-import java.net.URLConnection;
import java.util.*;
import java.util.jar.*;
import java.util.zip.ZipEntry;
@@ -27,7 +25,6 @@ import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
public class BundleDescriptionFactory {
static final String DIR = "dir"; //$NON-NLS-1$
@@ -38,6 +35,13 @@ public class BundleDescriptionFactory {
static String BUNDLE_FILE_KEY = "eclipse.p2.bundle.format"; //$NON-NLS-1$
+ // static final String DEFAULT_BUNDLE_LOCALIZATION = "plugin"; //$NON-NLS-1$
+ // static final String PROPERTIES_FILE_EXTENSION = ".properties"; //$NON-NLS-1$
+ // static final String MANIFEST_LOCALIZATIONS = "eclipse.p2.manifest.localizations"; //$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$
+
StateObjectFactory factory;
State state;
@@ -151,60 +155,190 @@ public class BundleDescriptionFactory {
return null;
manifest.put(BUNDLE_FILE_KEY, bundleLocation.isDirectory() ? DIR : JAR);
- localizeManifest(manifest, bundleLocation);
+ getManifestLocalizations(manifest, bundleLocation);
+ // localizeManifest(manifest, bundleLocation);
return manifest;
}
- private Properties loadProperties(File bundleLocation, String localizationFile) throws IOException {
- Properties result = new Properties();
- InputStream propertyStream = null;
- try {
- try {
- if (bundleLocation.isDirectory())
- propertyStream = new FileInputStream(new File(bundleLocation, localizationFile));
- else {
- URLConnection connection = new URL("jar:" + bundleLocation.toURL().toExternalForm() + "!/" + localizationFile).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;
- }
+ // private Properties loadProperties(File bundleLocation, String localizationFile) throws IOException {
+ // Properties result = new Properties();
+ // InputStream propertyStream = null;
+ // try {
+ // try {
+ // if (bundleLocation.isDirectory())
+ // propertyStream = new FileInputStream(new File(bundleLocation, localizationFile));
+ // else {
+ // URLConnection connection = new URL("jar:" + bundleLocation.toURL().toExternalForm() + "!/" + localizationFile).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;
+ // }
- // TODO this is a temporary hack to eagerly bind the translations (i.e., english) strings
- // into the manifest values. Eventualy we should stop doing this and have a real NL story for
- // metadata.
- private void localizeManifest(Dictionary manifest, File bundleLocation) {
- String localizationFile = (String) manifest.get(Constants.BUNDLE_LOCALIZATION);
- if (localizationFile == null)
- localizationFile = "plugin"; //$NON-NLS-1$
- localizationFile += ".properties"; //$NON-NLS-1$
- try {
- Properties strings = loadProperties(bundleLocation, localizationFile);
- // Walk over the manifest and try to replace all %xxx with the string value in the properties file
- for (Enumeration e = manifest.keys(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- String value = (String) manifest.get(key);
- if (value.startsWith("%")) { //$NON-NLS-1$
- String newValue = strings.getProperty(value.substring(1));
- if (newValue != null)
- manifest.put(key, newValue);
- }
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ // Collect the manifest localizations from the bundle directory
+ // and store them in the manifest.
+ private void getManifestLocalizations(Dictionary manifest, File bundleLocation) {
+ // Map localizations;
+ // Locale defaultLocale = null; // = Locale.ENGLISH; // TODO: get this from GeneratorInfo
+ // String bundleLocalization = (String) manifest.get(Constants.BUNDLE_LOCALIZATION);
+ // if (bundleLocalization == null || bundleLocalization.trim().length() == 0)
+ // bundleLocalization = DEFAULT_BUNDLE_LOCALIZATION;
+ //
+ // if ("jar".equalsIgnoreCase(new Path(bundleLocation.getName()).getFileExtension()) && //$NON-NLS-1$
+ // bundleLocation.isFile()) {
+ // localizations = getJarManifestLocalization(bundleLocation, bundleLocalization, manifest, defaultLocale);
+ // } else {
+ // localizations = getDirManifestLocalization(bundleLocation, bundleLocalization, manifest, defaultLocale);
+ // }
+ //
+ // if (localizations.size() > 0) {
+ // manifest.put(MANIFEST_LOCALIZATIONS, localizations);
+ // }
}
+ // private Map getJarManifestLocalization(File bundleLocation, String bundleLocalization, Dictionary manifest, Locale defaultLocale) {
+ // ZipFile jarFile = null;
+ // Map localizations = new HashMap(4);
+ // try {
+ // jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
+ // for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) {
+ // ZipEntry nextEntry = (ZipEntry) entries.nextElement();
+ // String nextName = nextEntry.getName();
+ // String localeString = getLocaleString(nextName, bundleLocalization);
+ //
+ // if (!nextEntry.isDirectory() && localeString != null) {
+ // Locale nextLocale = getLocale(localeString);
+ // InputStream stream = null;
+ // try {
+ // stream = jarFile.getInputStream(nextEntry);
+ // Properties properties = new Properties();
+ // properties.load(stream);
+ // Properties localizedStrings = getLocalizedProperties(manifest, 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;
+ // }
+ //
+ // private Map getDirManifestLocalization(File bundleLocation, String bundleLocalization, Dictionary manifest, Locale defaultLocale) {
+ // File localizationPath = new File(bundleLocation, bundleLocalization);
+ // File localizationDir = localizationPath.getParentFile();
+ // String localizationFile = localizationPath.getName();
+ // String[] localizationFiles = localizationDir.list(new LocalizationFileFilter(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(getLocaleString(nextFile, localizationFile));
+ //
+ // try {
+ // Properties properties = loadProperties(bundleLocation, nextFile);
+ // Properties localizedStrings = getLocalizedProperties(manifest, 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;
+ // }
+
+ // private class LocalizationFileFilter implements FilenameFilter {
+ //
+ // String filenamePrefix;
+ //
+ // public LocalizationFileFilter(String filenamePrefix) {
+ // this.filenamePrefix = filenamePrefix;
+ // }
+ //
+ // /* (non-Javadoc)
+ // * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
+ // */
+ // public boolean accept(File directory, String filename) {
+ // return (getLocaleString(filename, filenamePrefix) != null ? true : false);
+ // }
+ // }
+
+ // 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;
+ // }
+
+ // static private 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;
+ // }
+ //
+ // static private Properties getLocalizedProperties(Dictionary manifest, Properties properties) {
+ // // Walk over the manifest and find all %xxx with the string value
+ // // in the properties file and copy them to the localized properties.
+ // Properties localizedProperties = new Properties();
+ // for (Enumeration e = manifest.keys(); e.hasMoreElements();) {
+ // String key = (String) e.nextElement();
+ // Object value = manifest.get(key);
+ // if (value instanceof String) {
+ // String stringValue = (String) value;
+ // if (stringValue.startsWith("%")) { //$NON-NLS-1$
+ // String newValue = properties.getProperty(stringValue.substring(1));
+ // if (newValue != null)
+ // localizedProperties.put(key, newValue);
+ // }
+ // }
+ // }
+ // return localizedProperties;
+ // }
+
private Properties manifestToProperties(Attributes attributes) {
Properties result = new Properties();
for (Iterator i = attributes.keySet().iterator(); i.hasNext();) {
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
index ad5ec421c..dfb49fbbd 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/Generator.java
@@ -93,6 +93,8 @@ public class Generator {
private static final String ORG_ECLIPSE_UPDATE_CONFIGURATOR = "org.eclipse.update.configurator"; //$NON-NLS-1$
private static final String ORG_ECLIPSE_EQUINOX_LAUNCHER = "org.eclipse.equinox.launcher"; //$NON-NLS-1$
+ static final String DEFAULT_BUNDLE_LOCALIZATION = "plugin"; //$NON-NLS-1$
+
private final IGeneratorInfo info;
private GeneratorResult incrementalResult = null;
@@ -305,32 +307,86 @@ public class Generator {
}
protected void generateBundleIUs(BundleDescription[] bundles, GeneratorResult result, IArtifactRepository destination) {
- for (int i = 0; i < bundles.length; i++) {
- BundleDescription bd = bundles[i];
- // A bundle may be null if the associated plug-in does not have a manifest file -
- // for example, org.eclipse.jdt.launching.j9
- if (bd != null && bd.getSymbolicName() != null && bd.getVersion() != null) {
- String format = (String) ((Dictionary) bd.getUserObject()).get(BundleDescriptionFactory.BUNDLE_FILE_KEY);
- boolean isDir = format.equals(BundleDescriptionFactory.DIR) ? true : false;
- IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(bd.getSymbolicName(), bd.getVersion().toString());
- IArtifactDescriptor ad = MetadataGeneratorHelper.createArtifactDescriptor(key, new File(bd.getLocation()), true, false);
- if (isDir)
- publishArtifact(ad, new File(bd.getLocation()).listFiles(), destination, false);
- else
- publishArtifact(ad, new File[] {new File(bd.getLocation())}, destination, true);
- if (info.reuseExistingPack200Files() && !info.publishArtifacts()) {
- File packFile = new Path(bd.getLocation()).addFileExtension("pack.gz").toFile(); //$NON-NLS-1$
- if (packFile.exists()) {
- IArtifactDescriptor ad200 = MetadataGeneratorHelper.createPack200ArtifactDescriptor(key, packFile, ad.getProperty(IArtifactDescriptor.ARTIFACT_SIZE));
- publishArtifact(ad200, new File[] {packFile}, destination, true);
+ // Computing the path for localized property files in a NL fragment bundle
+ // requires the BUNDLE_LOCALIZATION property from the manifest of the host bundle,
+ // so a first pass is done over all the bundles to cache this value as well as the tags
+ // from the manifest for the localizable properties.
+ final int CACHE_PHASE = 0;
+ final int GENERATE_PHASE = 1;
+ final int BUNDLE_LOCALIZATION_INDEX = MetadataGeneratorHelper.BUNDLE_LOCALIZATION_INDEX;
+ Map bundleLocalizationMap = new HashMap(bundles.length);
+ Set localizationIUs = new HashSet(32);
+ for (int phase = CACHE_PHASE; phase <= GENERATE_PHASE; phase++) {
+ for (int i = 0; i < bundles.length; i++) {
+ BundleDescription bd = bundles[i];
+ // A bundle may be null if the associated plug-in does not have a manifest file -
+ // for example, org.eclipse.jdt.launching.j9
+ if (bd != null && bd.getSymbolicName() != null && bd.getVersion() != null) {
+ Map bundleManifest = (Map) bd.getUserObject();
+
+ if (phase == CACHE_PHASE) {
+ if (bundleManifest != null) {
+ String[] cachedValues = MetadataGeneratorHelper.getManifestCachedValues(bundleManifest);
+ bundleLocalizationMap.put(makeSimpleKey(bd), cachedValues);
+ }
+ } else {
+ String format = (String) (bundleManifest).get(BundleDescriptionFactory.BUNDLE_FILE_KEY);
+ boolean isDir = (format != null && format.equals(BundleDescriptionFactory.DIR) ? true : false);
+
+ IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(bd.getSymbolicName(), bd.getVersion().toString());
+ IArtifactDescriptor ad = MetadataGeneratorHelper.createArtifactDescriptor(key, new File(bd.getLocation()), true, false);
+ if (isDir)
+ publishArtifact(ad, new File(bd.getLocation()).listFiles(), destination, false);
+ else
+ publishArtifact(ad, new File[] {new File(bd.getLocation())}, destination, true);
+ if (info.reuseExistingPack200Files() && !info.publishArtifacts()) {
+ File packFile = new Path(bd.getLocation()).addFileExtension("pack.gz").toFile(); //$NON-NLS-1$
+ if (packFile.exists()) {
+ IArtifactDescriptor ad200 = MetadataGeneratorHelper.createPack200ArtifactDescriptor(key, packFile, ad.getProperty(IArtifactDescriptor.ARTIFACT_SIZE));
+ publishArtifact(ad200, new File[] {packFile}, destination, true);
+ }
+ }
+
+ IInstallableUnit bundleIU = MetadataGeneratorHelper.createBundleIU(bd, bundleManifest, isDir, key, localizationIUs);
+
+ if (isFragment(bd)) {
+ // TODO: Can NL fragments be multi-host? What special handling
+ // is required for multi-host fragments in general?
+ String hostId = bd.getHost().getName();
+ String hostKey = makeSimpleKey(hostId);
+ String[] cachedValues = (String[]) bundleLocalizationMap.get(hostKey);
+
+ if (cachedValues != null) {
+ MetadataGeneratorHelper.createHostLocalizationFragments(bd, hostId, cachedValues, localizationIUs);
+ }
+ }
+
+ result.rootIUs.add(bundleIU);
+ result.nonRootIUs.addAll(localizationIUs);
+ localizationIUs.clear();
}
}
- IInstallableUnit iu = MetadataGeneratorHelper.createBundleIU(bd, (Map) bd.getUserObject(), isDir, key);
- result.rootIUs.add(iu);
}
}
}
+ private static boolean isFragment(BundleDescription bd) {
+ return (bd.getHost() != null ? true : false);
+ }
+
+ private static String makeSimpleKey(BundleDescription bd) {
+ // TODO: can't use the bundle version in the key for the BundleLocalization
+ // property map since the host specification for a fragment has a
+ // version range, not a version. Hence, this mechanism for finding
+ // manifest localization property files may break under changes
+ // to the BundleLocalization property of a bundle.
+ return makeSimpleKey(bd.getSymbolicName() /*, bd.getVersion() */);
+ }
+
+ private static String makeSimpleKey(String id /*, Version version */) {
+ return id; // + '_' + version.toString();
+ }
+
/**
* Generates IUs corresponding to update site categories.
* @param categoriesToFeatures Map of SiteCategory ->Set (Feature IUs in that category).
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
index 247806f79..53b7d9a69 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
@@ -12,7 +12,12 @@
package org.eclipse.equinox.internal.provisional.p2.metadata.generator;
import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
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;
@@ -57,6 +62,17 @@ public class MetadataGeneratorHelper {
*/
public static final String TYPE_ECLIPSE_SOURCE = "source"; //$NON-NLS-1$
+ /**
+ * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace
+ * representing localized manifest properties
+ * @see RequiredCapability#getName()
+ */
+ public static final String TYPE_ECLIPSE_MANIFEST_LOCALIZATION = "manifest.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};
private static final String CAPABILITY_NS_JAVA_PACKAGE = "java.package"; //$NON-NLS-1$
@@ -90,6 +106,14 @@ public class MetadataGeneratorHelper {
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));
+ public static final ProvidedCapability MANIFEST_LOCALIZATION_CAPABILITY = MetadataFactory.createProvidedCapability(NAMESPACE_ECLIPSE_TYPE, TYPE_ECLIPSE_MANIFEST_LOCALIZATION, 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 MANIFEST_LOCALIZATIONS = "eclipse.p2.manifest.localizations"; //$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, boolean asIs, boolean recur) {
//TODO this size calculation is bogus
@@ -149,6 +173,20 @@ public class MetadataGeneratorHelper {
return MetadataFactory.createInstallableUnit(cu);
}
+ public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Set localizationIUs) {
+ IInstallableUnit bundleIU = createBundleIU(bd, manifest, isFolderPlugin, key);
+
+ String bundleLocalization = (String) manifest.get(Constants.BUNDLE_LOCALIZATION);
+ if (bundleLocalization == null) {
+ bundleLocalization = DEFAULT_BUNDLE_LOCALIZATION;
+ }
+ Map manifestLocalizations = getManifestLocalizations(manifest, new File(bd.getLocation()));
+ if (manifestLocalizations != null) {
+ localizationIUs.addAll(createLocalizationFragmentsForBundle(bd, manifestLocalizations));
+ }
+ return bundleIU;
+ }
+
public static IInstallableUnit createBundleIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key) {
boolean isBinaryBundle = true;
if (manifest != null && manifest.containsKey("Eclipse-SourceBundle")) { //$NON-NLS-1$
@@ -175,7 +213,7 @@ public class MetadataGeneratorHelper {
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 package
+ // 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
@@ -191,12 +229,12 @@ public class MetadataGeneratorHelper {
}
iu.setRequiredCapabilities((RequiredCapability[]) reqsDeps.toArray(new RequiredCapability[reqsDeps.size()]));
- // Create Set of provided capabilities
+ // 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
+ // 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
@@ -216,16 +254,16 @@ public class MetadataGeneratorHelper {
iu.setTouchpointType(TOUCHPOINT_OSGI);
- // 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.
+ // 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) {
+ if (value != null && value.length() > 0) {
iu.setProperty(BUNDLE_IU_PROPERTY_MAP[i + 1], value);
}
}
@@ -240,9 +278,110 @@ public class MetadataGeneratorHelper {
touchpointData.put("zipped", "true"); //$NON-NLS-1$ //$NON-NLS-2$
touchpointData.put("manifest", toManifestString(manifest)); //$NON-NLS-1$
iu.addTouchpointData(MetadataFactory.createTouchpointData(touchpointData));
+
return MetadataFactory.createInstallableUnit(iu);
}
+ private static List createLocalizationFragmentsForBundle(BundleDescription bd, Map manifestLocalizations) {
+ List localizationFragments = new ArrayList(manifestLocalizations.size());
+ for (Iterator iter = manifestLocalizations.keySet().iterator(); iter.hasNext();) {
+ Locale locale = (Locale) iter.next();
+ Properties localizedStrings = (Properties) manifestLocalizations.get(locale);
+ IInstallableUnitFragment nextLocaleFragment = createLocalizationFragmentOfBundle(bd, locale, localizedStrings);
+ localizationFragments.add(nextLocaleFragment);
+ }
+ return localizationFragments;
+ }
+
+ /*
+ * @param bd
+ * @param locale
+ * @param localizedStrings
+ * @return installableUnitFragment
+ */
+ private static IInstallableUnitFragment createLocalizationFragmentOfBundle(BundleDescription bd, Locale locale, Properties localizedStrings) {
+ InstallableUnitFragmentDescription fragment = new MetadataFactory.InstallableUnitFragmentDescription();
+ String fragmentId = makeLocalizationFragmentId(bd.getSymbolicName(), locale);
+ fragment.setId(fragmentId);
+ fragment.setVersion(bd.getVersion());
+
+ RequiredCapability[] hostReqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, bd.getSymbolicName(), new VersionRange(bd.getVersion(), true, bd.getVersion(), true), null, false, false)};
+ fragment.setHost(hostReqs);
+
+ fragment.setSingleton(true);
+
+ Enumeration propertyKeys = localizedStrings.propertyNames();
+ while (propertyKeys.hasMoreElements()) {
+ String nextKey = (String) propertyKeys.nextElement();
+ fragment.setProperty(nextKey, localizedStrings.getProperty(nextKey));
+ }
+ // TODO: do we need any capabilities?
+ // Create set of provided capabilities It's just a tag indicating a localization fragment.
+ ArrayList providedCapabilities = new ArrayList(1);
+ providedCapabilities.add(MANIFEST_LOCALIZATION_CAPABILITY);
+ fragment.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()]));
+
+ return MetadataFactory.createInstallableUnitFragment(fragment);
+ }
+
+ public static void createHostLocalizationFragments(BundleDescription bd, String hostId, String[] hostBundleManifestValues, Set localizationIUs) {
+ Map hostLocalizations = getHostLocalizations(new File(bd.getLocation()), hostBundleManifestValues);
+
+ for (Iterator iter = hostLocalizations.keySet().iterator(); iter.hasNext();) {
+ Locale locale = (Locale) iter.next();
+ Properties localizedStrings = (Properties) hostLocalizations.get(locale);
+ IInstallableUnitFragment nextLocaleFragment = createLocalizationFragmentOfHost(hostId, hostBundleManifestValues, bd, locale, localizedStrings);
+ localizationIUs.add(nextLocaleFragment);
+ }
+ }
+
+ /*
+ * @param hostId
+ * @param bd
+ * @param locale
+ * @param localizedStrings
+ * @return installableUnitFragment
+ */
+ private static IInstallableUnitFragment createLocalizationFragmentOfHost(String hostId, String[] hostManifestValues, BundleDescription bd, Locale locale, Properties localizedStrings) {
+ InstallableUnitFragmentDescription fragment = new MetadataFactory.InstallableUnitFragmentDescription();
+ HostSpecification hostSpec = bd.getHost();
+ String fragmentId = makeLocalizationFragmentId(hostId, locale);
+ fragment.setId(fragmentId);
+ fragment.setVersion(bd.getVersion()); // TODO: is this a meaningful version?
+
+ RequiredCapability[] hostReqs = new RequiredCapability[] {MetadataFactory.createRequiredCapability(NAMESPACE_ECLIPSE_TYPE, hostSpec.getName(), hostSpec.getVersionRange(), null, false, false)};
+ fragment.setHost(hostReqs);
+
+ fragment.setSingleton(true);
+
+ for (int i = 0; i < BUNDLE_LOCALIZED_PROPERTIES.length; i++) {
+ String nextKey = hostManifestValues[i];
+ String localizedValue = null;
+ if (nextKey != null && (localizedValue = localizedStrings.getProperty(nextKey)) != null) {
+ fragment.setProperty(nextKey, localizedValue);
+ }
+ }
+ // TODO: do we need any capabilities? It's just a tag indicating a localization fragment.
+ // Create set of provided capabilities
+ ArrayList providedCapabilities = new ArrayList(1);
+ providedCapabilities.add(MANIFEST_LOCALIZATION_CAPABILITY);
+ fragment.setCapabilities((ProvidedCapability[]) providedCapabilities.toArray(new ProvidedCapability[providedCapabilities.size()]));
+
+ return MetadataFactory.createInstallableUnitFragment(fragment);
+ }
+
+ /**
+ * @param id
+ * @param locale
+ * @return the id for the fragment contain the localized properties
+ * for the manifest of the bundle with the given id
+ * in the given locale.
+ */
+ private static String makeLocalizationFragmentId(String id, Locale locale) {
+ String localeString = (!DEFAULT_LOCALE.equals(locale) ? '_' + locale.toString() : ""); //$NON-NLS-1$
+ return id + "_manifest" + localeString + "_properties"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
/**
* Creates an IU corresponding to an update site category
* @param category The category descriptor
@@ -377,16 +516,41 @@ public class MetadataGeneratorHelper {
return MetadataFactory.createInstallableUnit(cu);
}
- // TODO: TEMPORARY - We should figure out if we want to expose something like InstallableUnitDescription
- public static IInstallableUnit createEclipseIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Properties extraProperties) {
- InstallableUnit iu = (InstallableUnit) createBundleIU(bd, manifest, isFolderPlugin, key);
+ private static void addExtraProperties(IInstallableUnit iiu, Properties extraProperties) {
+ if (iiu instanceof InstallableUnit) {
+ InstallableUnit iu = (InstallableUnit) iiu;
- Enumeration e = extraProperties.propertyNames();
- while (e.hasMoreElements()) {
- String name = (String) e.nextElement();
- iu.setProperty(name, extraProperties.getProperty(name));
+ for (Enumeration e = extraProperties.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ iu.setProperty(name, extraProperties.getProperty(name));
+ }
}
- return iu;
+ }
+
+ public static IInstallableUnit[] createEclipseIU(BundleDescription bd, Map manifest, boolean isFolderPlugin, IArtifactKey key, Properties extraProperties) {
+ ArrayList iusCreated = new ArrayList(4);
+
+ IInstallableUnit iu = createBundleIU(bd, manifest, isFolderPlugin, key);
+ addExtraProperties(iu, extraProperties);
+ iusCreated.add(iu);
+
+ String bundleLocalization = null;
+ if (bd.getHost() == null) // not a fragment
+ bundleLocalization = (String) manifest.get(Constants.BUNDLE_LOCALIZATION);
+ if (bundleLocalization == null)
+ bundleLocalization = DEFAULT_BUNDLE_LOCALIZATION;
+
+ Map manifestLocalizations = getManifestLocalizations(manifest, new File(bd.getLocation()));
+
+ if (manifestLocalizations != null) {
+ List localizationFragments = createLocalizationFragmentsForBundle(bd, manifestLocalizations);
+ for (Iterator iter = localizationFragments.iterator(); iter.hasNext();) {
+ addExtraProperties((IInstallableUnit) iter.next(), extraProperties);
+ }
+ iusCreated.addAll(localizationFragments);
+ }
+
+ return (IInstallableUnit[]) (iusCreated.toArray(new IInstallableUnit[iusCreated.size()]));
}
public static IArtifactKey createFeatureArtifactKey(String fsn, String version) {
@@ -777,4 +941,207 @@ public class MetadataGeneratorHelper {
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.
+ 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 = getJarManifestLocalization(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues);
+ } else {
+ localizations = getDirManifestLocalization(bundleLocation, bundleLocalization, defaultLocale, bundleManifestValues);
+ }
+
+ return localizations;
+ }
+
+ public static String[] getManifestCachedValues(Map manifest) {
+ String[] cachedValues = new String[BUNDLE_LOCALIZED_PROPERTIES.length + 1];
+ for (int j = 0; j < MetadataGeneratorHelper.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.
+ 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 = getJarManifestLocalization(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues);
+ } else {
+ localizations = getDirManifestLocalization(bundleLocation, hostBundleLocalization, defaultLocale, hostBundleManifestValues);
+ }
+
+ return localizations;
+ }
+
+ private static Map getJarManifestLocalization(File bundleLocation, String bundleLocalization, Locale defaultLocale, String[] bundleManifestValues) {
+ ZipFile jarFile = null;
+ Map localizations = new HashMap(4);
+ try {
+ jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ);
+ for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) {
+ ZipEntry nextEntry = (ZipEntry) entries.nextElement();
+ String nextName = nextEntry.getName();
+ String localeString = getLocaleString(nextName, bundleLocalization);
+
+ if (!nextEntry.isDirectory() && localeString != null) {
+ Locale nextLocale = getLocale(localeString);
+ InputStream stream = null;
+ try {
+ stream = jarFile.getInputStream(nextEntry);
+ Properties properties = new Properties();
+ properties.load(stream);
+ Properties localizedStrings = getLocalizedProperties(bundleManifestValues, 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;
+ }
+
+ private static Map getDirManifestLocalization(File bundleLocation, String bundleLocalization, Locale defaultLocale, String[] hostBundleManifestValues) {
+ File localizationPath = new File(bundleLocation, bundleLocalization);
+ File localizationDir = localizationPath.getParentFile();
+ final String localizationFile = localizationPath.getName();
+ MetadataGeneratorHelper foo = new MetadataGeneratorHelper();
+ String[] localizationFiles = localizationDir.list(foo.new LocalizationFileFilter() {
+ public boolean accept(File directory, String filename) {
+ return (getLocaleString(filename, localizationFile) != null ? true : false);
+ }
+ });
+
+ 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(getLocaleString(nextFile, localizationFile));
+
+ try {
+ Properties properties = loadProperties(bundleLocation, nextFile);
+ Properties localizedStrings = getLocalizedProperties(hostBundleManifestValues, 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;
+ }
+
+ private abstract class LocalizationFileFilter implements FilenameFilter {
+
+ public LocalizationFileFilter() {
+ // Nothing to do
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
+ */
+ public abstract boolean accept(File directory, String filename);
+ }
+
+ 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;
+ }
+
+ private static Properties loadProperties(File bundleLocation, String localizationFile) throws IOException {
+ Properties result = new Properties();
+ InputStream propertyStream = null;
+ try {
+ try {
+ if (bundleLocation.isDirectory())
+ propertyStream = new FileInputStream(new File(bundleLocation, localizationFile));
+ else {
+ URLConnection connection = new URL("jar:" + bundleLocation.toURL().toExternalForm() + "!/" + localizationFile).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;
+ }
+
+ static private 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;
+ }
+
+ static private Properties getLocalizedProperties(String[] bundleManifestKeys, Properties properties) {
+ Properties localizedProperties = new Properties();
+ for (int i = 0; i < BUNDLE_LOCALIZED_PROPERTIES.length; i++) {
+ String key = bundleManifestKeys[i];
+ if (key != null) {
+ String localizedValue = properties.getProperty(key);
+ if (localizedValue != null)
+ localizedProperties.put(key, localizedValue);
+ }
+ }
+ return localizedProperties;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/directorywatcher/RepositoryListenerTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/directorywatcher/RepositoryListenerTest.java
index a3a692010..e7c36ac55 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/directorywatcher/RepositoryListenerTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/directorywatcher/RepositoryListenerTest.java
@@ -95,14 +95,14 @@ public class RepositoryListenerTest extends AbstractProvisioningTest {
assertTrue("2.3", repo.getArtifactFile(keys[i]).toString().startsWith(folder.getAbsolutePath().toString()));
}
- assertEquals("3.0", 2, getInstallableUnits(listener).length);
+ assertEquals("3.0", 4, getInstallableUnits(listener).length);
assertEquals("3.1", 2, listener.getArtifactRepository().getArtifactKeys().length);
watcher = new DirectoryWatcher(props, TestActivator.getContext());
watcher.addListener(listener);
watcher.start();
- assertEquals("4.0", 2, getInstallableUnits(listener).length);
+ assertEquals("4.0", 4, getInstallableUnits(listener).length);
assertEquals("4.1", 2, listener.getArtifactRepository().getArtifactKeys().length);
try {
@@ -112,7 +112,7 @@ public class RepositoryListenerTest extends AbstractProvisioningTest {
}
watcher.poll();
- assertEquals("5.0", 3, getInstallableUnits(listener).length);
+ assertEquals("5.0", 5, getInstallableUnits(listener).length);
assertEquals("5.1", 3, listener.getArtifactRepository().getArtifactKeys().length);
watcher.stop();
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/IUGeneralInfoPropertyPage.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/IUGeneralInfoPropertyPage.java
index c6f85a75d..a323de442 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/IUGeneralInfoPropertyPage.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/IUGeneralInfoPropertyPage.java
@@ -12,9 +12,11 @@ package org.eclipse.equinox.internal.provisional.p2.ui.dialogs;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Locale;
import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
import org.eclipse.equinox.internal.p2.ui.dialogs.IUPropertyPage;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.internal.provisional.p2.ui.query.IUPropertyUtils;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -52,10 +54,12 @@ public class IUGeneralInfoPropertyPage extends IUPropertyPage {
layout.marginHeight = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_NameLabel, iu.getProperty(IInstallableUnit.PROP_NAME));
+ //addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_NameLabel, iu.getProperty(IInstallableUnit.PROP_NAME));
+ addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_NameLabel, IUPropertyUtils.getIUProperty(iu, IInstallableUnit.PROP_NAME, Locale.getDefault()));
addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_IdentifierLabel, iu.getId());
addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_VersionLabel, iu.getVersion().toString());
- addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_ProviderLabel, iu.getProperty(IInstallableUnit.PROP_PROVIDER));
+ //addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_ProviderLabel, iu.getProperty(IInstallableUnit.PROP_PROVIDER));
+ addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_ProviderLabel, IUPropertyUtils.getIUProperty(iu, IInstallableUnit.PROP_PROVIDER, Locale.getDefault()));
addField(composite, ProvUIMessages.IUGeneralInfoPropertyPage_ContactLabel, iu.getProperty(IInstallableUnit.PROP_CONTACT));
}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/query/IUPropertyUtils.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/query/IUPropertyUtils.java
new file mode 100644
index 000000000..3b9b87f17
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/query/IUPropertyUtils.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.internal.provisional.p2.ui.query;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
+import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager;
+import org.eclipse.equinox.internal.provisional.p2.query.Collector;
+
+public class IUPropertyUtils {
+
+ public static String getIUProperty(IInstallableUnit iu, String propertyKey, Locale locale) {
+ String value = iu.getProperty(propertyKey);
+ if (value == null || value.length() <= 1 || value.charAt(0) != '%')
+ return value;
+ // else have a localizable property
+ String actualKey = value.substring(1);
+ String localizationBundles[] = buildLocalizationVariants(iu, locale);
+
+ IMetadataRepositoryManager repoMgr = (IMetadataRepositoryManager) ServiceHelper.getService(ProvUIActivator.getContext(), IMetadataRepositoryManager.class.getName());
+
+ for (int i = 0; i < localizationBundles.length; i++) {
+ InstallableUnitQuery iuQuery = new InstallableUnitQuery(localizationBundles[i]);
+ Collector collected = repoMgr.query(iuQuery, new Collector(), null);
+ if (!collected.isEmpty()) {
+ for (Iterator iter = collected.iterator(); iter.hasNext();) {
+ IInstallableUnit localizationIU = (IInstallableUnit) iter.next();
+ String translation = localizationIU.getProperty(actualKey);
+ if (translation != null)
+ return translation;
+ }
+ }
+ }
+
+ return value;
+ }
+
+ private static final String MANIFEST_NAME = "_manifest"; //$NON-NLS-1$
+ private static final String PROPERTIES_NAME = "_properties"; //$NON-NLS-1$
+
+ /**
+ */
+ private static String[] buildLocalizationVariants(IInstallableUnit iu, Locale locale) {
+ String id = iu.getId().toString();
+ String nl = locale.toString();
+ ArrayList result = new ArrayList(4);
+ int lastSeparator;
+ while (true) {
+ result.add(id + MANIFEST_NAME + '_' + nl + PROPERTIES_NAME);
+ lastSeparator = nl.lastIndexOf('_');
+ if (lastSeparator == -1)
+ break;
+ nl = nl.substring(0, lastSeparator);
+ }
+ //add the empty suffix last (most general)
+ result.add(id + MANIFEST_NAME + PROPERTIES_NAME);
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
index eaee92037..21a44fe52 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
@@ -101,8 +101,10 @@ public class UpdateSiteMetadataRepository extends AbstractRepository implements
mockManifest.put("Bundle-Version", entry.getVersion());
BundleDescription bundleDescription = bundleDesciptionFactory.getBundleDescription(mockManifest, null);
IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(entry.getId(), entry.getVersion());
- IInstallableUnit bundleIU = MetadataGeneratorHelper.createEclipseIU(bundleDescription, null, entry.isUnpack(), key, extraProperties);
- allSiteIUs.add(bundleIU);
+ IInstallableUnit[] bundleIUs = MetadataGeneratorHelper.createEclipseIU(bundleDescription, null, entry.isUnpack(), key, extraProperties);
+ for (int n = 0; n < bundleIUs.length; n++) {
+ allSiteIUs.add(bundleIUs[n]);
+ }
}
}

Back to the top