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 2017/03/29 06:40:09 UTC

svn commit: r1789277 - in /sling/trunk/bundles/extensions/i18n: ./ src/main/java/org/apache/sling/i18n/impl/ src/main/resources/OSGI-INF/ src/test/java/org/apache/sling/i18n/impl/

Author: cziegeler
Date: Wed Mar 29 06:40:08 2017
New Revision: 1789277

URL: http://svn.apache.org/viewvc?rev=1789277&view=rev
Log:
SLING-6741 : Migrate to R6 annotations, clean up dependencies

Removed:
    sling/trunk/bundles/extensions/i18n/src/main/resources/OSGI-INF/
Modified:
    sling/trunk/bundles/extensions/i18n/pom.xml
    sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java
    sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundleProvider.java
    sling/trunk/bundles/extensions/i18n/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java

Modified: sling/trunk/bundles/extensions/i18n/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/i18n/pom.xml?rev=1789277&r1=1789276&r2=1789277&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/i18n/pom.xml (original)
+++ sling/trunk/bundles/extensions/i18n/pom.xml Wed Mar 29 06:40:08 2017
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>29</version>
+        <version>30</version>
         <relativePath />
     </parent>
 
@@ -52,10 +52,6 @@
         <plugins>
             <plugin>
                 <groupId>org.apache.felix</groupId>
-                <artifactId>maven-scr-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <extensions>true</extensions>
                 <configuration>
@@ -188,11 +184,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.scr.annotations</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
@@ -218,7 +209,6 @@
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
-            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>

Modified: sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java?rev=1789277&r1=1789276&r2=1789277&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java (original)
+++ sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/I18NFilter.java Wed Mar 29 06:40:08 2017
@@ -37,14 +37,6 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferencePolicyOption;
-import org.apache.felix.scr.annotations.sling.SlingFilter;
-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.Order;
@@ -54,6 +46,11 @@ import org.apache.sling.i18n.LocaleResol
 import org.apache.sling.i18n.RequestLocaleResolver;
 import org.apache.sling.i18n.ResourceBundleProvider;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,14 +59,16 @@ import org.slf4j.LoggerFactory;
  * The <code>I18NFilter</code> class is a request level filter, which provides
  * the resource bundle for the current request.
  */
-@SlingFilter(generateService = true,
-             order = 700, scope = { SlingFilterScope.REQUEST, SlingFilterScope.ERROR })
-@Properties({
-    @Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, value="/"),
-    @Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
-              value = "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Internationalization Support Filter"),
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation") })
+@Component(service = Filter.class,
+    property = {
+            Constants.SERVICE_DESCRIPTION + "=Internationalization Support Filter",
+            Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+            Constants.SERVICE_RANKING + ":Integer=700",
+            "sling.filter.scope=REQUEST",
+            "sling.filter.scope=ERROR",
+            HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN + "=/",
+            HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT + "=(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)"
+    })
 public class I18NFilter implements Filter {
 
     /**
@@ -82,17 +81,11 @@ public class I18NFilter implements Filte
 
     private final DefaultLocaleResolver DEFAULT_LOCALE_RESOLVER = new DefaultLocaleResolver();
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY)
     private volatile LocaleResolver localeResolver = DEFAULT_LOCALE_RESOLVER;
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY)
     private volatile RequestLocaleResolver requestLocaleResolver = DEFAULT_LOCALE_RESOLVER;
 
-    @Reference(name = "resourceBundleProvider",
-               referenceInterface = ResourceBundleProvider.class,
-               cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
-               policy = ReferencePolicy.DYNAMIC)
-    private final Map<Object, ResourceBundleProvider> providers = new TreeMap<Object, ResourceBundleProvider>();
+    private final Map<Object, ResourceBundleProvider> providers = new TreeMap<>();
 
     private volatile ResourceBundleProvider[] sortedProviders = new ResourceBundleProvider[0];
 
@@ -150,6 +143,9 @@ public class I18NFilter implements Filte
 
     // ---------- SCR Integration ----------------------------------------------
 
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            policy = ReferencePolicy.DYNAMIC,
+            policyOption=ReferencePolicyOption.GREEDY)
     protected void bindLocaleResolver(final LocaleResolver resolver) {
         this.localeResolver = resolver;
     }
@@ -160,6 +156,9 @@ public class I18NFilter implements Filte
         }
     }
 
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            policy = ReferencePolicy.DYNAMIC,
+            policyOption=ReferencePolicyOption.GREEDY)
     protected void bindRequestLocaleResolver(final RequestLocaleResolver resolver) {
         this.requestLocaleResolver = resolver;
     }
@@ -170,6 +169,9 @@ public class I18NFilter implements Filte
         }
     }
 
+    @Reference(service = ResourceBundleProvider.class,
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC)
     protected void bindResourceBundleProvider(final ResourceBundleProvider provider, final Map<String, Object> props) {
         synchronized ( this.providers ) {
             this.providers.put(ServiceUtil.getComparableForServiceRanking(props, Order.ASCENDING), provider);

Modified: sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundleProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundleProvider.java?rev=1789277&r1=1789276&r2=1789277&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundleProvider.java (original)
+++ sling/trunk/bundles/extensions/i18n/src/main/java/org/apache/sling/i18n/impl/JcrResourceBundleProvider.java Wed Mar 29 06:40:08 2017
@@ -39,10 +39,6 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Semaphore;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -51,13 +47,20 @@ import org.apache.sling.api.resource.Val
 import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
 import org.apache.sling.api.resource.observation.ResourceChange;
 import org.apache.sling.api.resource.observation.ResourceChangeListener;
-import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.commons.scheduler.ScheduleOptions;
 import org.apache.sling.commons.scheduler.Scheduler;
 import org.apache.sling.i18n.ResourceBundleProvider;
 import org.apache.sling.serviceusermapping.ServiceUserMapped;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,23 +70,39 @@ import org.slf4j.LoggerFactory;
  * <code>ResourceBundle</code> instances from resources stored in the
  * repository.
  */
-@Component(immediate = true, metatype = true, label = "%provider.name", description = "%provider.description")
-@Service({ResourceBundleProvider.class, ResourceChangeListener.class})
-@Property(name=ResourceChangeListener.PATHS, value="/")
+@Component(service = {ResourceBundleProvider.class, ResourceChangeListener.class},
+    property = {
+            Constants.SERVICE_DESCRIPTION + "=I18n Resource Bundle Provider",
+            Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+            ResourceChangeListener.PATHS + "=/"
+    })
+@Designate(ocd = JcrResourceBundleProvider.Config.class)
 public class JcrResourceBundleProvider implements ResourceBundleProvider, ResourceChangeListener, ExternalResourceChangeListener {
 
-    private static final boolean DEFAULT_PRELOAD_BUNDLES = false;
-
-    private static final int DEFAULT_INVALIDATION_DELAY = 5000;
-
-    @Property(value = "en")
-    private static final String PROP_DEFAULT_LOCALE = "locale.default";
-
-    @Property(boolValue = DEFAULT_PRELOAD_BUNDLES)
-    private static final String PROP_PRELOAD_BUNDLES = "preload.bundles";
-
-    @Property(longValue = DEFAULT_INVALIDATION_DELAY)
-    private static final String PROP_INVALIDATION_DELAY = "invalidation.delay";
+    @ObjectClassDefinition(name ="Apache Sling I18N ResourceBundle Provider",
+            description ="ResourceBundleProvider service which loads the messages "+
+                 "from the repository. If the user name field is left empty, the provider will "+
+                 "log into the repository as the administrative user. Otherwise the given user "+
+                 "name and password are used to access the repository. Failing to access the "+
+                 "repository, effectively disables the provider.")
+    public @interface Config {
+
+        @AttributeDefinition(name = "Default Locale",
+            description = "The default locale to assume if none can be "+
+                 "resolved otherwise. This value must be in the form acceptable to the "+
+                 "java.util.Locale class.")
+        String locale_default() default "en";
+
+        @AttributeDefinition(name = "Preload Bundles",
+                description = "Whether or not to eagerly load the resource bundles "+
+                    "on bundle start or a cache invalidation.")
+        boolean preload_bundles() default false;
+
+        @AttributeDefinition(name = "Invalidation Delay",
+                description = "In case of dictionary change events the cached "+
+                        "resource bundle becomes invalid after the given delay (in ms). ")
+        long invalidation_delay() default 5000;
+    }
 
     @Reference
     private Scheduler scheduler;
@@ -117,9 +136,9 @@ public class JcrResourceBundleProvider i
      * Map of cached resource bundles indexed by a key combined of the base name
      * and <code>Locale</code> used to load and identify the <code>ResourceBundle</code>.
      */
-    private final ConcurrentHashMap<Key, JcrResourceBundle> resourceBundleCache = new ConcurrentHashMap<Key, JcrResourceBundle>();
+    private final ConcurrentHashMap<Key, JcrResourceBundle> resourceBundleCache = new ConcurrentHashMap<>();
 
-    private final ConcurrentHashMap<Key, Semaphore> loadingGuards = new ConcurrentHashMap<Key, Semaphore>();
+    private final ConcurrentHashMap<Key, Semaphore> loadingGuards = new ConcurrentHashMap<>();
 
     /**
      * paths from which JCR resource bundles have been loaded
@@ -137,7 +156,7 @@ public class JcrResourceBundleProvider i
     /**
      * Each ResourceBundle is registered as a service. Each registration is stored in this map with the locale & base name used as a key.
      */
-    private final Map<Key, ServiceRegistration<ResourceBundle>> bundleServiceRegistrations = new HashMap<Key, ServiceRegistration<ResourceBundle>>();
+    private final Map<Key, ServiceRegistration<ResourceBundle>> bundleServiceRegistrations = new HashMap<>();
 
     private boolean preloadBundles;
 
@@ -331,7 +350,7 @@ public class JcrResourceBundleProvider i
             log.warn("Could not find resource bundle service for {}", key);
         }
 
-        Collection<JcrResourceBundle> dependentBundles = new ArrayList<JcrResourceBundle>();
+        Collection<JcrResourceBundle> dependentBundles = new ArrayList<>();
         // this bundle might be a parent of a cached bundle -> invalidate those dependent bundles as well
         for (JcrResourceBundle bundle : resourceBundleCache.values()) {
             if (bundle.getParent() instanceof JcrResourceBundle) {
@@ -360,14 +379,14 @@ public class JcrResourceBundleProvider i
      * details and the default locale to use
      * @throws LoginException
      */
-    protected void activate(BundleContext context, Map<String, Object> props) throws LoginException {
-        String localeString = PropertiesUtil.toString(props.get(PROP_DEFAULT_LOCALE),
-            null);
+    @Activate
+    protected void activate(final BundleContext context, final Config config) throws LoginException {
+        String localeString = config.locale_default();
         this.defaultLocale = toLocale(localeString);
-        this.preloadBundles = PropertiesUtil.toBoolean(props.get(PROP_PRELOAD_BUNDLES), DEFAULT_PRELOAD_BUNDLES);
+        this.preloadBundles = config.preload_bundles();
 
         this.bundleContext = context;
-        invalidationDelay = PropertiesUtil.toLong(props.get(PROP_INVALIDATION_DELAY), DEFAULT_INVALIDATION_DELAY);
+        invalidationDelay = config.invalidation_delay();
         if (this.resourceResolverFactory != null) { // this is only null during test execution!
             resourceResolver = resourceResolverFactory.getServiceResourceResolver(null);
             scheduleReloadBundles(false);
@@ -375,6 +394,7 @@ public class JcrResourceBundleProvider i
 
     }
 
+    @Deactivate
     protected void deactivate() {
         clearCache();
         resourceResolver.close();
@@ -423,7 +443,7 @@ public class JcrResourceBundleProvider i
     }
 
     private void registerResourceBundle(Key key, JcrResourceBundle resourceBundle) {
-        Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
+        Dictionary<String, Object> serviceProps = new Hashtable<>();
         if (key.baseName != null) {
             serviceProps.put("baseName", key.baseName);
         }
@@ -525,7 +545,7 @@ public class JcrResourceBundleProvider i
             resourceResolver.refresh();
             Iterator<Map<String, Object>> bundles = resourceResolver.queryResources(
                     JcrResourceBundle.QUERY_LANGUAGE_ROOTS, "xpath");
-            Set<Key> usedKeys = new HashSet<Key>();
+            Set<Key> usedKeys = new HashSet<>();
             while (bundles.hasNext()) {
                 Map<String,Object> bundle = bundles.next();
                 if (bundle.containsKey(PROP_LANGUAGE)) {

Modified: sling/trunk/bundles/extensions/i18n/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/i18n/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java?rev=1789277&r1=1789276&r2=1789277&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/i18n/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java (original)
+++ sling/trunk/bundles/extensions/i18n/src/test/java/org/apache/sling/i18n/impl/ConcurrentJcrResourceBundleLoadingTest.java Wed Mar 29 06:40:08 2017
@@ -26,9 +26,8 @@ import static org.powermock.api.mockito.
 import static org.powermock.api.mockito.PowerMockito.spy;
 import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
 
-import java.util.HashMap;
+import java.lang.annotation.Annotation;
 import java.util.Locale;
-import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -60,9 +59,28 @@ public class ConcurrentJcrResourceBundle
     @Before
     public void setup() throws Exception {
         provider = spy(new JcrResourceBundleProvider());
-        Map<String, Object> properties = new HashMap<String, Object>();
-        properties.put("locale.default", "en");
-        provider.activate(PowerMockito.mock(BundleContext.class), properties);
+        provider.activate(PowerMockito.mock(BundleContext.class), new JcrResourceBundleProvider.Config() {
+
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return JcrResourceBundleProvider.Config.class;
+            }
+
+            @Override
+            public boolean preload_bundles() {
+                return false;
+            }
+
+            @Override
+            public String locale_default() {
+                return "en";
+            }
+
+            @Override
+            public long invalidation_delay() {
+                return 5000;
+            }
+        });
         doReturn(english).when(provider, "createResourceBundle", eq(null), eq(Locale.ENGLISH));
         doReturn(german).when(provider, "createResourceBundle", eq(null), eq(Locale.GERMAN));
         Mockito.when(german.getLocale()).thenReturn(Locale.GERMAN);