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