felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1692966 [3/3] - in /felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds: src/org/apache/felix/scr/impl/ src/org/apache/felix/scr/impl/config/ src/org/apache/felix/scr/impl/helper/ src/org/apache/felix/scr/impl/m...
Date Mon, 27 Jul 2015 22:01:59 GMT
Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTracker.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTracker.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTracker.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTracker.java
Mon Jul 27 22:01:59 2015
@@ -27,13 +27,11 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.osgi.framework.AllServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -72,7 +70,7 @@ import org.osgi.framework.ServiceReferen
  * @param <S>
  * @param <T>
  */
-public class ServiceTracker<S, T> {
+public class ServiceTracker<S, T, U extends ServiceEvent> {
 	/* set this to true to compile in debug messages */
 	static final boolean					DEBUG	= false;
 	/**
@@ -85,27 +83,18 @@ public class ServiceTracker<S, T> {
 	 * 
 	 * @since 1.1
 	 */
-	protected final Filter					filter;
+	protected final Filter					eventFilter;
     /**
      * The {@code ServiceTrackerCustomizer} for this tracker.
      */
-    final ServiceTrackerCustomizer<S, T> customizer;
+    final ServiceTrackerCustomizer<S, T, U> customizer;
 	/**
 	 * Filter string for use when adding the ServiceListener. If this field is
 	 * set, then certain optimizations can be taken since we don't have a user
 	 * supplied filter.
 	 */
-	final String							listenerFilter;
-	/**
-	 * Class name to be tracked. If this field is set, then we are tracking by
-	 * class name.
-	 */
-	private final String					trackClass;
-	/**
-	 * Reference to be tracked. If this field is set, then we are tracking a
-	 * single ServiceReference.
-	 */
-	private final ServiceReference<S>		trackReference;
+	final String							initialReferenceFilterString;
+
 	/**
 	 * Tracked services: {@code ServiceReference} -> customized Object and
 	 * {@code ServiceListener} object
@@ -129,93 +118,9 @@ public class ServiceTracker<S, T> {
 		return tracked;
 	}
 
-	/**
-	 * Cached ServiceReference for getServiceReference.
-	 * 
-	 * This field is volatile since it is accessed by multiple threads.
-	 */
-	private volatile ServiceReference<S>	cachedReference;
-	/**
-	 * Cached service object for getService.
-	 * 
-	 * This field is volatile since it is accessed by multiple threads.
-	 */
-	private volatile T						cachedService;
+    private ExtendedServiceListenerContext<U> extendedServiceListenerContext;
+    private String classFilterString;
 
-	/**
-	 * Create a {@code ServiceTracker} on the specified {@code ServiceReference}
-	 * .
-	 * 
-	 * <p>
-	 * The service referenced by the specified {@code ServiceReference} will be
-	 * tracked by this {@code ServiceTracker}.
-	 * 
-	 * @param context The {@code BundleContext} against which the tracking is
-	 *        done.
-	 * @param reference The {@code ServiceReference} for the service to be
-	 *        tracked.
-	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If customizer
-	 *        is {@code null}, then this {@code ServiceTracker} will be used as
-	 *        the {@code ServiceTrackerCustomizer} and this
-	 *        {@code ServiceTracker} will call the
-	 *        {@code ServiceTrackerCustomizer} methods on itself.
-	 */
-	public ServiceTracker(final BundleContext context, final ServiceReference<S> reference,
final ServiceTrackerCustomizer<S, T> customizer) {
-		this.context = context;
-		this.trackReference = reference;
-		this.trackClass = null;
-		this.customizer = customizer;
-		this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString()
+ ")";
-		try {
-			this.filter = context.createFilter(listenerFilter);
-		} catch (InvalidSyntaxException e) {
-			/*
-			 * we could only get this exception if the ServiceReference was
-			 * invalid
-			 */
-			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException:
" + e.getMessage());
-			iae.initCause(e);
-			throw iae;
-		}
-	}
-
-	/**
-	 * Create a {@code ServiceTracker} on the specified class name.
-	 * 
-	 * <p>
-	 * Services registered under the specified class name will be tracked by
-	 * this {@code ServiceTracker}.
-	 * 
-	 * @param context The {@code BundleContext} against which the tracking is
-	 *        done.
-	 * @param clazz The class name of the services to be tracked.
-	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If customizer
-	 *        is {@code null}, then this {@code ServiceTracker} will be used as
-	 *        the {@code ServiceTrackerCustomizer} and this
-	 *        {@code ServiceTracker} will call the
-	 *        {@code ServiceTrackerCustomizer} methods on itself.
-	 */
-	public ServiceTracker(final BundleContext context, final String clazz, final ServiceTrackerCustomizer<S,
T> customizer) {
-		this.context = context;
-		this.trackReference = null;
-		this.trackClass = clazz;
-		this.customizer = customizer;
-		// we call clazz.toString to verify clazz is non-null!
-		this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")";
-		try {
-			this.filter = context.createFilter(listenerFilter);
-		} catch (InvalidSyntaxException e) {
-			/*
-			 * we could only get this exception if the clazz argument was
-			 * malformed
-			 */
-			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException:
" + e.getMessage());
-			iae.initCause(e);
-			throw iae;
-		}
-	}
 
 	/**
 	 * Create a {@code ServiceTracker} on the specified {@code Filter} object.
@@ -226,51 +131,38 @@ public class ServiceTracker<S, T> {
 	 * 
 	 * @param context The {@code BundleContext} against which the tracking is
 	 *        done.
-	 * @param filter The {@code Filter} to select the services to be tracked.
 	 * @param customizer The customizer object to call when services are added,
 	 *        modified, or removed in this {@code ServiceTracker}. If customizer
 	 *        is null, then this {@code ServiceTracker} will be used as the
 	 *        {@code ServiceTrackerCustomizer} and this {@code ServiceTracker}
 	 *        will call the {@code ServiceTrackerCustomizer} methods on itself.
 	 * @param initialActive Initial active state of the tracker.
+	 * @param bundleComponentActivator TODO
+	 * @param eventFilter The {@code Filter} to select the services to be tracked.
+	 * @param classFilterString TODO
+	 * @param initialReferenceFilterString TODO
 	 * @since 1.1
 	 */
-	public ServiceTracker(final BundleContext context, final Filter filter, final ServiceTrackerCustomizer<S,
T> customizer, boolean initialActive) {
+	public ServiceTracker(final BundleContext context,
+	    final ServiceTrackerCustomizer<S, T, U> customizer,
+	    boolean initialActive,
+	    ExtendedServiceListenerContext<U> bundleComponentActivator,
+	    final Filter eventFilter,
+	    final String classFilterString,
+	    final String initialReferenceFilterString) {
+        if ((context == null)) {
+            /*
+             * we throw a NPE here to be consistent with the other constructors
+             */
+            throw new NullPointerException( "BundleContext");
+        }
 		this.context = context;
-		this.trackReference = null;
-		this.trackClass = null;
-		this.listenerFilter = filter.toString();
-		this.filter = filter;
+		this.initialReferenceFilterString = initialReferenceFilterString;
+		this.eventFilter = eventFilter;
 		this.customizer = customizer;
 		this.active = initialActive;
-		if ((context == null)) {
-			/*
-			 * we throw a NPE here to be consistent with the other constructors
-			 */
-			throw new NullPointerException( "BundleContext");
-		}
-	}
-
-	/**
-	 * Create a {@code ServiceTracker} on the specified class.
-	 * 
-	 * <p>
-	 * Services registered under the name of the specified class will be tracked
-	 * by this {@code ServiceTracker}.
-	 * 
-	 * @param context The {@code BundleContext} against which the tracking is
-	 *        done.
-	 * @param clazz The class of the services to be tracked.
-	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If customizer
-	 *        is {@code null}, then this {@code ServiceTracker} will be used as
-	 *        the {@code ServiceTrackerCustomizer} and this
-	 *        {@code ServiceTracker} will call the
-	 *        {@code ServiceTrackerCustomizer} methods on itself.
-	 * @since 1.5
-	 */
-	public ServiceTracker(final BundleContext context, final Class<S> clazz, final ServiceTrackerCustomizer<S,
T> customizer) {
-		this(context, clazz.getName(), customizer);
+		this.extendedServiceListenerContext = bundleComponentActivator;
+		this.classFilterString = classFilterString;
 	}
 
 	/**
@@ -315,25 +207,13 @@ public class ServiceTracker<S, T> {
 				return;
 			}
 			if (DEBUG) {
-				System.out.println("ServiceTracker.open: " + filter);
+				System.out.println("ServiceTracker.open: " + eventFilter);
 			}
-			t = trackAllServices ? new AllTracked( trackingCount ) : new Tracked( trackingCount );
+			t = new Tracked( trackingCount );
 			synchronized (t) {
 				try {
-					context.addServiceListener(t, listenerFilter);
-					ServiceReference<S>[] references = null;
-					if (trackClass != null) {
-						references = getInitialReferences(trackAllServices, trackClass, null);
-					} else {
-						if (trackReference != null) {
-							if (trackReference.getBundle() != null) {
-								ServiceReference<S>[] single = new ServiceReference[] {trackReference};
-								references = single;
-							}
-						} else { /* user supplied filter */
-							references = getInitialReferences(trackAllServices, null, listenerFilter);
-						}
-					}
+					extendedServiceListenerContext.addServiceListener(classFilterString, eventFilter, t);
+					ServiceReference<S>[] references = getInitialReferences(null, initialReferenceFilterString);
 					/* set tracked with the initial references */
 					t.setInitial(references);
 				} catch (InvalidSyntaxException e) {
@@ -349,18 +229,16 @@ public class ServiceTracker<S, T> {
 	/**
 	 * Returns the list of initial {@code ServiceReference}s that will be
 	 * tracked by this {@code ServiceTracker}.
-	 * 
-	 * @param trackAllServices If {@code true}, use
-	 *        {@code getAllServiceReferences}.
 	 * @param className The class name with which the service was registered, or
 	 *        {@code null} for all services.
 	 * @param filterString The filter criteria or {@code null} for all services.
+	 * 
 	 * @return The list of initial {@code ServiceReference}s.
 	 * @throws InvalidSyntaxException If the specified filterString has an
 	 *         invalid syntax.
 	 */
-	private ServiceReference<S>[] getInitialReferences(boolean trackAllServices, String
className, String filterString) throws InvalidSyntaxException {
-		ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices)
? context.getAllServiceReferences(className, filterString) : context.getServiceReferences(className,
filterString));
+	private ServiceReference<S>[] getInitialReferences(String className, String filterString)
throws InvalidSyntaxException {
+		ServiceReference<S>[] result = (ServiceReference<S>[]) context.getServiceReferences(className,
filterString);
 		return result;
 	}
 
@@ -386,7 +264,7 @@ public class ServiceTracker<S, T> {
 				return map;
 			}
 			if (DEBUG) {
-				System.out.println("ServiceTracker.close: " + filter);
+				System.out.println("ServiceTracker.close: " + eventFilter);
 			}
 			outgoing.close();
             synchronized ( outgoing )
@@ -397,7 +275,7 @@ public class ServiceTracker<S, T> {
 //			references = getServiceReferences();
 //			tracked = null;
 			try {
-				context.removeServiceListener(outgoing);
+				extendedServiceListenerContext.removeServiceListener(classFilterString, eventFilter,
outgoing);
 			} catch (IllegalStateException e) {
 				/* In case the context was stopped. */
 			}
@@ -412,9 +290,7 @@ public class ServiceTracker<S, T> {
 //			}
 //		}
 		if (DEBUG) {
-			if ((cachedReference == null) && (cachedService == null)) {
-				System.out.println("ServiceTracker.close[cached cleared]: " + filter);
-			}
+				System.out.println("ServiceTracker.close[cached cleared]: " + eventFilter);
 		}
         return map;
 	}
@@ -427,7 +303,7 @@ public class ServiceTracker<S, T> {
                 return;
             }
             if (DEBUG) {
-                System.out.println("ServiceTracker.close: " + filter);
+                System.out.println("ServiceTracker.close: " + eventFilter);
             }
         }
         for (ServiceReference<S> ref: toUntrack.keySet()) {
@@ -479,7 +355,7 @@ public class ServiceTracker<S, T> {
 	 * 
 	 * @param reference The reference to modified service.
 	 * @param service The service object for the modified service.
-	 * @see ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, Object,
int)
+	 * @see ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, Object,
int, ServiceEvent)
 	 */
 	public void modifiedService(ServiceReference<S> reference, T service, int trackingCount)
{
 		/* do nothing */
@@ -504,67 +380,13 @@ public class ServiceTracker<S, T> {
 	 * 
 	 * @param reference The reference to removed service.
 	 * @param service The service object for the removed service.
-	 * @see ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, Object,
int)
+	 * @see ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, Object,
int, ServiceEvent)
 	 */
 	public void removedService(ServiceReference<S> reference, T service, int trackingCount)
{
 		context.ungetService(reference);
 	}
 
 	/**
-	 * Wait for at least one service to be tracked by this
-	 * {@code ServiceTracker}. This method will also return when this
-	 * {@code ServiceTracker} is closed.
-	 * 
-	 * <p>
-	 * It is strongly recommended that {@code waitForService} is not used during
-	 * the calling of the {@code BundleActivator} methods.
-	 * {@code BundleActivator} methods are expected to complete in a short
-	 * period of time.
-	 * 
-	 * <p>
-	 * This implementation calls {@link #getService()} to determine if a service
-	 * is being tracked.
-	 * 
-	 * @param timeout The time interval in milliseconds to wait. If zero, the
-	 *        method will wait indefinitely.
-	 * @return Returns the result of {@link #getService()}.
-	 * @throws InterruptedException If another thread has interrupted the
-	 *         current thread.
-	 * @throws IllegalArgumentException If the value of timeout is negative.
-	 */
-	public T waitForService(long timeout) throws InterruptedException {
-		if (timeout < 0) {
-			throw new IllegalArgumentException("timeout value is negative");
-		}
-
-		T object = getService();
-		if (object != null) {
-			return object;
-		}
-
-		final long endTime = (timeout == 0) ? 0 : (System.currentTimeMillis() + timeout);
-		do {
-			final Tracked t = tracked();
-			if (t == null) { /* if ServiceTracker is not open */
-				return null;
-			}
-			synchronized (t) {
-				if (t.size() == 0) {
-					t.wait(timeout);
-				}
-			}
-			object = getService();
-			if (endTime > 0) { // if we have a timeout
-				timeout = endTime - System.currentTimeMillis();
-				if (timeout <= 0) { // that has expired
-					break;
-				}
-			}
-		} while (object == null);
-		return object;
-	}
-
-	/**
 	 * Return an array of {@code ServiceReference}s for all services being
 	 * tracked by this {@code ServiceTracker}.
 	 * 
@@ -586,76 +408,6 @@ public class ServiceTracker<S, T> {
 		}
 	}
 
-	/**
-	 * Returns a {@code ServiceReference} for one of the services being tracked
-	 * by this {@code ServiceTracker}.
-	 * 
-	 * <p>
-	 * If multiple services are being tracked, the service with the highest
-	 * ranking (as specified in its {@code service.ranking} property) is
-	 * returned. If there is a tie in ranking, the service with the lowest
-	 * service ID (as specified in its {@code service.id} property); that is,
-	 * the service that was registered first is returned. This is the same
-	 * algorithm used by {@code BundleContext.getServiceReference}.
-	 * 
-	 * <p>
-	 * This implementation calls {@link #getServiceReferences()} to get the list
-	 * of references for the tracked services.
-	 * 
-	 * @return A {@code ServiceReference} or {@code null} if no services are
-	 *         being tracked.
-	 * @since 1.1
-	 */
-	public ServiceReference<S> getServiceReference() {
-		ServiceReference<S> reference = cachedReference;
-		if (reference != null) {
-			if (DEBUG) {
-				System.out.println("ServiceTracker.getServiceReference[cached]: " + filter);
-			}
-			return reference;
-		}
-		if (DEBUG) {
-			System.out.println("ServiceTracker.getServiceReference: " + filter);
-		}
-		ServiceReference<S>[] references = getServiceReferences();
-		int length = (references == null) ? 0 : references.length;
-		if (length == 0) { /* if no service is being tracked */
-			return null;
-		}
-		int index = 0;
-		if (length > 1) { /* if more than one service, select highest ranking */
-			int rankings[] = new int[length];
-			int count = 0;
-			int maxRanking = Integer.MIN_VALUE;
-			for (int i = 0; i < length; i++) {
-				Object property = references[i].getProperty(Constants.SERVICE_RANKING);
-				int ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
-				rankings[i] = ranking;
-				if (ranking > maxRanking) {
-					index = i;
-					maxRanking = ranking;
-					count = 1;
-				} else {
-					if (ranking == maxRanking) {
-						count++;
-					}
-				}
-			}
-			if (count > 1) { /* if still more than one service, select lowest id */
-				long minId = Long.MAX_VALUE;
-				for (int i = 0; i < length; i++) {
-					if (rankings[i] == maxRanking) {
-						long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
-						if (id < minId) {
-							index = i;
-							minId = id;
-						}
-					}
-				}
-			}
-		}
-		return cachedReference = references[index];
-	}
 
 	/**
 	 * Returns the service object for the specified {@code ServiceReference} if
@@ -708,34 +460,6 @@ public class ServiceTracker<S, T> {
 		}
 	}
 
-	/**
-	 * Returns a service object for one of the services being tracked by this
-	 * {@code ServiceTracker}.
-	 * 
-	 * <p>
-	 * If any services are being tracked, this implementation returns the result
-	 * of calling {@code getService(getServiceReference())}.
-	 * 
-	 * @return A service object or {@code null} if no services are being
-	 *         tracked.
-	 */
-	public T getService() {
-		T service = cachedService;
-		if (service != null) {
-			if (DEBUG) {
-				System.out.println("ServiceTracker.getService[cached]: " + filter);
-			}
-			return service;
-		}
-		if (DEBUG) {
-			System.out.println("ServiceTracker.getService: " + filter);
-		}
-		ServiceReference<S> reference = getServiceReference();
-		if (reference == null) {
-			return null;
-		}
-		return cachedService = getService(reference);
-	}
 
 	/**
 	 * Remove a service from this {@code ServiceTracker}.
@@ -810,10 +534,8 @@ public class ServiceTracker<S, T> {
 	 * between the listener thread and the user thread.
 	 */
 	void modified() {
-		cachedReference = null; /* clear cached value */
-		cachedService = null; /* clear cached value */
 		if (DEBUG) {
-			System.out.println("ServiceTracker.modified: " + filter);
+			System.out.println("ServiceTracker.modified: " + eventFilter);
 		}
 	}
 
@@ -1106,11 +828,12 @@ public class ServiceTracker<S, T> {
                 if (DEBUG) {
                     System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
                 }
-                trackAdding(item, null); /*
-                                         * Begin tracking it. We call trackAdding
-                                         * since we have already put the item in the
-                                         * adding list.
-                                         */
+                /*
+                 * Begin tracking it. We call trackAdding
+                 * since we have already put the item in the
+                 * adding list.
+                 */
+                trackAdding(item, null); 
             }
         }
 
@@ -1410,7 +1133,7 @@ public class ServiceTracker<S, T> {
 	 * 
 	 * @ThreadSafe
 	 */
-	private class Tracked extends AbstractTracked<ServiceReference<S>, T, ServiceEvent>
implements ServiceListener {
+	private class Tracked extends AbstractTracked<ServiceReference<S>, T, U> implements
ExtendedServiceListener<U> {
 		/**
 		 * Tracked constructor.
          * @param trackingCount
@@ -1425,7 +1148,7 @@ public class ServiceTracker<S, T> {
 		 * 
 		 * @param event {@code ServiceEvent} object from the framework.
 		 */
-		final public void serviceChanged(final ServiceEvent event) {
+		final public void serviceChanged(final U event) {
 			/*
 			 * Check if we had a delayed call (which could happen when we
 			 * close).
@@ -1484,12 +1207,12 @@ public class ServiceTracker<S, T> {
          * @return Customized object for the tracked item or {@code null} if the
 		 *         item is not to be tracked.
 		 */
-		final T customizerAdding( final ServiceReference<S> item, final ServiceEvent related
) {
+		final T customizerAdding( final ServiceReference<S> item, final U related ) {
 			return customizer.addingService( item );
 		}
 
-		final void customizerAdded( final ServiceReference<S> item, final ServiceEvent related,
final T object, int trackingCount, int serviceCount ) {
-		    customizer.addedService( item, object, trackingCount, serviceCount );
+		final void customizerAdded( final ServiceReference<S> item, final U related, final
T object, int trackingCount, int serviceCount ) {
+		    customizer.addedService( item, object, trackingCount, serviceCount, related );
 		}
 
 		/**
@@ -1501,8 +1224,8 @@ public class ServiceTracker<S, T> {
          * @param object Customized object for the tracked item.
          * @param trackingCount
          */
-		final void customizerModified( final ServiceReference<S> item, final ServiceEvent
related, final T object, int trackingCount ) {
-			customizer.modifiedService( item, object, trackingCount );
+		final void customizerModified( final ServiceReference<S> item, final U related, final
T object, int trackingCount ) {
+			customizer.modifiedService( item, object, trackingCount, related );
 		}
 
         /**
@@ -1514,8 +1237,8 @@ public class ServiceTracker<S, T> {
          * @param object Customized object for the tracked item.
          * @param trackingCount
          */
-		final void customizerRemoved( final ServiceReference<S> item, final ServiceEvent
related, final T object, int trackingCount ) {
-			customizer.removedService(item, object, trackingCount );
+		final void customizerRemoved( final ServiceReference<S> item, final U related, final
T object, int trackingCount ) {
+			customizer.removedService(item, object, trackingCount, related );
 		}
 	}
 
@@ -1526,13 +1249,13 @@ public class ServiceTracker<S, T> {
 	 * @since 1.3
 	 * @ThreadSafe
 	 */
-	private class AllTracked extends Tracked implements AllServiceListener {
-		/**
-		 * AllTracked constructor.
-         * @param trackingCount
-         */
-		AllTracked( AtomicInteger trackingCount ) {
-			super( trackingCount );
-		}
-	}
+//	private class AllTracked extends Tracked<U> implements AllServiceListener {
+//		/**
+//		 * AllTracked constructor.
+//         * @param trackingCount
+//         */
+//		AllTracked( AtomicInteger trackingCount ) {
+//			super( trackingCount );
+//		}
+//	}
 }

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
Mon Jul 27 22:01:59 2015
@@ -16,6 +16,7 @@
 
 package org.apache.felix.scr.impl.manager;
 
+import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -47,7 +48,7 @@ import org.osgi.framework.ServiceReferen
  * @ThreadSafe
  * @version $Id: c14b8d47026b6bd4ba1f2db7bf7e755d00fc6f6a $
  */
-public interface ServiceTrackerCustomizer<S, T> {
+public interface ServiceTrackerCustomizer<S, T, U extends ServiceEvent> {
 	/**
 	 * A service is being added to the {@code ServiceTracker}.
 	 * 
@@ -69,7 +70,7 @@ public interface ServiceTrackerCustomize
 	 */
 	public T addingService( ServiceReference<S> reference );
 
-    public void addedService( ServiceReference<S> reference, T service, int trackingCount,
int serviceCount );
+    public void addedService( ServiceReference<S> reference, T service, int trackingCount,
int serviceCount, U event );
 
 	/**
 	 * A service tracked by the {@code ServiceTracker} has been modified.
@@ -79,10 +80,11 @@ public interface ServiceTrackerCustomize
 	 * {@code ServiceTracker} has had it properties modified.
 	 *
      * @param reference The reference to the service that has been modified.
-     * @param service The service object for the specified referenced service.
-     * @param trackingCount
+	 * @param service The service object for the specified referenced service.
+	 * @param trackingCount
+	 * @param event TODO
      */
-	public void modifiedService( ServiceReference<S> reference, T service, int trackingCount
);
+	public void modifiedService( ServiceReference<S> reference, T service, int trackingCount,
U event );
 
 	/**
 	 * A service tracked by the {@code ServiceTracker} has been removed.
@@ -94,7 +96,8 @@ public interface ServiceTrackerCustomize
      * @param reference The reference to the service that has been removed.
 	 * @param service The service object for the specified referenced service.
 	 * @param trackingCount
+	 * @param event TODO
      */
-	public void removedService( ServiceReference<S> reference, T service, int trackingCount
);
+	public void removedService( ServiceReference<S> reference, T service, int trackingCount,
U event );
 
 }

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/SingleComponentManager.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/SingleComponentManager.java
Mon Jul 27 22:01:59 2015
@@ -372,14 +372,15 @@ public class SingleComponentManager<S> e
     }
 
     @Override
-    <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager,
RefPair<S, T> refPair, int trackingCount )
+    <T> boolean invokeUpdatedMethod( DependencyManager<S, T> dependencyManager,
RefPair<S, T> refPair, int trackingCount )
     {
-        ComponentContextImpl<S> componentContext = m_componentContext;
+        final ComponentContextImpl<S> componentContext = m_componentContext;
         if ( componentContext != null )
         {
-            EdgeInfo info = componentContext.getEdgeInfo( dependencyManager );
-            dependencyManager.invokeUpdatedMethod( componentContext, refPair, trackingCount,
info );
+            final EdgeInfo info = componentContext.getEdgeInfo( dependencyManager );
+            return dependencyManager.invokeUpdatedMethod( componentContext, refPair, trackingCount,
info );
         }
+        return false;
     }
 
     @Override
@@ -449,7 +450,7 @@ public class SingleComponentManager<S> e
                 	{
                 		servicePids.addAll((List)configPropServicePids);
                 	}
-                	else 
+                	else
                 	{
                 		servicePids.add(configPropServicePids.toString());
                 	}
@@ -457,7 +458,7 @@ public class SingleComponentManager<S> e
                     {
                         servicePids.add((String)m_factoryProperties.get(Constants.SERVICE_PID));
                     }
-                    
+
                 	if ( servicePids.size() == 1 )
                 	{
                 		props.put(Constants.SERVICE_PID, servicePids.get(0));
@@ -594,7 +595,7 @@ public class SingleComponentManager<S> e
                     log( LogService.LOG_DEBUG, "Attempting to activate unsatisfied component",
null );
                     updateTargets( getProperties() );
                     releaseActivationWriteeLock( "reconfigure.unsatisfied" );
-                    activateInternal( getTrackingCount().get() );
+                    activateInternal( );
                     return;
                 }
 
@@ -623,7 +624,7 @@ public class SingleComponentManager<S> e
                         {
                             releaseActivationWriteeLock("reconfigure.deactivate.activate");
                         }
-                        activateInternal(getTrackingCount().get());
+                        activateInternal();
                     }
                 }
             }
@@ -760,10 +761,11 @@ public class SingleComponentManager<S> e
     public S getService( Bundle bundle, ServiceRegistration<S> serviceRegistration
)
     {
         boolean success = getServiceInternal();
-        if ( success )
+        ComponentContextImpl<S> componentContext = m_componentContext;
+        if ( success && componentContext != null)
         {
             m_useCount.incrementAndGet();
-            return m_componentContext.getImplementationObject( true );
+            return componentContext.getImplementationObject( true );
         }
         else
         {
@@ -897,7 +899,7 @@ public class SingleComponentManager<S> e
         }
     }
 
-    void ungetService( )
+    private void ungetService( )
     {
         deleteComponent( ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED );
     }

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
Mon Jul 27 22:01:59 2015
@@ -721,15 +721,6 @@ public class ReferenceMetadata
                     throw componentMetadata.validationFailure( "Field value type must be
one of " + FIELD_VALUE_TYPE_VALID );
                 }
             }
-
-            // static references only allow replace strategy
-            if ( m_isStatic )
-            {
-                if ( ! m_field_option.equals(FIELD_STRATEGY_REPLACE) )
-                {
-                    throw componentMetadata.validationFailure( "Field strategy update not
allowed for static field references." );
-                }
-            }
         }
 
         m_validated = true;

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/AnnotationTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/AnnotationTest.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/AnnotationTest.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/AnnotationTest.java
Mon Jul 27 22:01:59 2015
@@ -56,6 +56,7 @@ public class AnnotationTest extends Test
     public @interface A1 {
         boolean bool();
         byte byt();
+        char cha();
         Class<?> clas();
         E1 e1();
         double doubl();
@@ -90,6 +91,7 @@ public class AnnotationTest extends Test
     {
         assertEquals(true, a.bool());
         assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
         assertEquals(String.class, a.clas());
         assertEquals(E1.a, a.e1());
         assertEquals(3.14d, a.doubl());
@@ -122,9 +124,10 @@ public class AnnotationTest extends Test
 
     private Map<String, Object> allValues()
     {
-        Map<String, Object> values = new HashMap();
+        Map<String, Object> values = new HashMap<String, Object>();
         values.put("bool", "true");
         values.put("byt", 12l);
+        values.put("cha", 'c');
         values.put("clas", String.class.getName());
         values.put("e1", E1.a.toString());
         values.put("doubl", "3.14");
@@ -146,6 +149,7 @@ public class AnnotationTest extends Test
         A1 a = (A1) o;
         assertEquals(false, a.bool());
         assertEquals((byte)0, a.byt());
+        assertEquals((char)0, a.cha());
         assertEquals(null, a.clas());
         assertEquals(null, a.e1());
         assertEquals(0d, a.doubl());
@@ -159,6 +163,7 @@ public class AnnotationTest extends Test
     public @interface A2 {
         boolean bool() default true;
         byte byt() default 5;
+        char cha() default 'a';
         Class<?> clas() default Integer.class;
         E1 e1() default E1.b;
         double doubl() default -2;
@@ -179,6 +184,7 @@ public class AnnotationTest extends Test
         A2 a = (A2) o;
         assertEquals(true, a.bool());
         assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
         assertEquals(String.class, a.clas());
         assertEquals(E1.a, a.e1());
         assertEquals(3.14d, a.doubl());
@@ -192,6 +198,7 @@ public class AnnotationTest extends Test
     public @interface A1Arrays {
         boolean[] bool();
         byte[] byt();
+        char[] cha();
         Class<?>[] clas();
         E1[] e1();
         double[] doubl();
@@ -212,6 +219,7 @@ public class AnnotationTest extends Test
         A1Arrays a = (A1Arrays) o;
         assertEquals(null, a.bool());
         assertEquals(null, a.byt());
+        assertEquals(null, a.cha());
         assertEquals(null, a.clas());
         assertEquals(null, a.e1());
         assertEquals(null, a.doubl());
@@ -232,6 +240,7 @@ public class AnnotationTest extends Test
         A1Arrays a = (A1Arrays) o;
         assertArrayEquals(new boolean[] {true}, a.bool());
         assertArrayEquals(new byte[] {(byte)12}, a.byt());
+        assertArrayEquals(new char[] {'c'}, a.cha());
         assertArrayEquals(new Class<?>[] {String.class}, a.clas());
         assertArrayEquals(new E1[] {E1.a}, a.e1());
         assertArrayEquals(new double[] {3.14d}, a.doubl());
@@ -260,6 +269,7 @@ public class AnnotationTest extends Test
         Map<String, Object> values = new HashMap();
         values.put("bool", new boolean[] {true, false});
         values.put("byt", new byte[] {12, 3});
+        values.put("cha", new char[] {'c', 'h', 'a', 'r'});
         values.put("clas", new String[] {String.class.getName(), Integer.class.getName()});
         values.put("e1", new String[] {E1.a.name(), E1.b.name()});
         values.put("doubl", new double[] {3.14, 2.78, 9});
@@ -308,6 +318,7 @@ public class AnnotationTest extends Test
         A1Arrays a = (A1Arrays) o;
         assertArrayEquals(new boolean[] {true, false}, a.bool());
         assertArrayEquals(new byte[] {12, 3}, a.byt());
+        assertArrayEquals(new char[] {'c', 'h', 'a', 'r'}, a.cha());
         assertArrayEquals(new Class<?>[] {String.class, Integer.class}, a.clas());
         assertArrayEquals(new E1[] {E1.a, E1.b}, a.e1());
         assertArrayEquals(new double[] {3.14, 2.78, 9}, a.doubl());

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/BindMethodTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/BindMethodTest.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/BindMethodTest.java
(original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/helper/BindMethodTest.java
Mon Jul 27 22:01:59 2015
@@ -450,7 +450,7 @@ public class BindMethodTest extends Test
         ComponentContainer container = newContainer();
         SingleComponentManager icm = new SingleComponentManager( container, new ComponentMethods()
);
         BindMethod bm = new BindMethod( methodName, component.getClass(),
-                FakeService.class.getName(), dsVersion, false, ReferenceMetadata.ReferenceScope.bundle
);
+                FakeService.class.getName(), dsVersion, false );
         RefPair refPair = new SingleRefPair( m_serviceReference );
         ComponentContextImpl<T1> cc = new ComponentContextImpl(icm, new MockBundle());
         assertTrue( bm.getServiceObject( cc, refPair, m_context, icm ) );

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java?rev=1692966&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
(added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/test/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
Mon Jul 27 22:01:59 2015
@@ -0,0 +1,106 @@
+/*
+ * 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.felix.scr.impl.manager;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.felix.scr.impl.config.ComponentContainer;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class SingleComponentManagerTest
+{
+    @Test
+    public void testGetService() throws Exception {
+        ComponentMetadata cm = new ComponentMetadata(DSVersion.DS13);
+        cm.setImplementationClassName("foo.bar.SomeClass");
+        cm.validate(null);
+
+        @SuppressWarnings("unchecked")
+        ComponentContainer<Object> cc = Mockito.mock(ComponentContainer.class);
+        Mockito.when(cc.getComponentMetadata()).thenReturn(cm);
+
+        SingleComponentManager<Object> scm = new SingleComponentManager<Object>(cc,
new ComponentMethods()) {
+            @Override
+            boolean getServiceInternal()
+            {
+                return true;
+            }
+        };
+
+        BundleContext bc = Mockito.mock(BundleContext.class);
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.getBundleContext()).thenReturn(bc);
+
+        ComponentContextImpl<Object> cci = new ComponentContextImpl<Object>(scm,
b);
+        Object implObj = new Object();
+        cci.setImplementationObject(implObj);
+        cci.setImplementationAccessible(true);
+
+        Field f = SingleComponentManager.class.getDeclaredField("m_componentContext");
+        f.setAccessible(true);
+        f.set(scm, cci);
+
+        scm.m_internalEnabled = true;
+        assertSame(implObj, scm.getService(null, null));
+
+        Field u = SingleComponentManager.class.getDeclaredField("m_useCount");
+        u.setAccessible(true);
+        AtomicInteger use = (AtomicInteger) u.get(scm);
+        assertEquals(1, use.get());
+    }
+
+    @Test
+    public void testGetServiceWithNullComponentContext() throws Exception
+    {
+        ComponentMetadata cm = new ComponentMetadata(DSVersion.DS13);
+        cm.setImplementationClassName("foo.bar.SomeClass");
+        cm.validate(null);
+
+        @SuppressWarnings("unchecked")
+        ComponentContainer<Object> cc = Mockito.mock(ComponentContainer.class);
+        Mockito.when(cc.getComponentMetadata()).thenReturn(cm);
+
+        SingleComponentManager<?> scm = new SingleComponentManager<Object>(cc,
new ComponentMethods()) {
+            @Override
+            boolean getServiceInternal()
+            {
+                return true;
+            }
+        };
+        scm.m_internalEnabled = true;
+        assertNull("m_componentContext is null, this should not cause an NPE",
+                scm.getService(null, null));
+
+        Field u = SingleComponentManager.class.getDeclaredField("m_useCount");
+        u.setAccessible(true);
+        AtomicInteger use = (AtomicInteger) u.get(scm);
+        assertEquals(0, use.get());
+    }
+}



Mime
View raw message