You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2012/08/28 09:00:37 UTC
svn commit: r1377994 - in /sling/trunk/contrib/extensions/i18n: pom.xml
src/main/java/org/apache/sling/i18n/impl/I18NFilter.java
Author: cziegeler
Date: Tue Aug 28 07:00:37 2012
New Revision: 1377994
URL: http://svn.apache.org/viewvc?rev=1377994&view=rev
Log:
SLING-2576 : I18n: Allow multiple ResourceBundleProviders, use the first one responding for a given locale
Modified:
sling/trunk/contrib/extensions/i18n/pom.xml
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java
Modified: sling/trunk/contrib/extensions/i18n/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/pom.xml?rev=1377994&r1=1377993&r2=1377994&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/pom.xml (original)
+++ sling/trunk/contrib/extensions/i18n/pom.xml Tue Aug 28 07:00:37 2012
@@ -70,6 +70,9 @@
SLING-INF/nodetypes/jcrlanguage.cnd,
SLING-INF/nodetypes/message.cnd
</Sling-Nodetypes>
+ <Embed-Dependency>
+ org.apache.sling.commons.osgi;inline="org/apache/sling/commons/osgi/ServiceUtil.*"
+ </Embed-Dependency>
</instructions>
</configuration>
@@ -83,6 +86,12 @@
<version>2.1.0</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.osgi</artifactId>
+ <version>2.1.0</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.apache.sling</groupId>
Modified: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java?rev=1377994&r1=1377993&r2=1377994&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java (original)
+++ sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java Tue Aug 28 07:00:37 2012
@@ -23,8 +23,10 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.util.TreeMap;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -45,6 +47,7 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.sling.SlingFilterScope;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
+import org.apache.sling.commons.osgi.ServiceUtil;
import org.apache.sling.i18n.DefaultLocaleResolver;
import org.apache.sling.i18n.LocaleResolver;
import org.apache.sling.i18n.RequestLocaleResolver;
@@ -58,7 +61,7 @@ import org.slf4j.LoggerFactory;
* the resource bundle for the current request.
*/
@SlingFilter(generateComponent = false, generateService = true, order = -700, scope = SlingFilterScope.REQUEST)
-@Component(immediate = true, metatype = false)
+@Component(immediate = true, metatype = false, specVersion="1.1")
@Properties({
@Property(name = "pattern", value="/.*"),
@Property(name = Constants.SERVICE_DESCRIPTION, value = "Internationalization Support Filter"),
@@ -76,8 +79,15 @@ public class I18NFilter implements Filte
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
private RequestLocaleResolver requestLocaleResolver = DEFAULT_LOCALE_RESOLVER;
- @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
- private ResourceBundleProvider resourceBundleProvider;
+ @Reference(name = "resourceBundleProvider",
+ referenceInterface = ResourceBundleProvider.class,
+ cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
+ policy = ReferencePolicy.DYNAMIC)
+ private final Map<Object, ResourceBundleProvider> providers = new TreeMap<Object, ResourceBundleProvider>();
+
+ private volatile ResourceBundleProvider[] sortedProviders = new ResourceBundleProvider[0];
+
+ private final ResourceBundleProvider combinedProvider = new CombinedBundleProvider();
/** Count the number init() has been called. */
private volatile int initCount;
@@ -104,13 +114,13 @@ public class I18NFilter implements Filte
if ( !runGlobal || this.requestLocaleResolver == DEFAULT_LOCALE_RESOLVER ) {
// wrap with our ResourceBundle provisioning
request = new I18NSlingHttpServletRequest(request,
- resourceBundleProvider, localeResolver);
+ combinedProvider, localeResolver);
} else {
- request = new BaseI18NSlingHttpServletRequest(request, resourceBundleProvider);
+ request = new BaseI18NSlingHttpServletRequest(request, combinedProvider);
}
} else {
request = new I18NHttpServletRequest(request,
- resourceBundleProvider, requestLocaleResolver);
+ combinedProvider, requestLocaleResolver);
}
// and forward the request
@@ -147,8 +157,60 @@ public class I18NFilter implements Filte
this.requestLocaleResolver = DEFAULT_LOCALE_RESOLVER;
}
}
+
+ protected void bindResourceBundleProvider(final ResourceBundleProvider provider, final Map<String, Object> props) {
+ synchronized ( this.providers ) {
+ this.providers.put(ServiceUtil.getComparableForServiceRanking(props), provider);
+ this.sortedProviders = this.providers.values().toArray(new ResourceBundleProvider[this.providers.size()]);
+ }
+ }
+
+ protected void unbindResourceBundleProvider(final ResourceBundleProvider provider, final Map<String, Object> props) {
+ synchronized ( this.providers ) {
+ this.providers.remove(ServiceUtil.getComparableForServiceRanking(props));
+ this.sortedProviders = this.providers.values().toArray(new ResourceBundleProvider[this.providers.size()]);
+ }
+ }
+
// ---------- internal -----------------------------------------------------
+ /** Provider that goes through a list of registered providers and takes the first non-null responses */
+ private class CombinedBundleProvider implements ResourceBundleProvider {
+
+ public Locale getDefaultLocale() {
+ // ask all registered providers, use the first one that returns
+ for (final ResourceBundleProvider provider : sortedProviders) {
+ final Locale locale = provider.getDefaultLocale();
+ if (locale != null) {
+ return locale;
+ }
+ }
+ return null;
+ }
+
+ public ResourceBundle getResourceBundle(final Locale locale) {
+ // ask all registered providers, use the first one that returns
+ for (final ResourceBundleProvider provider : sortedProviders) {
+ final ResourceBundle bundle = provider.getResourceBundle(locale);
+ if (bundle != null) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ public ResourceBundle getResourceBundle(final String baseName, final Locale locale) {
+ // ask all registered providers, use the first one that returns
+ for (final ResourceBundleProvider provider : sortedProviders) {
+ final ResourceBundle bundle = provider.getResourceBundle(baseName, locale);
+ if (bundle != null) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+ }
+
// ---------- internal class -----------------------------------------------
private static class I18NHttpServletRequest