Commit patch to fix some issues with service registry hooks that were
causing them to fail the TCK. (FELIX-1277)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@799087 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index d141c5b..ced9680 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2586,22 +2586,34 @@
void addServiceListener(Bundle bundle, ServiceListener l, String f)
throws InvalidSyntaxException
{
- m_dispatcher.addListener(
+ Filter oldFilter = m_dispatcher.addListener(
bundle, ServiceListener.class, l, (f == null) ? null : FrameworkUtil.createFilter(f));
- // Invoke the ListenerHook.added() on all hooks.
List listenerHooks = m_registry.getListenerHooks();
- final Collection c = Collections.singleton(
- new ListenerHookInfoImpl(bundle.getBundleContext(), f));
+ if (oldFilter != null)
+ {
+ final Collection removed = Collections.singleton(
+ new ListenerHookInfoImpl(bundle.getBundleContext(), l, oldFilter.toString(), true));
+ InvokeHookCallback removedCallback = new ListenerHookRemovedCallback(removed);
+ for (int i = 0; i < listenerHooks.size(); i++)
+ {
+ m_registry.invokeHook((ServiceReference) listenerHooks.get(i), this, removedCallback);
+ };
+ }
+
+ // Invoke the ListenerHook.added() on all hooks.
+ final Collection added = Collections.singleton(
+ new ListenerHookInfoImpl(bundle.getBundleContext(), l, f, false));
+ InvokeHookCallback addedCallback = new InvokeHookCallback()
+ {
+ public void invokeHook(Object hook)
+ {
+ ((ListenerHook) hook).added(added);
+ }
+ };
for (int i = 0; i < listenerHooks.size(); i++)
{
- ServiceRegistry.invokeHook(listenerHooks.get(i), this, new InvokeHookCallback()
- {
- public void invokeHook(Object hook)
- {
- ((ListenerHook) hook).added(c);
- }
- });
+ m_registry.invokeHook((ServiceReference) listenerHooks.get(i), this, addedCallback);
}
}
@@ -2622,9 +2634,10 @@
// Invoke the ListenerHook.removed() on all hooks.
List listenerHooks = m_registry.getListenerHooks();
Collection c = Collections.singleton(listener);
+ InvokeHookCallback callback = new ListenerHookRemovedCallback(c);
for (int i = 0; i < listenerHooks.size(); i++)
{
- ((ListenerHook) listenerHooks.get(i)).removed(c);
+ m_registry.invokeHook((ServiceReference) listenerHooks.get(i), this, callback);
}
}
}
@@ -2719,13 +2732,12 @@
// to invoke the callback with all existing service listeners.
if (m_registry.isHook(classNames, ListenerHook.class, svcObj))
{
- Object hookRef = ServiceRegistry.getHookRef(svcObj, reg);
- ServiceRegistry.invokeHook(hookRef, this, new InvokeHookCallback()
+ m_registry.invokeHook(reg.getReference(), this, new InvokeHookCallback()
{
public void invokeHook(Object hook)
{
((ListenerHook) hook).
- added(m_dispatcher.wrapAllServiceListeners());
+ added(m_dispatcher.wrapAllServiceListeners(false));
}
});
}
@@ -2784,19 +2796,20 @@
// activate findhooks
List findHooks = m_registry.getFindHooks();
+ InvokeHookCallback callback = new InvokeHookCallback()
+ {
+ public void invokeHook(Object hook)
+ {
+ ((FindHook) hook).find(bundle.getBundleContext(),
+ className,
+ expr,
+ !checkAssignable,
+ new ShrinkableCollection(refList));
+ }
+ };
for (int i = 0; i < findHooks.size(); i++)
{
- ServiceRegistry.invokeHook(findHooks.get(i), this, new InvokeHookCallback()
- {
- public void invokeHook(Object hook)
- {
- ((FindHook) hook).find(bundle.getBundleContext(),
- className,
- expr,
- !checkAssignable,
- new ShrinkableCollection(refList));
- }
- });
+ m_registry.invokeHook((ServiceReference) findHooks.get(i), this, callback);
}
if (refList.size() > 0)
@@ -4297,6 +4310,21 @@
}
}
+ private static class ListenerHookRemovedCallback implements InvokeHookCallback
+ {
+ private final Collection /* ListenerHookInfo */ m_removed;
+
+ ListenerHookRemovedCallback(Collection /* ListenerHookInfo */ removed)
+ {
+ m_removed = removed;
+ }
+
+ public void invokeHook(Object hook)
+ {
+ ((ListenerHook) hook).removed(m_removed);
+ }
+ }
+
//
// Locking related methods.
//
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 8e2b055..ddd4e53 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -367,7 +367,7 @@
{
private ServiceReferenceImpl() {}
- ServiceRegistrationImpl getServiceRegistration()
+ ServiceRegistrationImpl getRegistration()
{
return ServiceRegistrationImpl.this;
}
@@ -465,7 +465,7 @@
// Get the service registration and ask it to check
// if the service object is assignable to the requesting
// bundle's class.
- allow = getServiceRegistration().isClassAccessible(requestClass);
+ allow = getRegistration().isClassAccessible(requestClass);
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index ce09d85..413e331 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -27,7 +27,7 @@
public class ServiceRegistry
{
- private Logger m_logger = null;
+ private final Logger m_logger;
private long m_currentServiceId = 1L;
// Maps bundle to an array of service registrations.
private Map m_serviceRegsMap = new HashMap();
@@ -40,12 +40,9 @@
private final ServiceRegistryCallbacks m_callbacks;
- private final Object m_eventHookLock = new Object();
- private Object[] m_eventHooks = new Object[0];
- private final Object m_findHookLock = new Object();
- private Object[] m_findHooks = new Object[0];
- private final Object m_listenerHookLock = new Object();
- private Object[] m_listenerHooks = new Object[0];
+ private final Set m_eventHooks = new TreeSet(Collections.reverseOrder());
+ private final Set m_findHooks = new TreeSet(Collections.reverseOrder());
+ private final Set m_listenerHooks = new TreeSet(Collections.reverseOrder());
public ServiceRegistry(Logger logger, ServiceRegistryCallbacks callbacks)
{
@@ -78,9 +75,9 @@
// Create the service registration.
reg = new ServiceRegistrationImpl(
this, bundle, classNames, new Long(m_currentServiceId++), svcObj, dict);
-
+
// Keep track of registered hooks.
- addHooks(classNames, svcObj, reg);
+ addHooks(classNames, svcObj, reg.getReference());
// Get the bundles current registered services.
ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
@@ -99,7 +96,7 @@
public void unregisterService(Bundle bundle, ServiceRegistration reg)
{
// If this is a hook, it should be removed.
- removeHook(reg);
+ removeHook(reg.getReference());
synchronized (this)
{
@@ -202,7 +199,8 @@
else if (className != null)
{
String[] objectClass = (String[])
- ((ServiceRegistrationImpl) regs[regIdx]).getProperty(FelixConstants.OBJECTCLASS);
+ ((ServiceRegistrationImpl) regs[regIdx])
+ .getProperty(FelixConstants.OBJECTCLASS);
for (int classIdx = 0;
classIdx < objectClass.length;
classIdx++)
@@ -248,7 +246,8 @@
Object svcObj = null;
// Get the service registration.
- ServiceRegistrationImpl reg = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getServiceRegistration();
+ ServiceRegistrationImpl reg =
+ ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
synchronized (this)
{
@@ -338,7 +337,8 @@
public boolean ungetService(Bundle bundle, ServiceReference ref)
{
UsageCount usage = null;
- ServiceRegistrationImpl reg = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getServiceRegistration();
+ ServiceRegistrationImpl reg =
+ ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
synchronized (this)
{
@@ -384,7 +384,7 @@
{
// Remove reference from usages array.
((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
- .getServiceRegistration().ungetService(bundle, usage.m_svcObj);
+ .getRegistration().ungetService(bundle, usage.m_svcObj);
}
}
finally
@@ -454,7 +454,7 @@
}
public synchronized Bundle[] getUsingBundles(ServiceReference ref)
- {
+ {
Bundle[] bundles = null;
for (Iterator iter = m_inUseMap.entrySet().iterator(); iter.hasNext(); )
{
@@ -646,50 +646,40 @@
}
}
- private void addHooks(String[] classNames, Object svcObj, ServiceRegistration reg)
+ private void addHooks(String[] classNames, Object svcObj, ServiceReference ref)
{
if (isHook(classNames, EventHook.class, svcObj))
{
- synchronized (m_eventHookLock)
+ synchronized (m_eventHooks)
{
- m_eventHooks = addHookToArray(m_eventHooks, svcObj, reg);
+ m_eventHooks.add(ref);
}
}
if (isHook(classNames, FindHook.class, svcObj))
{
- synchronized (m_findHookLock)
+ synchronized (m_findHooks)
{
- m_findHooks = addHookToArray(m_findHooks, svcObj, reg);
+ m_findHooks.add(ref);
}
}
if (isHook(classNames, ListenerHook.class, svcObj))
{
- synchronized (m_listenerHookLock)
+ synchronized (m_listenerHooks)
{
- m_listenerHooks = addHookToArray(m_listenerHooks, svcObj, reg);
+ m_listenerHooks.add(ref);
}
}
}
-
- private static Object[] addHookToArray(Object[] src, Object svcObj, ServiceRegistration reg)
+
+ static boolean isHook(String[] classNames, Class hookClass, Object svcObj)
{
- Object hookRef = getHookRef(svcObj, reg);
-
- Object[] dst = new Object[src.length + 1];
- System.arraycopy(src, 0, dst, 0, src.length);
- dst[src.length] = hookRef;
- return dst;
- }
-
- boolean isHook(String[] classNames, Class hookClass, Object svcObj)
- {
- if (svcObj instanceof ServiceFactory)
+ if (svcObj instanceof ServiceFactory)
{
return Arrays.asList(classNames).contains(hookClass.getName());
}
-
+
if (hookClass.isAssignableFrom(svcObj.getClass()))
{
String hookName = hookClass.getName();
@@ -704,96 +694,42 @@
return false;
}
- private void removeHook(ServiceRegistration reg)
+ private void removeHook(ServiceReference ref)
{
- Object svcObj = ((ServiceRegistrationImpl) reg).getService();
- String [] classNames = (String[]) reg.getReference().getProperty(Constants.OBJECTCLASS);
-
- if (isHook(classNames, EventHook.class, svcObj))
+ Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
+ .getRegistration().getService();
+ String [] classNames = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+
+ if (isHook(classNames, EventHook.class, svcObj))
{
- synchronized (m_eventHookLock)
+ synchronized (m_eventHooks)
{
- m_eventHooks = removeFromHookArray(m_eventHooks, svcObj, reg);
+ m_eventHooks.remove(ref);
}
}
-
- if (isHook(classNames, FindHook.class, svcObj))
+
+ if (isHook(classNames, FindHook.class, svcObj))
{
- synchronized (m_findHookLock)
+ synchronized (m_findHooks)
{
- m_findHooks = removeFromHookArray(m_findHooks, svcObj, reg);
+ m_findHooks.remove(ref);
}
}
if (isHook(classNames, ListenerHook.class, svcObj))
{
- synchronized (m_listenerHookLock)
+ synchronized (m_listenerHooks)
{
- m_listenerHooks = removeFromHookArray(m_listenerHooks, svcObj, reg);
+ m_listenerHooks.remove(ref);
}
}
}
- private static Object[] removeFromHookArray(Object[] src, Object svcObj, ServiceRegistration reg)
- {
- Object[] dst = src;
-
- int idx = -1;
- for (int i = 0; i < src.length; i++)
- {
- boolean found = false;
- if (svcObj instanceof ServiceFactory)
- {
- if (src[i] instanceof Object[])
- {
- Object [] arrElem = (Object []) src[i];
- if (arrElem[0].equals(svcObj) && arrElem[1].equals(reg))
- {
- found = true;
- }
- }
- }
- else
- {
- if (src[i].equals(svcObj))
- {
- found = true;
- }
- }
-
- if (found)
- {
- idx = i;
- break;
- }
- }
-
- if (idx >= 0)
- {
- if (src.length == 1)
- {
- dst = new Object[0];
- }
- else
- {
- dst = new Object[src.length - 1];
- System.arraycopy(dst, 0, src, 0, idx);
- if (idx < dst.length)
- {
- System.arraycopy(
- src, idx + 1, dst, idx, dst.length - idx);
- }
- }
- }
-
- return dst;
- }
-
public List getEventHooks()
{
synchronized (m_eventHooks)
{
- return Collections.unmodifiableList(Arrays.asList(m_eventHooks));
+ return new ArrayList(m_eventHooks);
}
}
@@ -801,7 +737,7 @@
{
synchronized (m_findHooks)
{
- return Collections.unmodifiableList(Arrays.asList(m_findHooks));
+ return new ArrayList(m_findHooks);
}
}
@@ -809,80 +745,38 @@
{
synchronized (m_listenerHooks)
{
- return Collections.unmodifiableList(Arrays.asList(m_listenerHooks));
+ return new ArrayList(m_listenerHooks);
}
}
-
- /**
- * Returns a hook reference object that can be passed to the
- * {@link #invokeHook(Object, Framework, InvokeHookCallback)} method.
- * @param svcObj The Service Object. Either the service itself, or a <tt>ServiceFactory</tt>
- * object.
- * @param reg The associated <tt>ServiceRegistration</tt>.
- * @return In the case of a <tt>ServiceFactory</tt> an Object[2] with both the
- * factory and the <tt>ServiceRegistration</tt> is returned. In all other
- * cases the svcObj is returned as passed in. This is the behavior expected
- * by the {@link #invokeHook(Object, Framework, InvokeHookCallback)} method.
- */
- static Object getHookRef(Object svcObj, ServiceRegistration reg)
- {
- if (svcObj instanceof ServiceFactory)
- {
- return new Object[] {svcObj, reg};
- }
- else
- {
- return svcObj;
- }
- }
-
+
/**
* Invokes a Service Registry Hook
- * @param hookRef The hook to be invoked, this is an element on the list returned by the
- * {@link #getEventHooks()}, {@link #getFindHooks()} or {@link #getListenerHooks()}
- * methods. It could either contain the hook object itself or an Object[2] when a
- * ServiceFactory is used. In that case the first element is the hook ServiceFactory
- * and the second element is its ServiceRegistration.
+ * @param ref The ServiceReference associated with the hook to be invoked, the hook
+ * service object will be obtained through this object.
* @param framework The framework that is invoking the hook, typically the Felix object.
- * @param callback This is a callback object that is invoked with the actual hook object to
+ * @param callback This is a callback object that is invoked with the actual hook object to
* be used, either the plain hook, or one obtained from the ServiceFactory.
*/
- public static void invokeHook(
- Object hookRef, Framework framework, InvokeHookCallback callback)
+ public void invokeHook(
+ ServiceReference ref, Framework framework, InvokeHookCallback callback)
{
- Object hook;
- boolean serviceFactory;
- if (hookRef instanceof Object[])
- {
- serviceFactory = true;
- Object[] array = (Object[]) hookRef;
- ServiceFactory hookFactory = (ServiceFactory) array[0];
- ServiceRegistration sr = (ServiceRegistration) array[1];
- hook = hookFactory.getService(framework, sr);
- }
- else
- {
- serviceFactory = false;
- hook = hookRef;
- }
-
- try
+ Object hook = getService(framework, ref);
+
+ try
{
callback.invokeHook(hook);
- // TODO: SERVICE HOOKS - Check that "services in use" is handled
}
- finally
+ catch (Throwable th)
{
- if (serviceFactory)
- {
- Object [] array = (Object []) hookRef;
- ServiceFactory hookFactory = (ServiceFactory) array[0];
- ServiceRegistration sr = (ServiceRegistration) array[1];
- hookFactory.ungetService(framework, sr, hook);
- }
+ m_logger.log(ref, Logger.LOG_WARNING,
+ "Problem invoking Service Registry Hook", th);
}
- }
-
+ finally
+ {
+ ungetService(framework, ref);
+ }
+ }
+
private static class UsageCount
{
public int m_count = 0;
@@ -894,4 +788,21 @@
{
void serviceChanged(ServiceEvent event, Dictionary oldProps);
}
+
+ private static class ServiceRankingComparator implements Comparator
+ {
+ public int compare(Object o1, Object o2)
+ {
+ if (!(o1 instanceof ServiceRegistration) ||
+ !(o2 instanceof ServiceRegistration))
+ {
+ return 0;
+ }
+
+ ServiceReference r1 = ((ServiceRegistration) o1).getReference();
+ ServiceReference r2 = ((ServiceRegistration) o2).getReference();
+
+ return -r1.compareTo(r2);
+ }
+ }
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index a74f0b9..4d45b5d 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -45,6 +45,7 @@
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServicePermission;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.SynchronousBundleListener;
import org.osgi.framework.hooks.service.EventHook;
import org.osgi.framework.hooks.service.ListenerHook;
@@ -175,7 +176,7 @@
}
}
- public void addListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
+ public Filter addListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
{
// Verify the listener.
if (l == null)
@@ -190,9 +191,10 @@
// See if we can simply update the listener, if so then
// return immediately.
- if (updateListener(bundle, clazz, l, filter))
+ Filter oldFilter = updateListener(bundle, clazz, l, filter);
+ if (oldFilter != null)
{
- return;
+ return oldFilter;
}
// Lock the object to add the listener.
@@ -282,8 +284,9 @@
m_serviceListeners = listeners;
}
}
+ return null;
}
-
+
public ListenerHook.ListenerInfo removeListener(
Bundle bundle, Class clazz, EventListener l)
{
@@ -341,7 +344,7 @@
// the listener for the ListenerHook callback.
if (ServiceListener.class == clazz)
{
- listenerInfo = wrapListener(listeners, i);
+ listenerInfo = wrapListener(listeners, i, true);
}
idx = i;
break;
@@ -481,7 +484,7 @@
}
}
- public boolean updateListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
+ public Filter updateListener(Bundle bundle, Class clazz, EventListener l, Filter filter)
{
synchronized (this)
{
@@ -515,6 +518,7 @@
(listeners[i + LISTENER_CLASS_OFFSET] == clazz) &&
(listeners[i + LISTENER_OBJECT_OFFSET] == l))
{
+ Filter oldFilter = null;
if (clazz == FrameworkListener.class)
{
// The spec says to ignore this case.
@@ -526,14 +530,15 @@
else if (clazz == ServiceListener.class)
{
// The spec says to update the filter in this case.
+ oldFilter = (Filter) listeners[i + LISTENER_FILTER_OFFSET];
listeners[i + LISTENER_FILTER_OFFSET] = filter;
}
- return true;
+ return oldFilter;
}
}
}
- return false;
+ return null;
}
/**
@@ -543,7 +548,7 @@
* @return Returns all existing service listener information into a collection of
* ListenerHook.ListenerInfo objects
**/
- public Collection /* <? extends ListenerHook.ListenerInfo> */ wrapAllServiceListeners()
+ public Collection /* <? extends ListenerHook.ListenerInfo> */ wrapAllServiceListeners(boolean removed)
{
Object[] listeners = null;
synchronized (this)
@@ -554,7 +559,7 @@
List existingListeners = new ArrayList();
for (int i = 0, j = 0; i < listeners.length; i += LISTENER_ARRAY_INCREMENT, j++)
{
- existingListeners.add(wrapListener(listeners, i));
+ existingListeners.add(wrapListener(listeners, i, removed));
}
return existingListeners;
}
@@ -566,13 +571,15 @@
* @param offset The offset into the array of the listener to wrap.
* @return A ListenerHook.ListenerInfo object for the specified listener.
*/
- private static ListenerHook.ListenerInfo wrapListener(Object[] listeners, int offset)
+ private static ListenerHook.ListenerInfo wrapListener(Object[] listeners, int offset, boolean removed)
{
Filter filter = ((Filter)listeners[offset + LISTENER_FILTER_OFFSET]);
return new ListenerHookInfoImpl(
((Bundle)listeners[offset + LISTENER_BUNDLE_OFFSET]).getBundleContext(),
- filter == null ? null : filter.toString());
+ (ServiceListener) listeners[offset + LISTENER_OBJECT_OFFSET],
+ filter == null ? null : filter.toString(),
+ removed);
}
public void fireFrameworkEvent(FrameworkEvent event)
@@ -631,17 +638,19 @@
{
final ListenerBundleContextCollectionWrapper wrapper =
new ListenerBundleContextCollectionWrapper(listeners);
+ InvokeHookCallback callback = new InvokeHookCallback()
+ {
+ public void invokeHook(Object hook)
+ {
+ ((EventHook) hook).event(event, wrapper);
+ }
+ };
for (int i = 0; i < eventHooks.size(); i++)
{
- if (felix != null)
+ if (felix != null)
{
- ServiceRegistry.invokeHook(eventHooks.get(i), felix, new InvokeHookCallback()
- {
- public void invokeHook(Object hook)
- {
- ((EventHook) hook).event(event, wrapper);
- }
- });
+ m_serviceRegistry.invokeHook(
+ (ServiceReference) eventHooks.get(i), felix, callback);
}
}
@@ -1164,4 +1173,4 @@
public Object[] m_listeners = null;
public EventObject m_event = null;
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ListenerHookInfoImpl.java b/framework/src/main/java/org/apache/felix/framework/util/ListenerHookInfoImpl.java
index 5f034cc..fbd3704 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/ListenerHookInfoImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/ListenerHookInfoImpl.java
@@ -19,17 +19,22 @@
package org.apache.felix.framework.util;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceListener;
import org.osgi.framework.hooks.service.ListenerHook;
public class ListenerHookInfoImpl implements ListenerHook.ListenerInfo
{
private final BundleContext m_context;
+ private final ServiceListener m_listener;
private final String m_filter;
+ private boolean m_removed;
- public ListenerHookInfoImpl(BundleContext context, String filter)
+ public ListenerHookInfoImpl(BundleContext context, ServiceListener listener, String filter, boolean removed)
{
m_context = context;
+ m_listener = listener;
m_filter = filter;
+ m_removed = removed;
}
public BundleContext getBundleContext()
@@ -44,6 +49,35 @@
public boolean isRemoved()
{
- throw new UnsupportedOperationException("Not supported yet.");
+ return m_removed;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof ListenerHookInfoImpl))
+ {
+ return false;
+ }
+
+ ListenerHookInfoImpl other = (ListenerHookInfoImpl) obj;
+ return other.m_listener == m_listener &&
+ (m_filter == null ? other.m_filter == null : m_filter.equals(other.m_filter));
+ }
+
+ public int hashCode()
+ {
+ int rc = 17;
+
+ rc = 37 * rc + m_listener.hashCode();
+ if (m_filter != null)
+ {
+ rc = 37 * rc + m_filter.hashCode();
+ }
+ return rc;
}
}
\ No newline at end of file
diff --git a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
index 562da2f..7034774 100644
--- a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -19,7 +19,6 @@
package org.apache.felix.framework;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
@@ -31,6 +30,7 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.service.EventHook;
import org.osgi.framework.hooks.service.FindHook;
@@ -58,7 +58,9 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getEventHooks().size());
- assertSame(hook, sr.getEventHooks().iterator().next());
+ assertTrue(sr.getEventHooks().iterator().next() instanceof ServiceReference);
+ assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
@@ -84,10 +86,8 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getEventHooks().size());
- Object [] arr = (Object[]) sr.getEventHooks().iterator().next();
- assertEquals(2, arr.length);
- assertSame(sf, arr[0]);
- assertTrue(arr[1] instanceof ServiceRegistration);
+ assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
+ assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
@@ -117,7 +117,8 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getFindHooks().size());
- assertSame(hook, sr.getFindHooks().iterator().next());
+ assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
@@ -143,10 +144,8 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getFindHooks().size());
- Object [] arr = (Object[]) sr.getFindHooks().iterator().next();
- assertEquals(2, arr.length);
- assertSame(sf, arr[0]);
- assertTrue(arr[1] instanceof ServiceRegistration);
+ assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
+ assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
assertEquals("Postcondition failed", 0, sr.getListenerHooks().size());
@@ -179,7 +178,8 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getListenerHooks().size());
- assertSame(hook, sr.getListenerHooks().iterator().next());
+ assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
@@ -205,10 +205,8 @@
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getListenerHooks().size());
- Object [] arr = (Object[]) sr.getListenerHooks().iterator().next();
- assertEquals(2, arr.length);
- assertSame(sf, arr[0]);
- assertTrue(arr[1] instanceof ServiceRegistration);
+ assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
+ assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
assertEquals("Postcondition failed", 0, sr.getEventHooks().size());
assertEquals("Postcondition failed", 0, sr.getFindHooks().size());
@@ -260,11 +258,14 @@
FindHook.class.getName(),
EventHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getListenerHooks().size());
- assertSame(hook, sr.getListenerHooks().iterator().next());
+ assertSame(reg.getReference(), sr.getListenerHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
assertEquals(1, sr.getEventHooks().size());
- assertSame(hook, sr.getEventHooks().iterator().next());
+ assertSame(reg.getReference(), sr.getEventHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
assertEquals(1, sr.getFindHooks().size());
- assertSame(hook, sr.getFindHooks().iterator().next());
+ assertSame(reg.getReference(), sr.getFindHooks().iterator().next());
+ assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
sr.unregisterService(b, reg);
assertEquals("Should be no hooks left after unregistration", 0, sr.getEventHooks().size());
@@ -296,6 +297,8 @@
public void testInvokeHook()
{
+ ServiceRegistry sr = new ServiceRegistry(null, null);
+
final List result = new ArrayList();
InvokeHookCallback callback = new InvokeHookCallback()
{
@@ -316,16 +319,19 @@
{
}
};
- assertSame(hook, ServiceRegistry.getHookRef(hook, null));
+ ServiceRegistration reg = new ServiceRegistrationImpl(sr, null, null, null,
+ hook, new Hashtable());
assertEquals("Precondition failed", 0, result.size());
- ServiceRegistry.invokeHook(hook, fr, callback);
+ sr.invokeHook(reg.getReference(), fr, callback);
assertEquals(1, result.size());
assertSame(hook, result.iterator().next());
}
public void testInvokeHookFactory()
{
+ ServiceRegistry sr = new ServiceRegistry(null, null);
+
final List result = new ArrayList();
InvokeHookCallback callback = new InvokeHookCallback()
{
@@ -364,25 +370,19 @@
}
};
- MockControl control2 = MockControl.createNiceControl(ServiceRegistration.class);
- ServiceRegistration reg = (ServiceRegistration) control2.getMock();
- control2.replay();
-
- Object [] arg = new Object[2];
- arg[0] = sf;
- arg[1] = reg;
- Object [] arg2 = (Object[]) ServiceRegistry.getHookRef(sf, reg);
- assertTrue(Arrays.equals(arg, arg2));
+ ServiceRegistration reg = new ServiceRegistrationImpl(sr, null,
+ new String[] {FindHook.class.getName()}, null,
+ sf, new Hashtable());
assertEquals("Precondition failed", 0, result.size());
assertEquals("Precondition failed", 0, sfGet.size());
assertEquals("Precondition failed", 0, sfUnget.size());
- ServiceRegistry.invokeHook(arg, fr, callback);
+ sr.invokeHook(reg.getReference(), fr, callback);
assertEquals(1, result.size());
assertSame(hook, result.iterator().next());
assertEquals(1, sfGet.size());
assertEquals(1, sfUnget.size());
assertSame(reg, sfGet.iterator().next());
assertSame(reg, sfUnget.iterator().next());
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
index b66cff9..3dff2c5 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
@@ -19,10 +19,10 @@
package org.apache.felix.framework.util;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -78,20 +78,11 @@
};
Logger logger = new Logger();
- ServiceRegistry registry = new ServiceRegistry(logger, null)
- {
- public List getEventHooks()
- {
- return Collections.unmodifiableList(
- Arrays.asList(new EventHook[]
- {
- eh1, eh2
- }));
- }
- };
+ ServiceRegistry registry = new ServiceRegistry(logger, null);
+ registry.registerService(null, new String [] {EventHook.class.getName()}, eh1, new Hashtable());
+ registry.registerService(null, new String [] {EventHook.class.getName()}, eh2, new Hashtable());
// -- Set up event dispatcher
-
EventDispatcher ed = EventDispatcher.start(logger);
EventDispatcher.shutdown(); // stop the thread - would be nicer if we could create one without a thread for testing
ed.setServiceRegistry(registry);
@@ -181,4 +172,4 @@
return b;
}
-}
\ No newline at end of file
+}