Bug 331260 - Implement an extensible translation service
diff --git a/bundles/org.eclipse.e4.core.services/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.core.services/META-INF/MANIFEST.MF index 484f3ca..ceab5d2 100644 --- a/bundles/org.eclipse.e4.core.services/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.e4.core.services/META-INF/MANIFEST.MF
@@ -49,4 +49,4 @@ Eclipse-ExtensibleAPI: true Bundle-ClassPath: injection_annotations.jar, . Bundle-Activator: org.eclipse.e4.core.internal.services.ServicesActivator -Service-Component: OSGI-INF/translationService.xml +Service-Component: OSGI-INF/translationService.xml, OSGI-INF/messagefactory.xml
diff --git a/bundles/org.eclipse.e4.core.services/OSGI-INF/messagefactory.xml b/bundles/org.eclipse.e4.core.services/OSGI-INF/messagefactory.xml new file mode 100644 index 0000000..e9dd9fd --- /dev/null +++ b/bundles/org.eclipse.e4.core.services/OSGI-INF/messagefactory.xml
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.core.services.messagefactory"> + <implementation class="org.eclipse.e4.core.internal.services.MessageFactoryServiceImpl"/> + <service> + <provide interface="org.eclipse.e4.core.services.translation.IMessageFactoryService"/> + </service> +</scr:component>
diff --git a/bundles/org.eclipse.e4.core.services/build.properties b/bundles/org.eclipse.e4.core.services/build.properties index 64ceec5..3221b82 100644 --- a/bundles/org.eclipse.e4.core.services/build.properties +++ b/bundles/org.eclipse.e4.core.services/build.properties
@@ -5,6 +5,7 @@ .options,\ about.html,\ plugin.properties,\ - OSGI-INF/ + OSGI-INF/,\ + OSGI-INF/messagefactory.xml src.includes = schema/ source.. = src/
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/MessageFactory.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/internal/services/MessageFactoryServiceImpl.java similarity index 77% rename from bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/MessageFactory.java rename to bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/internal/services/MessageFactoryServiceImpl.java index 8799820..100f9e6 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/MessageFactory.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/internal/services/MessageFactoryServiceImpl.java
@@ -8,7 +8,7 @@ * Contributors: * Tom Schind<tom.schindl@bestsolution.at> - initial API and implementation ******************************************************************************/ -package org.eclipse.e4.core.services.translation; +package org.eclipse.e4.core.internal.services; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -18,25 +18,31 @@ import java.security.PrivilegedAction; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; +import org.eclipse.e4.core.services.translation.IMessageFactoryService; +import org.eclipse.e4.core.services.translation.ITranslationService; +import org.eclipse.e4.core.services.translation.Message; import org.eclipse.e4.core.services.translation.Message.ReferenceType; +import org.eclipse.e4.core.services.translation.PropertiesBundleTranslationProvider; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; -public class MessageFactory { - // TODO Clean up maps +public class MessageFactoryServiceImpl implements IMessageFactoryService { // Cache so when multiple instance use the same message class - private static Map<Object, Reference<Object>> SOFT_CACHE = Collections + private Map<Object, Reference<Object>> SOFT_CACHE = Collections .synchronizedMap(new HashMap<Object, Reference<Object>>()); - private static Map<Object, Reference<Object>> WEAK_CACHE = Collections + private Map<Object, Reference<Object>> WEAK_CACHE = Collections .synchronizedMap(new HashMap<Object, Reference<Object>>()); - @SuppressWarnings("unchecked") - public static <M> M createInstance(final String locale, final Class<M> messages) + private int CLEANUPCOUNT = 0; + + public <M> M createInstance(final String locale, final Class<M> messages) throws InstantiationException, IllegalAccessException { String key = messages.getName() + "_" + locale; @@ -44,6 +50,23 @@ Map<Object, Reference<Object>> cache = null; ReferenceType type = ReferenceType.NONE; + if (++CLEANUPCOUNT > 1000) { + Iterator<Entry<Object, Reference<Object>>> it = WEAK_CACHE.entrySet().iterator(); + while (it.hasNext()) { + if (it.next().getValue().get() == null) { + it.remove(); + } + } + + it = SOFT_CACHE.entrySet().iterator(); + while (it.hasNext()) { + if (it.next().getValue().get() == null) { + it.remove(); + } + } + CLEANUPCOUNT = 0; + } + if (annotation == null || annotation.referenceType() == ReferenceType.SOFT) { cache = SOFT_CACHE; type = ReferenceType.SOFT; @@ -53,6 +76,7 @@ } if (cache != null && cache.containsKey(key)) { + @SuppressWarnings("unchecked") Reference<M> ref = (Reference<M>) cache.get(key); M o = ref.get(); if (o != null) { @@ -97,7 +121,7 @@ throws InstantiationException, IllegalAccessException { if (annotation != null && !annotation.providerId().equals("")) { - Bundle b = FrameworkUtil.getBundle(MessageFactory.class); + Bundle b = FrameworkUtil.getBundle(MessageFactoryServiceImpl.class); BundleContext ctx = b.getBundleContext(); ServiceReference<ITranslationService> reference = ctx .getServiceReference(ITranslationService.class);
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/IMessageFactoryService.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/IMessageFactoryService.java new file mode 100644 index 0000000..3054e8a --- /dev/null +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/translation/IMessageFactoryService.java
@@ -0,0 +1,6 @@ +package org.eclipse.e4.core.services.translation; + +public interface IMessageFactoryService { + public <M> M createInstance(final String locale, final Class<M> messages) + throws InstantiationException, IllegalAccessException; +}