Fixed a bug in ConfigurationDependency which did not correctly detect the state transition from an available configuration to a no longer available one (for example, if you deleted the configuration). Furthermore, some whitespace cleanups and some synchronization inconsistencies solved.
Updated the pom.xml to use current dependencies and versions.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@616718 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/pom.xml b/dependencymanager/pom.xml
index ce8b44c..7fb85fc 100644
--- a/dependencymanager/pom.xml
+++ b/dependencymanager/pom.xml
@@ -27,13 +27,13 @@
<modelVersion>4.0.0</modelVersion>
<packaging>bundle</packaging>
<name>Apache Felix Dependency Manager</name>
- <version>0.9.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<artifactId>org.apache.felix.dependencymanager</artifactId>
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.osgi.core</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
index 31410e4..83b3364 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
@@ -120,7 +120,7 @@
if ((oldSettings == null) && (settings != null)) {
m_service.dependencyAvailable(this);
}
- if ((oldSettings == null) && (settings == null)) {
+ if ((oldSettings != null) && (settings == null)) {
m_service.dependencyUnavailable(this);
}
if ((oldSettings != null) && (settings != null)) {
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
index a72174a..cbd98b5 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
@@ -197,4 +197,51 @@
* for this service.
*/
public void stop();
+
+ /**
+ * Sets the factory to use to create the implementation. You can specify
+ * both the factory class and method to invoke. The method should return
+ * the implementation, and can use any method to create it. Actually, this
+ * can be used together with <code>setComposition</code> to create a
+ * composition of instances that work together to implement a service. The
+ * factory itself can also be instantiated lazily by not specifying an
+ * instance, but a <code>Class</code>.
+ *
+ * @param factory the factory instance or class
+ * @param createMethod the name of the create method
+ */
+ public Service setFactory(Object factory, String createMethod);
+
+ /**
+ * Sets the factory to use to create the implementation. You specify the
+ * method to invoke. The method should return the implementation, and can
+ * use any method to create it. Actually, this can be used together with
+ * <code>setComposition</code> to create a composition of instances that
+ * work together to implement a service. The factory method is called on
+ * ??? TODO ???
+ *
+ * @param createMethod the name of the create method
+ */
+ public Service setFactory(String createMethod);
+
+ /**
+ * Sets the instance and method to invoke to get back all instances that
+ * are part of a composition and need dependencies injected. All of them
+ * will be searched for any of the dependencies. The method that is
+ * invoked must return an <code>Object[]</code>.
+ *
+ * @param instance the instance that has the method
+ * @param getMethod the method to invoke
+ */
+ public Service setComposition(Object instance, String getMethod);
+
+ /**
+ * Sets the method to invoke on the service implementation to get back all
+ * instances that are part of a composition and need dependencies injected.
+ * All of them will be searched for any of the dependencies. The method that
+ * is invoked must return an <code>Object[]</code>.
+ *
+ * @param getMethod the method to invoke
+ */
+ public Service setComposition(String getMethod);
}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
index b661810..206f6a9 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
@@ -61,15 +61,15 @@
m_autoConfig = true;
}
- public boolean isRequired() {
+ public synchronized boolean isRequired() {
return m_isRequired;
}
- public boolean isAvailable() {
+ public synchronized boolean isAvailable() {
return m_isAvailable;
}
- public boolean isAutoConfig() {
+ public synchronized boolean isAutoConfig() {
return m_autoConfig;
}
@@ -86,12 +86,16 @@
private Object getNullObject() {
if (m_nullObject == null) {
- m_nullObject = Proxy.newProxyInstance(m_trackedServiceName.getClassLoader(), new Class[] {m_trackedServiceName}, new DefaultNullObject());
+ Class trackedServiceName;
+ synchronized (this) {
+ trackedServiceName = m_trackedServiceName;
+ }
+ m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(), new Class[] {trackedServiceName}, new DefaultNullObject());
}
return m_nullObject;
}
- public Class getInterface() {
+ public synchronized Class getInterface() {
return m_trackedServiceName;
}
@@ -203,6 +207,8 @@
if (!isRequired()) {
invokeRemoved(ref, service);
}
+
+ // unget what we got in addingService (see ServiceTracker 701.4.1)
m_context.ungetService(ref);
}
@@ -241,7 +247,7 @@
return false;
}
- private Object getCallbackInstance() {
+ private synchronized Object getCallbackInstance() {
Object callbackInstance = m_callbackInstance;
if (callbackInstance == null) {
callbackInstance = m_service.getService();
@@ -253,8 +259,12 @@
Class currentClazz = instance.getClass();
boolean done = false;
while (!done && currentClazz != null) {
+ Class trackedServiceName;
+ synchronized (this) {
+ trackedServiceName = m_trackedServiceName;
+ }
done = invokeMethod(instance, currentClazz, methodName,
- new Class[][] {{ServiceReference.class, m_trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {m_trackedServiceName}, {Object.class}, {}},
+ new Class[][] {{ServiceReference.class, trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {trackedServiceName}, {Object.class}, {}},
new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}},
false);
if (!done) {
@@ -419,7 +429,7 @@
}
}
- public String toString() {
+ public synchronized String toString() {
return "ServiceDependency[" + m_trackedServiceName + " " + m_trackedServiceFilter + "]";
}
}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
index 6794d5a..a63f4b8 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
@@ -18,8 +18,17 @@
*/
package org.apache.felix.dependencymanager;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
@@ -692,7 +701,7 @@
try {
Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
m.setAccessible(true);
- instances = (Object[]) m.invoke(m_compositionManager, null);
+ instances = (Object[]) m.invoke(m_compositionManagerInstance, null);
}
catch (Exception e) {
// TODO Auto-generated catch block