Author: cziegeler
Date: Thu Jun 23 07:34:05 2016
New Revision: 1749852

URL: http://svn.apache.org/viewvc?rev=1749852&view=rev
Log:
SLING-5806 : No service returned if several services for same type

Added:
    
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
   (with props)
    
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
   (with props)
    
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
   (with props)
Modified:
    
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java

Modified: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java?rev=1749852&r1=1749851&r2=1749852&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java
 (original)
+++ 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java
 Thu Jun 23 07:34:05 2016
@@ -16,10 +16,7 @@
  */
 package org.apache.sling.rewriter.impl;
 
-import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.apache.sling.rewriter.Generator;
@@ -33,10 +30,8 @@ import org.apache.sling.rewriter.Seriali
 import org.apache.sling.rewriter.Transformer;
 import org.apache.sling.rewriter.TransformerFactory;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,13 +42,13 @@ import org.slf4j.LoggerFactory;
 public class FactoryCache {
 
     /** The required property containing the component type. */
-    private static final String PROPERTY_TYPE = "pipeline.type";
+    static final String PROPERTY_TYPE = "pipeline.type";
 
     /** The optional property for the pipeline mode (global) */
-    private static final String PROPERTY_MODE = "pipeline.mode";
+    static final String PROPERTY_MODE = "pipeline.mode";
 
     /** The global mode. */
-    private static final String MODE_GLOBAL = "global";
+    static final String MODE_GLOBAL = "global";
 
     /** The optional property for the paths the component should apply to */
     private static final String PROPERTY_PATHS = "pipeline.paths";
@@ -71,7 +66,7 @@ public class FactoryCache {
     private static final String PROPERTY_RESOURCE_TYPES = 
"pipeline.resourceTypes";
 
     /** The logger. */
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(FactoryCache.class);
+    static final Logger LOGGER = LoggerFactory.getLogger(FactoryCache.class);
 
     /** The tracker for generator factories. */
     private final HashingServiceTrackerCustomizer<GeneratorFactory> 
generatorTracker;
@@ -220,209 +215,18 @@ public class FactoryCache {
     }
 
     /**
-     * This service tracker stores all services into a hash map.
-     */
-    private static class HashingServiceTrackerCustomizer<T> extends 
ServiceTracker {
-
-        /** The services hashed by their name property. */
-        private final Map<String, T> services = new ConcurrentHashMap<String, 
T>();
-
-        /** The bundle context. */
-        protected final BundleContext context;
-
-        public HashingServiceTrackerCustomizer(final BundleContext bc, final 
String serviceClassName) {
-            super(bc, serviceClassName, null);
-            this.context = bc;
-        }
-
-        public T getFactory(final String type) {
-            return services.get(type);
-        }
-
-        private String getType(final ServiceReference ref) {
-            final String type = (String) ref.getProperty(PROPERTY_TYPE);
-            return type;
-        }
-
-        /**
-         * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-         */
-        public Object addingService(final ServiceReference reference) {
-            final String type = this.getType(reference);
-            @SuppressWarnings("unchecked")
-            final T factory = (type == null ? null : (T) 
this.context.getService(reference));
-            if ( factory != null ) {
-                if ( LOGGER.isDebugEnabled() ) {
-                    LOGGER.debug("Found service {}, type={}.", factory, type);
-                }
-                this.services.put(type, factory);
-            }
-            return factory;
-        }
-
-        /**
-         * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
-         */
-        public void removedService(final ServiceReference reference, final 
Object service) {
-            final String type = this.getType(reference);
-            if ( type != null ) {
-                this.services.remove(type);
-                this.context.ungetService(reference);
-            }
-        }
-    }
-
-    private static final class TransformerFactoryServiceTracker<T> extends 
HashingServiceTrackerCustomizer<T> {
-
-        private String getMode(final ServiceReference ref) {
-            final String mode = (String) ref.getProperty(PROPERTY_MODE);
-            return mode;
-        }
-
-        private boolean isGlobal(final ServiceReference ref) {
-            return MODE_GLOBAL.equalsIgnoreCase(this.getMode(ref));
-        }
-
-        public static final TransformerFactoryEntry[] EMPTY_ENTRY_ARRAY = new 
TransformerFactoryEntry[0];
-        public static final TransformerFactoryEntry[][] 
EMPTY_DOUBLE_ENTRY_ARRAY = new TransformerFactoryEntry[][] {EMPTY_ENTRY_ARRAY, 
EMPTY_ENTRY_ARRAY};
-
-        public static final TransformerFactory[] EMPTY_FACTORY_ARRAY = new 
TransformerFactory[0];
-        public static final TransformerFactory[][] EMPTY_DOUBLE_FACTORY_ARRAY 
= new TransformerFactory[][] {EMPTY_FACTORY_ARRAY, EMPTY_FACTORY_ARRAY};
-
-        private TransformerFactoryEntry[][] cached = EMPTY_DOUBLE_ENTRY_ARRAY;
-
-        /** flag for cache. */
-        private boolean cacheIsValid = true;
-
-        public TransformerFactoryServiceTracker(final BundleContext bc, final 
String serviceClassName) {
-            super(bc, serviceClassName);
-        }
-
-        /**
-         * @see 
org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
-         */
-        public Object addingService(ServiceReference reference) {
-            final boolean isGlobal = isGlobal(reference);
-            if ( isGlobal ) {
-                this.cacheIsValid = false;
-            }
-            Object obj = super.addingService(reference);
-            if ( obj == null && isGlobal ) {
-                obj = this.context.getService(reference);
-            }
-            return obj;
-        }
-
-        /**
-         * @see 
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
-         */
-        public void removedService(ServiceReference reference, Object service) 
{
-            if ( isGlobal(reference) ) {
-                this.cacheIsValid = false;
-            }
-            super.removedService(reference, service);
-        }
-
-        /**
-         * Get all global transformer factories.
-         * @return Two arrays of transformer factories
-         */
-        public TransformerFactoryEntry[][] 
getGlobalTransformerFactoryEntries() {
-            if ( !this.cacheIsValid ) {
-                synchronized ( this ) {
-                    if ( !this.cacheIsValid ) {
-                        final ServiceReference[] refs = 
this.getServiceReferences();
-                        if ( refs == null || refs.length == 0 ) {
-                            this.cached = EMPTY_DOUBLE_ENTRY_ARRAY;
-                        } else {
-                            Arrays.sort(refs, 
ServiceReferenceComparator.INSTANCE);
-
-                            int preCount = 0;
-                            int postCount = 0;
-                            for(final ServiceReference ref : refs) {
-                                if ( isGlobal(ref) ) {
-                                    final Object r = 
ref.getProperty(Constants.SERVICE_RANKING);
-                                    int ranking = (r instanceof Integer ? 
(Integer)r : 0);
-                                    if ( ranking < 0 ) {
-                                        preCount++;
-                                    } else {
-                                        postCount++;
-                                    }
-                                }
-                            }
-                            final TransformerFactoryEntry[][] globalFactories 
= new TransformerFactoryEntry[2][];
-                            if ( preCount == 0 ) {
-                                globalFactories[0] = EMPTY_ENTRY_ARRAY;
-                            } else {
-                                globalFactories[0] = new 
TransformerFactoryEntry[preCount];
-                            }
-                            if ( postCount == 0) {
-                                globalFactories[1] = EMPTY_ENTRY_ARRAY;
-                            } else {
-                                globalFactories[1] = new 
TransformerFactoryEntry[postCount];
-                            }
-                            int index = 0;
-                            for(final ServiceReference ref : refs) {
-                                if ( isGlobal(ref) ) {
-                                    if ( index < preCount ) {
-                                        globalFactories[0][index] = new 
TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
-                                    } else {
-                                        globalFactories[1][index - preCount] = 
new TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
-                                    }
-                                    index++;
-                                }
-                            }
-                            this.cached = globalFactories;
-                        }
-                    }
-                    this.cacheIsValid = true;
-                }
-            }
-
-            return this.cached;
-        }
-
-        /**
-         * Get all global transformer factories that apply to the current 
request.
-         * @param context The current processing context.
-         * @return Two arrays containing the transformer factories.
-         */
-        public TransformerFactory[][] getGlobalTransformerFactories(final 
ProcessingContext context) {
-            final TransformerFactoryEntry[][] globalFactoryEntries = 
this.getGlobalTransformerFactoryEntries();
-            // quick check
-            if ( globalFactoryEntries == EMPTY_DOUBLE_ENTRY_ARRAY ) {
-                return EMPTY_DOUBLE_FACTORY_ARRAY;
-            }
-            final TransformerFactory[][] factories = new 
TransformerFactory[2][];
-            for(int i=0; i<2; i++) {
-                if ( globalFactoryEntries[i] == EMPTY_ENTRY_ARRAY ) {
-                    factories[i] = EMPTY_FACTORY_ARRAY;
-                } else {
-                    factories[i] = new 
TransformerFactory[globalFactoryEntries[i].length];
-                    for(int m=0; m<globalFactoryEntries[i].length; m++) {
-                        final TransformerFactoryEntry entry = 
globalFactoryEntries[i][m];
-                        if ( entry.match(context) ) {
-                            factories[i][m] = entry.factory;
-                        }
-                    }
-                }
-            }
-            return factories;
-        }
-    }
-
-    /**
      * Comparator for service references.
      */
-    private static final class ServiceReferenceComparator implements 
Comparator<ServiceReference> {
+    static final class ServiceReferenceComparator implements 
Comparator<ServiceReference> {
         public static ServiceReferenceComparator INSTANCE = new 
ServiceReferenceComparator();
 
+        @Override
         public int compare(ServiceReference o1, ServiceReference o2) {
             return o1.compareTo(o2);
         }
     }
 
-    private static final class TransformerFactoryEntry {
+    static final class TransformerFactoryEntry {
         public final TransformerFactory factory;
 
         private final ProcessorConfiguration configuration;

Added: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java?rev=1749852&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
 (added)
+++ 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
 Thu Jun 23 07:34:05 2016
@@ -0,0 +1,133 @@
+package org.apache.sling.rewriter.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * This service tracker stores all services into a hash map.
+ */
+class HashingServiceTrackerCustomizer<T> extends ServiceTracker {
+
+    public static final class Pair<T> {
+
+        public final ServiceReference reference;
+        public final T service;
+
+        public Pair(final ServiceReference r, final T s) {
+            this.reference = r;
+            this.service = s;
+        }
+    }
+
+    public static final class Entry<T> {
+
+        public volatile T service;
+
+        public final List<Pair<T>> references = new ArrayList<Pair<T>>();
+
+        public void add(final ServiceReference ref, final T service) {
+            references.add(new Pair<T>(ref, service));
+            Collections.sort(references, new Comparator<Pair<T>>() {
+
+                @Override
+                public int compare(final Pair<T> o1, final Pair<T> o2) {
+                    return o2.reference.compareTo(o1.reference);
+                }
+            });
+            if ( references.get(0).reference == ref ) {
+                this.service = service;
+            }
+        }
+
+        public void remove(final ServiceReference ref) {
+            if ( !references.isEmpty() ) {
+                boolean update = references.get(0).reference == ref;
+                final Iterator<Pair<T>> i = references.iterator();
+                while ( i.hasNext() ) {
+                    final Pair<T> pair = i.next();
+                    if ( pair.reference == ref ) {
+                        i.remove();
+                    }
+                }
+                if ( update ) {
+                    if ( references.isEmpty() ) {
+                        this.service = null;
+                    } else {
+                        this.service = references.get(0).service;
+                    }
+                }
+            }
+        }
+    }
+
+    /** The services hashed by their name property. */
+    private final Map<String, Entry<T>> services = new 
ConcurrentHashMap<String, Entry<T>>();
+
+    /** The bundle context. */
+    protected final BundleContext context;
+
+    public HashingServiceTrackerCustomizer(final BundleContext bc, final 
String serviceClassName) {
+        super(bc, serviceClassName, null);
+        this.context = bc;
+    }
+
+    public T getFactory(final String type) {
+        final Entry<T> entry = services.get(type);
+        return entry == null ? null : entry.service;
+    }
+
+    private String getType(final ServiceReference ref) {
+        final String type = (String) 
ref.getProperty(FactoryCache.PROPERTY_TYPE);
+        return type;
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    @Override
+    public Object addingService(final ServiceReference reference) {
+        final String type = this.getType(reference);
+        @SuppressWarnings("unchecked")
+        final T factory = (type == null ? null : (T) 
this.context.getService(reference));
+        if ( factory != null ) {
+            if ( FactoryCache.LOGGER.isDebugEnabled() ) {
+                FactoryCache.LOGGER.debug("Found service {}, type={}.", 
factory, type);
+            }
+            synchronized ( this ) {
+                Entry<T> entry = this.services.get(type);
+                if ( entry == null ) {
+                    entry = new Entry<T>();
+                    this.services.put(type, entry);
+                }
+                entry.add(reference, factory);
+            }
+        }
+        return factory;
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+     */
+    @Override
+    public void removedService(final ServiceReference reference, final Object 
service) {
+        final String type = this.getType(reference);
+        if ( type != null ) {
+            synchronized ( this ) {
+                final Entry<T> entry = this.services.get(type);
+                if ( entry != null ) {
+                    entry.remove(reference);
+                }
+            }
+            this.context.ungetService(reference);
+        }
+    }
+}
\ No newline at end of file

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizer.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java?rev=1749852&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
 (added)
+++ 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
 Thu Jun 23 07:34:05 2016
@@ -0,0 +1,152 @@
+package org.apache.sling.rewriter.impl;
+
+import java.util.Arrays;
+
+import org.apache.sling.rewriter.ProcessingContext;
+import org.apache.sling.rewriter.TransformerFactory;
+import org.apache.sling.rewriter.impl.FactoryCache.ServiceReferenceComparator;
+import org.apache.sling.rewriter.impl.FactoryCache.TransformerFactoryEntry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+final class TransformerFactoryServiceTracker<T> extends 
HashingServiceTrackerCustomizer<T> {
+
+    private String getMode(final ServiceReference ref) {
+        final String mode = (String) 
ref.getProperty(FactoryCache.PROPERTY_MODE);
+        return mode;
+    }
+
+    private boolean isGlobal(final ServiceReference ref) {
+        return FactoryCache.MODE_GLOBAL.equalsIgnoreCase(this.getMode(ref));
+    }
+
+    public static final TransformerFactoryEntry[] EMPTY_ENTRY_ARRAY = new 
TransformerFactoryEntry[0];
+    public static final TransformerFactoryEntry[][] EMPTY_DOUBLE_ENTRY_ARRAY = 
new TransformerFactoryEntry[][] {EMPTY_ENTRY_ARRAY, EMPTY_ENTRY_ARRAY};
+
+    public static final TransformerFactory[] EMPTY_FACTORY_ARRAY = new 
TransformerFactory[0];
+    public static final TransformerFactory[][] EMPTY_DOUBLE_FACTORY_ARRAY = 
new TransformerFactory[][] {EMPTY_FACTORY_ARRAY, EMPTY_FACTORY_ARRAY};
+
+    private TransformerFactoryEntry[][] cached = EMPTY_DOUBLE_ENTRY_ARRAY;
+
+    /** flag for cache. */
+    private boolean cacheIsValid = true;
+
+    public TransformerFactoryServiceTracker(final BundleContext bc, final 
String serviceClassName) {
+        super(bc, serviceClassName);
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
+     */
+    @Override
+    public Object addingService(ServiceReference reference) {
+        final boolean isGlobal = isGlobal(reference);
+        if ( isGlobal ) {
+            this.cacheIsValid = false;
+        }
+        Object obj = super.addingService(reference);
+        if ( obj == null && isGlobal ) {
+            obj = this.context.getService(reference);
+        }
+        return obj;
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+     */
+    @Override
+    public void removedService(ServiceReference reference, Object service) {
+        if ( isGlobal(reference) ) {
+            this.cacheIsValid = false;
+        }
+        super.removedService(reference, service);
+    }
+
+    /**
+     * Get all global transformer factories.
+     * @return Two arrays of transformer factories
+     */
+    public TransformerFactoryEntry[][] getGlobalTransformerFactoryEntries() {
+        if ( !this.cacheIsValid ) {
+            synchronized ( this ) {
+                if ( !this.cacheIsValid ) {
+                    final ServiceReference[] refs = 
this.getServiceReferences();
+                    if ( refs == null || refs.length == 0 ) {
+                        this.cached = EMPTY_DOUBLE_ENTRY_ARRAY;
+                    } else {
+                        Arrays.sort(refs, ServiceReferenceComparator.INSTANCE);
+
+                        int preCount = 0;
+                        int postCount = 0;
+                        for(final ServiceReference ref : refs) {
+                            if ( isGlobal(ref) ) {
+                                final Object r = 
ref.getProperty(Constants.SERVICE_RANKING);
+                                int ranking = (r instanceof Integer ? 
(Integer)r : 0);
+                                if ( ranking < 0 ) {
+                                    preCount++;
+                                } else {
+                                    postCount++;
+                                }
+                            }
+                        }
+                        final TransformerFactoryEntry[][] globalFactories = 
new TransformerFactoryEntry[2][];
+                        if ( preCount == 0 ) {
+                            globalFactories[0] = EMPTY_ENTRY_ARRAY;
+                        } else {
+                            globalFactories[0] = new 
TransformerFactoryEntry[preCount];
+                        }
+                        if ( postCount == 0) {
+                            globalFactories[1] = EMPTY_ENTRY_ARRAY;
+                        } else {
+                            globalFactories[1] = new 
TransformerFactoryEntry[postCount];
+                        }
+                        int index = 0;
+                        for(final ServiceReference ref : refs) {
+                            if ( isGlobal(ref) ) {
+                                if ( index < preCount ) {
+                                    globalFactories[0][index] = new 
TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
+                                } else {
+                                    globalFactories[1][index - preCount] = new 
TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
+                                }
+                                index++;
+                            }
+                        }
+                        this.cached = globalFactories;
+                    }
+                }
+                this.cacheIsValid = true;
+            }
+        }
+
+        return this.cached;
+    }
+
+    /**
+     * Get all global transformer factories that apply to the current request.
+     * @param context The current processing context.
+     * @return Two arrays containing the transformer factories.
+     */
+    public TransformerFactory[][] getGlobalTransformerFactories(final 
ProcessingContext context) {
+        final TransformerFactoryEntry[][] globalFactoryEntries = 
this.getGlobalTransformerFactoryEntries();
+        // quick check
+        if ( globalFactoryEntries == EMPTY_DOUBLE_ENTRY_ARRAY ) {
+            return EMPTY_DOUBLE_FACTORY_ARRAY;
+        }
+        final TransformerFactory[][] factories = new TransformerFactory[2][];
+        for(int i=0; i<2; i++) {
+            if ( globalFactoryEntries[i] == EMPTY_ENTRY_ARRAY ) {
+                factories[i] = EMPTY_FACTORY_ARRAY;
+            } else {
+                factories[i] = new 
TransformerFactory[globalFactoryEntries[i].length];
+                for(int m=0; m<globalFactoryEntries[i].length; m++) {
+                    final TransformerFactoryEntry entry = 
globalFactoryEntries[i][m];
+                    if ( entry.match(context) ) {
+                        factories[i][m] = entry.factory;
+                    }
+                }
+            }
+        }
+        return factories;
+    }
+}
\ No newline at end of file

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/TransformerFactoryServiceTracker.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java?rev=1749852&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
 (added)
+++ 
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
 Thu Jun 23 07:34:05 2016
@@ -0,0 +1,98 @@
+/*
+ * 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.rewriter.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class HashingServiceTrackerCustomizerTest {
+
+    @Test public void testAddRemove() {
+        final BundleContext bc = mock(BundleContext.class);
+        final HashingServiceTrackerCustomizer<Object> tracker = new 
HashingServiceTrackerCustomizer<Object>(bc, "java.lang.Object");
+
+        assertNull(tracker.getFactory("a"));
+        final Object service1 = new Object();
+        final ServiceReference ref1 = mock(ServiceReference.class);
+        when(ref1.getProperty(FactoryCache.PROPERTY_TYPE)).thenReturn("a");
+        when(bc.getService(ref1)).thenReturn(service1);
+        tracker.addingService(ref1);
+
+        assertNotNull(tracker.getFactory("a"));
+        assertEquals(service1, tracker.getFactory("a"));
+
+        tracker.removedService(ref1, service1);
+        assertNull(tracker.getFactory("a"));
+    }
+
+    @Test public void testMultipleAddRemove() {
+        final BundleContext bc = mock(BundleContext.class);
+        final HashingServiceTrackerCustomizer<Object> tracker = new 
HashingServiceTrackerCustomizer<Object>(bc, "java.lang.Object");
+
+        assertNull(tracker.getFactory("a"));
+        final Object service1 = new Object();
+        final Object service2 = new Object();
+        final Object service3 = new Object();
+
+        final ServiceReference ref1 = mock(ServiceReference.class);
+        when(ref1.getProperty(FactoryCache.PROPERTY_TYPE)).thenReturn("a");
+        when(bc.getService(ref1)).thenReturn(service1);
+
+        final ServiceReference ref2 = mock(ServiceReference.class);
+        when(ref2.getProperty(FactoryCache.PROPERTY_TYPE)).thenReturn("a");
+        when(bc.getService(ref2)).thenReturn(service2);
+
+        final ServiceReference ref3 = mock(ServiceReference.class);
+        when(ref3.getProperty(FactoryCache.PROPERTY_TYPE)).thenReturn("a");
+        when(bc.getService(ref3)).thenReturn(service3);
+
+        // ordering ref3 has highest ranking, then ref2, then ref1
+        when(ref1.compareTo(ref2)).thenReturn(-1);
+        when(ref1.compareTo(ref3)).thenReturn(-1);
+        when(ref2.compareTo(ref1)).thenReturn( 1);
+        when(ref2.compareTo(ref3)).thenReturn(-1);
+        when(ref3.compareTo(ref1)).thenReturn( 1);
+        when(ref3.compareTo(ref2)).thenReturn( 1);
+
+        tracker.addingService(ref1);
+
+        assertNotNull(tracker.getFactory("a"));
+        assertEquals(service1, tracker.getFactory("a"));
+
+        tracker.addingService(ref2);
+        assertEquals(service2, tracker.getFactory("a"));
+
+        tracker.addingService(ref3);
+        assertEquals(service3, tracker.getFactory("a"));
+
+        tracker.removedService(ref1, service1);
+        assertEquals(service3, tracker.getFactory("a"));
+
+        tracker.removedService(ref3, service3);
+        assertEquals(service2, tracker.getFactory("a"));
+
+        tracker.removedService(ref2, service2);
+        assertNull(tracker.getFactory("a"));
+    }
+}

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/contrib/extensions/rewriter/src/test/java/org/apache/sling/rewriter/impl/HashingServiceTrackerCustomizerTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url


Reply via email to