Bug 550490 - [metatype] avoid reloading the same ResourceBundle multiple
times

Change-Id: I834cc33abe957751ce332ce551ec19c4940e34a6
Signed-off-by: Anjum Fatima <anjum.eclipse@gmail.com>
diff --git a/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
index 1c605cb..7694336 100644
--- a/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.metatype/META-INF/MANIFEST.MF
@@ -1,6 +1,6 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %bundleName
-Bundle-Version: 1.5.100.qualifier
+Bundle-Version: 1.5.200.qualifier
 Bundle-SymbolicName: org.eclipse.equinox.metatype
 Bundle-Activator: org.eclipse.equinox.metatype.impl.Activator
 Import-Package: javax.xml.parsers,
diff --git a/bundles/org.eclipse.equinox.metatype/pom.xml b/bundles/org.eclipse.equinox.metatype/pom.xml
index cc823e9..7afaded 100644
--- a/bundles/org.eclipse.equinox.metatype/pom.xml
+++ b/bundles/org.eclipse.equinox.metatype/pom.xml
@@ -19,7 +19,7 @@
   </parent>
   <groupId>org.eclipse.equinox</groupId>
   <artifactId>org.eclipse.equinox.metatype</artifactId>
-  <version>1.5.100-SNAPSHOT</version>
+  <version>1.5.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
   <build>
     <plugins>
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
index db6a1c9..8ae0dde 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/LocalizationElement.java
@@ -25,11 +25,7 @@
 	/*
 	 * Internal Method - to get resource bundle.
 	 */
-	private static ResourceBundle getResourceBundle(String localization, String locale, Bundle bundle) {
-		// Determine the base name of the bundle localization property files.
-		// If the <MetaData> 'localization' attribute was not specified,
-		// use the Bundle-Localization manifest header value instead if it exists.
-		String resourceBase = localization != null ? localization : MetaTypeProviderImpl.getBundleLocalization(bundle);
+	private static ResourceBundle getResourceBundle(String resourceBase, String locale, Bundle bundle) {
 
 		// There are seven searching candidates possible:
 		// baseName + 
@@ -125,7 +121,7 @@
 	// @GuardedBy("this")
 	private String locale;
 	// @GuardedBy("this")
-	private ResourceBundle resourceBundle;
+	private Map<String, ResourceBundle> resourceBundleCache;
 
 	public LocalizationElement(String localization) {
 		this.localization = localization;
@@ -166,8 +162,20 @@
 	 * If the bundle is not set, an NPE will be generated by getResourceBundle(String, String, Bundle).
 	 */
 	protected synchronized ResourceBundle getResourceBundle() {
+		// Determine the base name of the bundle localization property files.
+		// If the <MetaData> 'localization' attribute was not specified,
+		// use the Bundle-Localization manifest header value instead if it exists.
+		String resourceBase = localization != null ? localization : MetaTypeProviderImpl.getBundleLocalization(bundle);
+		long bundleId = bundle.getBundleId();
+		String key = (locale != null) ? bundleId + ":" + locale + ":" + resourceBase : bundleId + ":" + resourceBase; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		ResourceBundle resourceBundle = resourceBundleCache.get(key);
+
 		if (resourceBundle == null) {
-			resourceBundle = getResourceBundle(localization, locale, bundle);
+			resourceBundle = getResourceBundle(resourceBase, locale, bundle);
+			if (resourceBundle != null) {
+				resourceBundleCache.put(key, resourceBundle);
+			}
 		}
 		return resourceBundle;
 	}
@@ -176,8 +184,9 @@
 	 * This method must be (and currently is) called before getResourceBundle().
 	 * If the bundle is not set, an NPE will be generated by getResourceBundle(String, String, Bundle).
 	 */
-	protected synchronized void setLocaleAndBundle(String locale, Bundle bundle) {
+	protected synchronized void setLocaleAndBundle(String locale, Bundle bundle, Map<String, ResourceBundle> resourceBundleCache) {
 		this.locale = locale;
 		this.bundle = bundle;
+		this.resourceBundleCache = resourceBundleCache;
 	}
 }
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
index fe33eaa..41369a6 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/MetaTypeProviderImpl.java
@@ -16,6 +16,7 @@
 import java.net.URL;
 import java.util.*;
 import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.xml.parsers.SAXParser;
 import org.eclipse.equinox.metatype.EquinoxObjectClassDefinition;
 import org.eclipse.osgi.util.NLS;
@@ -49,6 +50,8 @@
 	// Give access to subclasses.
 	protected final LogTracker logger;
 
+	private final Map<String, ResourceBundle> resourceBundleCache = new ConcurrentHashMap<>();
+
 	/**
 	 * Constructor of class MetaTypeProviderImpl.
 	 */
@@ -137,11 +140,11 @@
 		ObjectClassDefinitionImpl ocd;
 		if (_allPidOCDs.containsKey(pid)) {
 			ocd = (ObjectClassDefinitionImpl) (_allPidOCDs.get(pid)).clone();
-			ocd.setResourceBundle(locale, _bundle);
+			ocd.setResourceBundle(locale, _bundle, resourceBundleCache);
 			return ocd;
 		} else if (_allFPidOCDs.containsKey(pid)) {
 			ocd = (ObjectClassDefinitionImpl) (_allFPidOCDs.get(pid)).clone();
-			ocd.setResourceBundle(locale, _bundle);
+			ocd.setResourceBundle(locale, _bundle, resourceBundleCache);
 			return ocd;
 		} else {
 			throw new IllegalArgumentException(NLS.bind(MetaTypeMsg.OCD_PID_NOT_FOUND, pid));
diff --git a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
index eec2ede..8570c9d 100644
--- a/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
+++ b/bundles/org.eclipse.equinox.metatype/src/org/eclipse/equinox/metatype/impl/ObjectClassDefinitionImpl.java
@@ -219,14 +219,15 @@
 
 	/**
 	 * Method to set the resource bundle for this OCD and all its ADs.
+	 * @param resourceBundleCache 
 	 */
-	void setResourceBundle(String assignedLocale, Bundle bundle) {
-		setLocaleAndBundle(assignedLocale, bundle);
+	void setResourceBundle(String assignedLocale, Bundle bundle, Map<String, ResourceBundle> resourceBundleCache) {
+		setLocaleAndBundle(assignedLocale, bundle, resourceBundleCache);
 		for (AttributeDefinitionImpl ad : _required) {
-			ad.setLocaleAndBundle(assignedLocale, bundle);
+			ad.setLocaleAndBundle(assignedLocale, bundle, resourceBundleCache);
 		}
 		for (AttributeDefinitionImpl ad : _optional) {
-			ad.setLocaleAndBundle(assignedLocale, bundle);
+			ad.setLocaleAndBundle(assignedLocale, bundle, resourceBundleCache);
 		}
 	}