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 2011/08/16 12:47:36 UTC
svn commit: r1158191 - in /sling/trunk/contrib/extensions/i18n: ./
src/main/java/org/apache/sling/i18n/
src/main/java/org/apache/sling/i18n/impl/
Author: cziegeler
Date: Tue Aug 16 10:47:36 2011
New Revision: 1158191
URL: http://svn.apache.org/viewvc?rev=1158191&view=rev
Log:
SLING-2180 : Provide a resource bundle for all requests
Added:
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java (with props)
Modified:
sling/trunk/contrib/extensions/i18n/pom.xml
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/DefaultLocaleResolver.java
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/LocaleResolver.java
sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/ResourceBundleProvider.java
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=1158191&r1=1158190&r2=1158191&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/pom.xml (original)
+++ sling/trunk/contrib/extensions/i18n/pom.xml Tue Aug 16 10:47:36 2011
@@ -60,7 +60,7 @@
javax.jcr.*;version=1.0,*
</Import-Package>
<Export-Package>
- org.apache.sling.i18n;version=2.0.4
+ org.apache.sling.i18n;version=2.2.0
</Export-Package>
<Private-Package>
org.apache.sling.i18n.impl.*
Modified: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/DefaultLocaleResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/DefaultLocaleResolver.java?rev=1158191&r1=1158190&r2=1158191&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/DefaultLocaleResolver.java (original)
+++ sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/DefaultLocaleResolver.java Tue Aug 16 10:47:36 2011
@@ -23,6 +23,8 @@ import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.sling.api.SlingHttpServletRequest;
/**
@@ -31,14 +33,21 @@ import org.apache.sling.api.SlingHttpSer
* will be the Servlet Container's implementation of this method and thus be
* based on the client's <code>Accept-Language</code> header.
*/
-public class DefaultLocaleResolver implements LocaleResolver {
+public class DefaultLocaleResolver implements LocaleResolver, RequestLocaleResolver {
/**
* Return the Locales provided by the
* <code>ServletRequest.getLocales()</code> method collected in a
* <code>List</code>.
*/
- public List<Locale> resolveLocale(SlingHttpServletRequest request) {
+ public List<Locale> resolveLocale(final SlingHttpServletRequest request) {
+ return this.resolveLocale((HttpServletRequest)request);
+ }
+
+ /**
+ * @see org.apache.sling.i18n.RequestLocaleResolver#resolveLocale(javax.servlet.http.HttpServletRequest)
+ */
+ public List<Locale> resolveLocale(final HttpServletRequest request) {
Enumeration<?> locales = request.getLocales();
ArrayList<Locale> localeList = new ArrayList<Locale>();
while (locales.hasMoreElements()) {
@@ -46,5 +55,4 @@ public class DefaultLocaleResolver imple
}
return localeList;
}
-
}
Modified: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/LocaleResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/LocaleResolver.java?rev=1158191&r1=1158190&r2=1158191&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/LocaleResolver.java (original)
+++ sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/LocaleResolver.java Tue Aug 16 10:47:36 2011
@@ -32,7 +32,9 @@ import org.apache.sling.api.SlingHttpSer
* resolve one or more <code>Locale</code>s applicable to handle the request.
* <p>
* Only a single <code>LocaleResolver</code> service is currently used.
+ * @deprecated The {@link RequestLocaleResolver} should be used instead.
*/
+@Deprecated
public interface LocaleResolver {
/**
Added: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java?rev=1158191&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java (added)
+++ sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java Tue Aug 16 10:47:36 2011
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.i18n;
+
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * The <code>GlobalLocaleResolver</code> service interface may be implemented by a
+ * service registered under this name to allow the resolution of the request
+ * <code>Locale</code> to apply.
+ * <p>
+ * This interface is intended to be implemented by providers knowing how to
+ * resolve one or more <code>Locale</code>s applicable to handle the request.
+ * <p>
+ * Only a single <code>GlobalLocaleResolver</code> service is currently used.
+ * @since 2.2
+ */
+public interface RequestLocaleResolver {
+
+ /**
+ * Return a non-<code>null</code> but possiby empty list of
+ * <code>Locale</code> instances to consider for localization of the current
+ * request. The list returned is assumed to be ordered by preference where
+ * the first entry is the prefered <code>Locale</code> and the last entry is
+ * the least prefered <code>Locale</code>.
+ * <p>
+ * Returning an empty list is equivalent to returning a singleton list whose
+ * single entry is the {@link ResourceBundleProvider#getDefaultLocale()}.
+ *
+ * @param request The <code>SlingHttpServletRequest</code> providing hints
+ * and information for the <code>Locale</code> resolution.
+ * @return The list of <code>Locale</code>s to use for internationalization
+ * of request processing
+ */
+ List<Locale> resolveLocale(HttpServletRequest request);
+
+}
Propchange: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/RequestLocaleResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/ResourceBundleProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/ResourceBundleProvider.java?rev=1158191&r1=1158190&r2=1158191&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/ResourceBundleProvider.java (original)
+++ sling/trunk/contrib/extensions/i18n/src/main/java/org/apache/sling/i18n/ResourceBundleProvider.java Tue Aug 16 10:47:36 2011
@@ -34,6 +34,12 @@ import java.util.ResourceBundle;
public interface ResourceBundleProvider {
/**
+ * Request attribute to get the resource bundle.
+ * @since 2.2
+ */
+ String BUNDLE_REQ_ATTR = "org.apache.sling.i18n.resourcebundle";
+
+ /**
* Returns the default <code>Locale</code> assumed by this instance.
*/
Locale getDefaultLocale();
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=1158191&r1=1158190&r2=1158191&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 16 10:47:36 2011
@@ -32,6 +32,9 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
@@ -44,6 +47,7 @@ import org.apache.sling.api.SlingHttpSer
import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
import org.apache.sling.i18n.DefaultLocaleResolver;
import org.apache.sling.i18n.LocaleResolver;
+import org.apache.sling.i18n.RequestLocaleResolver;
import org.apache.sling.i18n.ResourceBundleProvider;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
@@ -56,58 +60,156 @@ import org.slf4j.LoggerFactory;
@SlingFilter(generateComponent = false, generateService = true, order = -700, scope = SlingFilterScope.REQUEST)
@Component(immediate = true, metatype = false)
@Properties({
+ @Property(name = "pattern", value="/.*"),
@Property(name = Constants.SERVICE_DESCRIPTION, value = "Internationalization Support Filter"),
@Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation") })
public class I18NFilter implements Filter {
- /** default log */
- private static final Logger log = LoggerFactory.getLogger(I18NFilter.class.getName());
+ /** Logger */
+ private final static Logger LOG = LoggerFactory.getLogger(I18NFilter.class.getName());
- private static LocaleResolver DEFAULT_LOCALE_RESOLVER = new DefaultLocaleResolver();
+ private final DefaultLocaleResolver DEFAULT_LOCALE_RESOLVER = new DefaultLocaleResolver();
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
private LocaleResolver localeResolver = DEFAULT_LOCALE_RESOLVER;
@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;
+ /** Count the number init() has been called. */
+ private volatile int initCount;
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
public void init(FilterConfig filterConfig) {
- // nothing to do
+ synchronized(this) {
+ initCount++;
+ }
}
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
-
- // wrap with our ResourceBundle provisioning
- request = new I18NSlingHttpServletRequest(request,
- resourceBundleProvider, localeResolver);
+ /**
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request,
+ final ServletResponse response,
+ final FilterChain chain)
+ throws IOException, ServletException {
+ final boolean runGlobal = this.initCount == 2;
+ if ( request instanceof SlingHttpServletRequest ) {
+ // check if we have to wrap
+ if ( !runGlobal || this.requestLocaleResolver == DEFAULT_LOCALE_RESOLVER ) {
+ // wrap with our ResourceBundle provisioning
+ request = new I18NSlingHttpServletRequest(request,
+ resourceBundleProvider, localeResolver);
+ }
+ } else {
+ request = new I18NHttpServletRequest(request,
+ resourceBundleProvider, requestLocaleResolver);
+ }
// and forward the request
chain.doFilter(request, response);
}
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
public void destroy() {
- // nothing to do
+ synchronized(this) {
+ initCount--;
+ }
}
// ---------- SCR Integration ----------------------------------------------
- protected void bindLocaleResolver(LocaleResolver localeResolver) {
- this.localeResolver = localeResolver;
+ protected void bindLocaleResolver(final LocaleResolver resolver) {
+ this.localeResolver = resolver;
}
- protected void unbindLocaleResolver(LocaleResolver localeResolver) {
- if (this.localeResolver == localeResolver) {
+ protected void unbindLocaleResolver(final LocaleResolver resolver) {
+ if (this.localeResolver == resolver) {
this.localeResolver = DEFAULT_LOCALE_RESOLVER;
}
}
+ protected void bindRequestLocaleResolver(final RequestLocaleResolver resolver) {
+ this.requestLocaleResolver = resolver;
+ }
+
+ protected void unbindRequestLocaleResolver(final RequestLocaleResolver resolver) {
+ if (this.requestLocaleResolver == resolver) {
+ this.requestLocaleResolver = DEFAULT_LOCALE_RESOLVER;
+ }
+ }
// ---------- internal -----------------------------------------------------
// ---------- internal class -----------------------------------------------
- private static class I18NSlingHttpServletRequest extends
- SlingHttpServletRequestWrapper {
+ private static class I18NHttpServletRequest
+ extends HttpServletRequestWrapper {
+
+ private final ResourceBundleProvider bundleProvider;
+
+ private final RequestLocaleResolver localeResolver;
+
+ private Locale locale;
+
+ private List<Locale> localeList;
+
+ private ResourceBundle resourceBundle;
+
+ I18NHttpServletRequest(final ServletRequest delegatee,
+ final ResourceBundleProvider bundleProvider,
+ final RequestLocaleResolver localeResolver) {
+ super((HttpServletRequest)delegatee);
+ this.bundleProvider = bundleProvider;
+ this.localeResolver = localeResolver;
+ }
+
+ @Override
+ public Locale getLocale() {
+ if (locale == null) {
+ locale = this.getLocaleList().get(0);
+ }
+
+ return locale;
+ }
+
+ @Override
+ public Enumeration<?> getLocales() {
+ return Collections.enumeration(getLocaleList());
+ }
+
+ @Override
+ public Object getAttribute(final String name) {
+ if ( ResourceBundleProvider.BUNDLE_REQ_ATTR.equals(name) ) {
+ if ( this.resourceBundle == null && this.bundleProvider != null) {
+ this.resourceBundle = this.bundleProvider.getResourceBundle(this.getLocale());
+ }
+ return this.resourceBundle;
+ }
+ return super.getAttribute(name);
+ }
+
+ private List<Locale> getLocaleList() {
+ if (localeList == null) {
+ List<Locale> resolved = localeResolver.resolveLocale((HttpServletRequest)this.getRequest());
+ this.localeList = (resolved != null && !resolved.isEmpty())
+ ? resolved
+ : Collections.singletonList(this.bundleProvider.getDefaultLocale());
+ }
+
+ return localeList;
+ }
+
+ }
+
+ private static class I18NSlingHttpServletRequest
+ extends SlingHttpServletRequestWrapper {
private final ResourceBundleProvider bundleProvider;
@@ -117,9 +219,9 @@ public class I18NFilter implements Filte
private List<Locale> localeList;
- I18NSlingHttpServletRequest(ServletRequest delegatee,
- ResourceBundleProvider bundleProvider,
- LocaleResolver localeResolver) {
+ I18NSlingHttpServletRequest(final ServletRequest delegatee,
+ final ResourceBundleProvider bundleProvider,
+ final LocaleResolver localeResolver) {
super((SlingHttpServletRequest) delegatee);
this.bundleProvider = bundleProvider;
this.localeResolver = localeResolver;
@@ -131,6 +233,15 @@ public class I18NFilter implements Filte
}
@Override
+ public Object getAttribute(final String name) {
+ if ( ResourceBundleProvider.BUNDLE_REQ_ATTR.equals(name) ) {
+ final Object superValue = super.getAttribute(name);
+ return (superValue != null ? superValue : this.getResourceBundle(null));
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
public ResourceBundle getResourceBundle(String baseName, Locale locale) {
if (bundleProvider != null) {
if (locale == null) {
@@ -140,12 +251,12 @@ public class I18NFilter implements Filte
try {
return bundleProvider.getResourceBundle(baseName, locale);
} catch (MissingResourceException mre) {
- log.warn(
+ LOG.warn(
"getResourceBundle: Cannot get ResourceBundle from provider",
mre);
}
} else {
- log.info("getResourceBundle: ResourceBundleProvider not available, calling default implementation");
+ LOG.info("getResourceBundle: ResourceBundleProvider not available, calling default implementation");
}
return super.getResourceBundle(baseName, locale);