Implemented ServiceEvent.MODIFIED_ENDMATCH. (FELIX-1244)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@785419 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 32e0abf..ee2b3ee 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -28,6 +28,7 @@
import org.apache.felix.framework.ext.SecurityProvider;
import org.apache.felix.framework.searchpolicy.*;
import org.apache.felix.framework.ModuleImpl.ModuleClassLoader;
+import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
import org.apache.felix.framework.util.*;
import org.apache.felix.framework.util.manifestparser.*;
import org.apache.felix.moduleloader.*;
@@ -616,18 +617,13 @@
m_nextId = Math.max(m_nextId, loadNextId());
// Create service registry.
- m_registry = new ServiceRegistry(m_logger);
- m_dispatcher.setServiceRegistry(m_registry);
-
- // Add a listener to the service registry; this is
- // used to distribute service registry events to
- // service listeners.
- m_registry.addServiceListener(new ServiceListener() {
- public void serviceChanged(ServiceEvent event)
+ m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
+ public void serviceChanged(ServiceEvent event, ServiceRegistration reg)
{
- fireServiceEvent(event);
+ fireServiceEvent(event, reg);
}
});
+ m_dispatcher.setServiceRegistry(m_registry);
// The framework is now in its startup sequence.
setBundleStateAndNotify(this, Bundle.STARTING);
@@ -3623,12 +3619,12 @@
/**
* Fires service events.
*
- * @param type The type of service event to fire.
- * @param ref The service reference associated with the event.
+ * @param event The service event to fire.
+ * @param reg The service registration associated with the service object.
**/
- private void fireServiceEvent(ServiceEvent event)
+ private void fireServiceEvent(ServiceEvent event, ServiceRegistration reg)
{
- m_dispatcher.fireServiceEvent(event, this);
+ m_dispatcher.fireServiceEvent(event, reg, this);
}
//
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 29f15b6..8c47b37 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -31,23 +31,23 @@
class ServiceRegistrationImpl implements ServiceRegistration
{
// Service registry.
- private ServiceRegistry m_registry = null;
+ private final ServiceRegistry m_registry;
// Bundle implementing the service.
- private Bundle m_bundle = null;
+ private final Bundle m_bundle;
// Interfaces associated with the service object.
- private String[] m_classes = null;
+ private final String[] m_classes;
// Service Id associated with the service object.
- private Long m_serviceId = null;
+ private final Long m_serviceId;
// Service object.
- private Object m_svcObj = null;
+ private volatile Object m_svcObj;
// Service factory interface.
- private ServiceFactory m_factory = null;
+ private volatile ServiceFactory m_factory;
// Associated property dictionary.
private volatile Map m_propMap = new StringMap(false);
// Re-usable service reference.
- private ServiceReferenceImpl m_ref = null;
+ private final ServiceReferenceImpl m_ref;
// Flag indicating that we are unregistering.
- private boolean m_isUnregistering = false;
+ private volatile boolean m_isUnregistering = false;
public ServiceRegistrationImpl(
ServiceRegistry registry, Bundle bundle,
@@ -82,7 +82,7 @@
m_svcObj = null;
}
- public ServiceReference getReference()
+ public synchronized ServiceReference getReference()
{
// Make sure registration is valid.
if (!isValid())
@@ -95,16 +95,24 @@
public void setProperties(Dictionary dict)
{
- // Make sure registration is valid.
- if (!isValid())
+ Map oldProps, newProps;
+ synchronized (this)
{
- throw new IllegalStateException(
- "The service registration is no longer valid.");
+ // Make sure registration is valid.
+ if (!isValid())
+ {
+ throw new IllegalStateException(
+ "The service registration is no longer valid.");
+ }
+ // Remember old properties.
+ oldProps = m_propMap;
+ // Set the properties.
+ initializeProperties(dict);
+ // Keep local reference to new properties.
+ newProps = m_propMap;
}
- // Set the properties.
- initializeProperties(dict);
// Tell registry about it.
- m_registry.servicePropertiesModified(this);
+ m_registry.servicePropertiesModified(this, oldProps, newProps);
}
public void unregister()
@@ -136,7 +144,7 @@
* @return <tt>true</tt> if the specified class is reachable from the
* service object's class loader, <tt>false</tt> otherwise.
**/
- protected boolean isClassAccessible(Class clazz)
+ private boolean isClassAccessible(Class clazz)
{
try
{
@@ -153,18 +161,18 @@
return false;
}
- protected Object getProperty(String key)
+ Object getProperty(String key)
{
return m_propMap.get(key);
}
- protected String[] getPropertyKeys()
+ private String[] getPropertyKeys()
{
Set s = m_propMap.keySet();
return (String[]) s.toArray(new String[s.size()]);
}
- protected Bundle[] getUsingBundles()
+ private Bundle[] getUsingBundles()
{
return m_registry.getUsingBundles(m_ref);
}
@@ -180,7 +188,7 @@
return m_svcObj;
}
- protected Object getService(Bundle acqBundle)
+ Object getService(Bundle acqBundle)
{
// If the service object is a service factory, then
// let it create the service object.
@@ -212,7 +220,7 @@
}
}
- protected void ungetService(Bundle relBundle, Object svcObj)
+ void ungetService(Bundle relBundle, Object svcObj)
{
// If the service object is a service factory, then
// let it release the service object.
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 fc35627..09d29a6 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -38,7 +38,7 @@
// Maps bundle to an array of usage counts.
private Map m_inUseMap = new HashMap();
- private ServiceListener m_serviceListener = null;
+ private final ServiceRegistryCallbacks m_callbacks;
private final Object m_eventHookLock = new Object();
private Object[] m_eventHooks = new Object[0];
@@ -47,9 +47,10 @@
private final Object m_listenerHookLock = new Object();
private Object[] m_listenerHooks = new Object[0];
- public ServiceRegistry(Logger logger)
+ public ServiceRegistry(Logger logger, ServiceRegistryCallbacks callbacks)
{
m_logger = logger;
+ m_callbacks = callbacks;
}
public synchronized ServiceReference[] getRegisteredServices(Bundle bundle)
@@ -85,7 +86,13 @@
ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
m_serviceRegsMap.put(bundle, addServiceRegistration(regs, reg));
}
- fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+
+ // Notify callback objects about registered service.
+ if (m_callbacks != null)
+ {
+ m_callbacks.serviceChanged(
+ new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()), reg);
+ }
return reg;
}
@@ -107,9 +114,12 @@
m_serviceRegsMap.put(bundle, removeServiceRegistration(regs, reg));
}
- // Fire the service event which gives all client bundles the
- // opportunity to unget their service object.
- fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
+ // Notify callback objects about unregistering service.
+ if (m_callbacks != null)
+ {
+ m_callbacks.serviceChanged(
+ new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()), reg);
+ }
// Now forcibly unget the service object for all stubborn clients.
synchronized (this)
@@ -498,9 +508,13 @@
return bundles;
}
- public void servicePropertiesModified(ServiceRegistration reg)
+ void servicePropertiesModified(ServiceRegistration reg, Map oldProps, Map newProps)
{
- fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
+ if (m_callbacks != null)
+ {
+ m_callbacks.serviceChanged(
+ new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()), reg);
+ }
}
public Logger getLogger()
@@ -554,82 +568,6 @@
return regs;
}
- public synchronized void addServiceListener(ServiceListener l)
- {
- m_serviceListener = ServiceListenerMulticaster.add(m_serviceListener, l);
- }
-
- public synchronized void removeServiceListener(ServiceListener l)
- {
- m_serviceListener = ServiceListenerMulticaster.remove(m_serviceListener, l);
- }
-
- protected void fireServiceChanged(ServiceEvent event)
- {
- // Grab a copy of the listener list.
- ServiceListener listener;
- synchronized (this)
- {
- listener = m_serviceListener;
- }
- // If not null, then dispatch event.
- if (listener != null)
- {
- listener.serviceChanged(event);
- }
- }
-
- private static class ServiceListenerMulticaster implements ServiceListener
- {
- protected ServiceListener m_a = null, m_b = null;
-
- protected ServiceListenerMulticaster(ServiceListener a, ServiceListener b)
- {
- m_a = a;
- m_b = b;
- }
-
- public void serviceChanged(ServiceEvent e)
- {
- m_a.serviceChanged(e);
- m_b.serviceChanged(e);
- }
-
- public static ServiceListener add(ServiceListener a, ServiceListener b)
- {
- if (a == null)
- {
- return b;
- }
- else if (b == null)
- {
- return a;
- }
- else
- {
- return new ServiceListenerMulticaster(a, b);
- }
- }
-
- public static ServiceListener remove(ServiceListener a, ServiceListener b)
- {
- if ((a == null) || (a == b))
- {
- return null;
- }
- else if (a instanceof ServiceListenerMulticaster)
- {
- return add(
- remove(((ServiceListenerMulticaster) a).m_a, b),
- remove(((ServiceListenerMulticaster) a).m_b, b));
- }
- else
- {
- return a;
- }
- }
- }
-
/**
* Utility method to retrieve the specified bundle's usage count for the
* specified service reference.
@@ -976,4 +914,9 @@
public ServiceReference m_ref = null;
public Object m_svcObj = null;
}
-}
+
+ public interface ServiceRegistryCallbacks
+ {
+ void serviceChanged(ServiceEvent event, ServiceRegistration reg);
+ }
+}
\ 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 25eb1c7..9b6b444 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
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Set;
import org.apache.felix.framework.InvokeHookCallback;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.ServiceRegistry;
@@ -44,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;
@@ -51,12 +53,13 @@
public class EventDispatcher
{
- private static final int LISTENER_BUNDLE_OFFSET = 0;
- private static final int LISTENER_CLASS_OFFSET = 1;
- private static final int LISTENER_OBJECT_OFFSET = 2;
- private static final int LISTENER_FILTER_OFFSET = 3;
- private static final int LISTENER_SECURITY_OFFSET = 4;
- private static final int LISTENER_ARRAY_INCREMENT = 5;
+ static final int LISTENER_BUNDLE_OFFSET = 0;
+ static final int LISTENER_CLASS_OFFSET = 1;
+ static final int LISTENER_OBJECT_OFFSET = 2;
+ static final int LISTENER_FILTER_OFFSET = 3;
+ static final int LISTENER_MATECHEDSET_OFFSET = 4;
+ static final int LISTENER_SECURITY_OFFSET = 5;
+ static final int LISTENER_ARRAY_INCREMENT = 6;
private Logger m_logger = null;
private volatile ServiceRegistry m_serviceRegistry = null;
@@ -198,6 +201,7 @@
synchronized (this)
{
Object[] listeners = null;
+ Set set = null;
Object acc = null;
if (clazz == FrameworkListener.class)
@@ -223,7 +227,11 @@
{
acc = ((SecurityManager) sm).getSecurityContext();
}
-
+ // We need to create a Set for keeping track of matching service
+ // registrations so we can fire ServiceEvent.MODIFIED_ENDMATCH
+ // events. We need a Set even if filter is null, since the
+ // listener can be updated and have a filter added later.
+ set = new SmallSet();
listeners = m_serviceListeners;
}
else
@@ -239,6 +247,7 @@
listeners[LISTENER_CLASS_OFFSET] = clazz;
listeners[LISTENER_OBJECT_OFFSET] = l;
listeners[LISTENER_FILTER_OFFSET] = filter;
+ listeners[LISTENER_MATECHEDSET_OFFSET] = set;
listeners[LISTENER_SECURITY_OFFSET] = acc;
}
// Otherwise, we need to do some array copying.
@@ -254,6 +263,7 @@
newList[listeners.length + LISTENER_CLASS_OFFSET] = clazz;
newList[listeners.length + LISTENER_OBJECT_OFFSET] = l;
newList[listeners.length + LISTENER_FILTER_OFFSET] = filter;
+ newList[listeners.length + LISTENER_MATECHEDSET_OFFSET] = set;
newList[listeners.length + LISTENER_SECURITY_OFFSET] = acc;
listeners = newList;
}
@@ -523,6 +533,7 @@
{
// The spec says to update the filter in this case.
listeners[i + LISTENER_FILTER_OFFSET] = filter;
+ ((Set) listeners[i + LISTENER_MATECHEDSET_OFFSET]).clear();
}
return true;
}
@@ -596,7 +607,7 @@
}
// Fire synchronous bundle listeners immediately on the calling thread.
- fireEventImmediately(m_logger, Request.BUNDLE_EVENT, syncListeners, event);
+ fireEventImmediately(m_logger, Request.BUNDLE_EVENT, syncListeners, event, null);
// The spec says that asynchronous bundle listeners do not get events
// of types STARTING, STOPPING, or LAZY_ACTIVATION.
@@ -609,7 +620,8 @@
}
}
- public void fireServiceEvent(final ServiceEvent event, Framework felix)
+ public void fireServiceEvent(
+ final ServiceEvent event, final ServiceRegistration reg, final Framework felix)
{
// Take a snapshot of the listener array.
Object[] listeners = null;
@@ -644,7 +656,7 @@
}
// Fire all service events immediately on the calling thread.
- fireEventImmediately(m_logger, Request.SERVICE_EVENT, listeners, event);
+ fireEventImmediately(m_logger, Request.SERVICE_EVENT, listeners, event, reg);
}
private void fireEventAsynchronously(
@@ -688,7 +700,8 @@
}
private static void fireEventImmediately(
- Logger logger, int type, Object[] listeners, EventObject event)
+ Logger logger, int type, Object[] listeners, EventObject event,
+ ServiceRegistration reg)
{
if (listeners.length > 0)
{
@@ -700,6 +713,7 @@
Bundle bundle = (Bundle) listeners[i + LISTENER_BUNDLE_OFFSET];
EventListener l = (EventListener) listeners[i + LISTENER_OBJECT_OFFSET];
Filter filter = (Filter) listeners[i + LISTENER_FILTER_OFFSET];
+ Set matchedSet = (Set) listeners[i + LISTENER_MATECHEDSET_OFFSET];
Object acc = listeners[i + LISTENER_SECURITY_OFFSET];
try
{
@@ -713,7 +727,8 @@
}
else if (type == Request.SERVICE_EVENT)
{
- invokeServiceListenerCallback(bundle, l, filter, acc, event);
+ invokeServiceListenerCallback(
+ bundle, l, filter, matchedSet, acc, event, reg);
}
}
catch (Throwable th)
@@ -786,7 +801,9 @@
}
private static void invokeServiceListenerCallback(
- Bundle bundle, final EventListener l, Filter filter, Object acc, final EventObject event)
+ Bundle bundle, final EventListener l, Filter filter,
+ Set matchedSet, Object acc, final EventObject event,
+ final ServiceRegistration reg)
{
// Service events should be delivered to STARTING,
// STOPPING, and ACTIVE bundles.
@@ -837,11 +854,24 @@
if (hasPermission)
{
// Dispatch according to the filter.
- if ((filter == null) || filter.match(((ServiceEvent) event).getServiceReference()))
+ boolean matched = (filter == null)
+ || filter.match(((ServiceEvent) event).getServiceReference());
+
+ if (matched)
{
if ((l instanceof AllServiceListener) ||
Util.isServiceAssignable(bundle, ((ServiceEvent) event).getServiceReference()))
{
+ // If we have a filter, then record the matching service
+ // registration so we can know when to fire a MODIFIED_ENDMATCH
+ // event if the filter no longer matches.
+ if (filter != null)
+ {
+ synchronized (matchedSet)
+ {
+ matchedSet.add(reg);
+ }
+ }
if (System.getSecurityManager() != null)
{
AccessController.doPrivileged(new PrivilegedAction() {
@@ -854,9 +884,37 @@
}
else
{
- {
- ((ServiceListener) l).serviceChanged((ServiceEvent) event);
- }
+ ((ServiceListener) l).serviceChanged((ServiceEvent) event);
+ }
+ }
+ }
+ // We need to send an MODIFIED_ENDMATCH event if the listener
+ // matched previously.
+ else if (((ServiceEvent) event).getType() == ServiceEvent.MODIFIED)
+ {
+ boolean removed = false;
+ synchronized (matchedSet)
+ {
+ removed = matchedSet.remove(reg);
+ }
+ if (removed)
+ {
+ final ServiceEvent se = new ServiceEvent(
+ ServiceEvent.MODIFIED_ENDMATCH,
+ ((ServiceEvent) event).getServiceReference());
+ if (System.getSecurityManager() != null)
+ {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run()
+ {
+ ((ServiceListener) l).serviceChanged(se);
+ return null;
+ }
+ });
+ }
+ else
+ {
+ ((ServiceListener) l).serviceChanged(se);
}
}
}
@@ -909,7 +967,7 @@
// NOTE: We don't catch any exceptions here, because
// the invoked method shields us from exceptions by
// catching Throwables when it invokes callbacks.
- fireEventImmediately(req.m_logger, req.m_type, req.m_listeners, req.m_event);
+ fireEventImmediately(req.m_logger, req.m_type, req.m_listeners, req.m_event, null);
// Put dispatch request in cache.
synchronized (m_requestPool)
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java b/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java
new file mode 100644
index 0000000..567a0c5
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/util/SmallSet.java
@@ -0,0 +1,198 @@
+/*
+ * 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.framework.util;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class SmallSet implements Set
+{
+ private Object[] m_objs;
+ private Set m_set;
+
+ public synchronized int size()
+ {
+ if (m_objs != null)
+ {
+ return m_objs.length;
+ }
+ else if (m_set != null)
+ {
+ return m_set.size();
+ }
+ return 0;
+ }
+
+ public synchronized boolean isEmpty()
+ {
+ return (size() == 0);
+ }
+
+ public synchronized boolean contains(Object obj)
+ {
+ boolean found = false;
+ if (obj != null)
+ {
+ if (m_objs != null)
+ {
+ for (int i = 0; !found && (i < m_objs.length); i++)
+ {
+ found = m_objs[i].equals(obj);
+ }
+ }
+ else
+ {
+ found = (m_set == null) ? false : m_set.contains(obj);
+ }
+ }
+ return found;
+ }
+
+ public synchronized Iterator iterator()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized Object[] toArray()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized Object[] toArray(Object[] arg0)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized boolean add(Object obj)
+ {
+ boolean found = contains(obj);
+ if (!found)
+ {
+ if (size() < 10)
+ {
+ if (m_objs == null)
+ {
+ m_objs = new Object[] { obj };
+ }
+ else
+ {
+ Object[] tobjs = new Object[m_objs.length + 1];
+ System.arraycopy(m_objs, 0, tobjs, 0, m_objs.length);
+ tobjs[m_objs.length] = obj;
+ m_objs = tobjs;
+ }
+ }
+ else
+ {
+ if (m_set == null)
+ {
+ m_set = new HashSet();
+ for (int i = 0; i < m_objs.length; i++)
+ {
+ m_set.add(m_objs[i]);
+ }
+ m_objs = null;
+ }
+ m_set.add(obj);
+ }
+ }
+ return !found;
+ }
+
+ public synchronized boolean remove(Object obj)
+ {
+ boolean found = contains(obj);
+ if (found)
+ {
+ if (size() < 10)
+ {
+ if (m_objs.length == 1)
+ {
+ m_objs = null;
+ }
+ else
+ {
+ int idx = -1;
+ for (int i = 0; (idx < 0) && (i < m_objs.length); i++)
+ {
+ if (m_objs[i].equals(obj))
+ {
+ idx = i;
+ }
+ }
+
+ if (idx >= 0)
+ {
+ Object[] tobjs = new Object[m_objs.length - 1];
+ System.arraycopy(m_objs, 0, tobjs, 0, idx);
+ if (idx < tobjs.length)
+ {
+ System.arraycopy(
+ m_objs, idx + 1, tobjs, idx, tobjs.length - idx);
+ }
+ m_objs = tobjs;
+ }
+ }
+ }
+ else
+ {
+ m_set.remove(obj);
+ if (m_set.size() < 10)
+ {
+ m_objs = new Object[m_set.size()];
+ int i = 0;
+ for (Iterator it = m_set.iterator(); it.hasNext(); )
+ {
+ m_objs[i++] = it.next();
+ }
+ m_set = null;
+ }
+ }
+ }
+ return found;
+ }
+
+ public synchronized boolean containsAll(Collection arg0)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized boolean addAll(Collection arg0)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized boolean retainAll(Collection arg0)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized boolean removeAll(Collection arg0)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public synchronized void clear()
+ {
+ m_objs = null;
+ m_set = null;
+ }
+}
\ 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 d0c8845..562da2f 100644
--- a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -45,7 +45,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
EventHook hook = new EventHook()
{
public void event(ServiceEvent event, Collection contexts)
@@ -74,7 +74,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
ServiceFactory sf = (ServiceFactory) sfControl.getMock();
@@ -103,7 +103,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
FindHook hook = new FindHook()
{
public void find(BundleContext context, String name, String filter,
@@ -133,7 +133,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
ServiceFactory sf = (ServiceFactory) sfControl.getMock();
@@ -162,10 +162,9 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
ListenerHook hook = new ListenerHook()
{
-
public void added(Collection listeners)
{
}
@@ -196,7 +195,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
ServiceFactory sf = (ServiceFactory) sfControl.getMock();
@@ -225,7 +224,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
class CombinedService implements ListenerHook, FindHook, EventHook, Runnable
{
public void added(Collection listeners)
@@ -256,10 +255,10 @@
assertEquals("Precondition failed", 0, sr.getFindHooks().size());
assertEquals("Precondition failed", 0, sr.getListenerHooks().size());
ServiceRegistration reg = sr.registerService(b, new String [] {
- Runnable.class.getName(),
- ListenerHook.class.getName(),
- FindHook.class.getName(),
- EventHook.class.getName()}, hook, new Hashtable());
+ Runnable.class.getName(),
+ ListenerHook.class.getName(),
+ FindHook.class.getName(),
+ EventHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getListenerHooks().size());
assertSame(hook, sr.getListenerHooks().iterator().next());
assertEquals(1, sr.getEventHooks().size());
@@ -279,7 +278,7 @@
Bundle b = (Bundle) control.getMock();
control.replay();
- ServiceRegistry sr = new ServiceRegistry(new Logger());
+ ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
String svcObj = "hello";
assertEquals("Precondition failed", 0, sr.getEventHooks().size());
assertEquals("Precondition failed", 0, sr.getFindHooks().size());
@@ -386,4 +385,4 @@
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/EventDispatcherListenerWrapperTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
index 1978c10..90d1f20 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherListenerWrapperTest.java
@@ -45,21 +45,24 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15),
- b3,
- BundleContext.class,
- new Object(),
- null,
- Boolean.TRUE,
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15), // LISTENER_SECURITY_OFFSET
+ b3, // LISTENER_BUNDLE_OFFSET
+ BundleContext.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ null, // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ Boolean.TRUE, // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -80,9 +83,15 @@
Object[] actualListeners =
((EventDispatcher.ListenerBundleContextCollectionWrapper) c).getListeners();
- Object[] expectedListeners = new Object[10];
- System.arraycopy(listeners, 0, expectedListeners, 0, 5);
- System.arraycopy(listeners, 10, expectedListeners, 5, 5);
+ Object[] expectedListeners = new Object[EventDispatcher.LISTENER_ARRAY_INCREMENT * 2];
+ System.arraycopy(listeners, 0, expectedListeners, 0,
+ EventDispatcher.LISTENER_ARRAY_INCREMENT);
+ System.arraycopy(
+ listeners,
+ EventDispatcher.LISTENER_ARRAY_INCREMENT * 2,
+ expectedListeners,
+ EventDispatcher.LISTENER_ARRAY_INCREMENT,
+ EventDispatcher.LISTENER_ARRAY_INCREMENT);
assertTrue(Arrays.equals(expectedListeners, actualListeners));
assertTrue(c.remove(bc1));
@@ -95,8 +104,12 @@
Object[] actualListeners2 =
((EventDispatcher.ListenerBundleContextCollectionWrapper) c).getListeners();
- Object[] expectedListeners2 = new Object[5];
- System.arraycopy(listeners, 10, expectedListeners2, 0, 5);
+ Object[] expectedListeners2 = new Object[EventDispatcher.LISTENER_ARRAY_INCREMENT];
+ System.arraycopy(
+ listeners, EventDispatcher.LISTENER_ARRAY_INCREMENT * 2,
+ expectedListeners2,
+ 0,
+ EventDispatcher.LISTENER_ARRAY_INCREMENT);
assertTrue(Arrays.equals(expectedListeners2, actualListeners2));
assertTrue(c.remove(bc3));
@@ -121,16 +134,18 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15)
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15) // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -260,21 +275,24 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15),
- b3,
- BundleContext.class,
- new Object(),
- null,
- Boolean.TRUE,
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15), // LISTENER_SECURITY_OFFSET
+ b3, // LISTENER_BUNDLE_OFFSET
+ BundleContext.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ null, // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ Boolean.TRUE, // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -310,21 +328,24 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15),
- b3,
- BundleContext.class,
- new Object(),
- null,
- Boolean.TRUE,
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15), // LISTENER_SECURITY_OFFSET
+ b3, // LISTENER_BUNDLE_OFFSET
+ BundleContext.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ null, // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ Boolean.TRUE, // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -356,21 +377,24 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15),
- b3,
- BundleContext.class,
- new Object(),
- null,
- Boolean.TRUE,
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15), // LISTENER_SECURITY_OFFSET
+ b3, // LISTENER_BUNDLE_OFFSET
+ BundleContext.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ null, // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ Boolean.TRUE, // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -405,16 +429,18 @@
Object[] listeners = new Object[]
{
- b1,
- String.class,
- new Object(),
- "(some=filter)",
- null,
- b2,
- Integer.class,
- new Object(),
- "(some.other=filter)",
- new Integer(15),
+ b1, // LISTENER_BUNDLE_OFFSET
+ String.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ null, // LISTENER_SECURITY_OFFSET
+ b2, // LISTENER_BUNDLE_OFFSET
+ Integer.class, // LISTENER_CLASS_OFFSET
+ new Object(), // LISTENER_OBJECT_OFFSET
+ "(some.other=filter)", // LISTENER_FILTER_OFFSET
+ null, // LISTENER_MATECHEDSET_OFFSET
+ new Integer(15), // LISTENER_SECURITY_OFFSET
};
Collection c = new EventDispatcher.ListenerBundleContextCollectionWrapper(listeners);
@@ -458,4 +484,4 @@
return b;
}
-}
\ 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 1d32fe3..62a1791 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
@@ -78,7 +78,7 @@
};
Logger logger = new Logger();
- ServiceRegistry registry = new ServiceRegistry(logger)
+ ServiceRegistry registry = new ServiceRegistry(logger, null)
{
public List getEventHooks()
{
@@ -155,7 +155,7 @@
framework
});
- ed.fireServiceEvent(event, framework);
+ ed.fireServiceEvent(event, null, framework);
assertEquals(1, fired.size());
assertSame(sl3, fired.iterator().next());
@@ -181,4 +181,4 @@
return b;
}
-}
\ No newline at end of file
+}