FELIX-303 Implemented support for compositions. Untested and unstable API, you have been warned.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@554752 13f79535-47bb-0310-9956-ffa450edef68
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 183cf07..d73c15b 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
@@ -71,6 +71,15 @@
// work queue
private final SerialExecutor m_executor = new SerialExecutor();
+ // instance factory
+ private Object m_instanceFactory;
+ private String m_instanceFactoryCreateMethod;
+
+ // composition manager
+ private Object m_compositionManager;
+ private String m_compositionManagerGetMethod;
+ private Object m_compositionManagerInstance;
+
public ServiceImpl(BundleContext context) {
m_state = new State((List) m_dependencies.clone(), false);
m_context = context;
@@ -269,6 +278,26 @@
m_implementation = implementation;
return this;
}
+
+ public synchronized Service setFactory(Object factory, String createMethod) {
+ m_instanceFactory = factory;
+ m_instanceFactoryCreateMethod = createMethod;
+ return this;
+ }
+
+ public synchronized Service setFactory(String createMethod) {
+ return setFactory(null, createMethod);
+ }
+
+ public synchronized Service setComposition(Object instance, String getMethod) {
+ m_compositionManager = instance;
+ m_compositionManagerGetMethod = getMethod;
+ return this;
+ }
+
+ public synchronized Service setComposition(String getMethod) {
+ return setComposition(null, getMethod);
+ }
public String toString() {
return "ServiceImpl[" + m_serviceName + " " + m_implementation + "]";
@@ -473,15 +502,52 @@
// instantiate
try {
m_serviceInstance = ((Class) m_implementation).newInstance();
- } catch (InstantiationException e) {
+ }
+ catch (InstantiationException e) {
// TODO handle this exception
e.printStackTrace();
- } catch (IllegalAccessException e) {
+ }
+ catch (IllegalAccessException e) {
// TODO handle this exception
e.printStackTrace();
}
}
else {
+ if (m_instanceFactoryCreateMethod != null) {
+ Object factory = null;
+ if (m_instanceFactory != null) {
+ if (m_instanceFactory instanceof Class) {
+ try {
+ factory = ((Class) m_instanceFactory).newInstance();
+ }
+ catch (InstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ else {
+ factory = m_instanceFactory;
+ }
+ }
+ else {
+ factory = null; // TODO!!!! where does the factory come from if not explicitly defined
+ }
+ if (factory == null) {
+ throw new IllegalStateException("Factory cannot be null");
+ }
+ try {
+ Method m = factory.getClass().getDeclaredMethod(m_instanceFactoryCreateMethod, null);
+ m_serviceInstance = m.invoke(factory, null);
+ }
+ catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
if (m_implementation == null) {
throw new IllegalStateException("Implementation cannot be null");
}
@@ -600,47 +666,75 @@
* @param instance the instance to fill in
*/
private void configureImplementation(Class clazz, Object instance) {
- Class serviceClazz = m_serviceInstance.getClass();
- while (serviceClazz != null) {
- Field[] fields = serviceClazz.getDeclaredFields();
- AccessibleObject.setAccessible(fields, true);
- for (int j = 0; j < fields.length; j++) {
- if (fields[j].getType().equals(clazz)) {
- try {
- // synchronized makes sure the field is actually written to immediately
- synchronized (new Object()) {
- fields[j].set(m_serviceInstance, instance);
- }
- }
- catch (Exception e) {
- System.err.println("Exception while trying to set " + fields[j].getName() +
- " of type " + fields[j].getType().getName() +
- " by classloader " + fields[j].getType().getClassLoader() +
- " which should equal type " + clazz.getName() +
- " by classloader " + clazz.getClassLoader() +
- " of type " + serviceClazz.getName() +
- " by classloader " + serviceClazz.getClassLoader() +
- " on " + m_serviceInstance +
- " by classloader " + m_serviceInstance.getClass().getClassLoader() +
- "\nDumping stack:"
- );
- e.printStackTrace();
- System.out.println("C: " + clazz);
- System.out.println("I: " + instance);
- System.out.println("I:C: " + instance.getClass().getClassLoader());
- Class[] classes = instance.getClass().getInterfaces();
- for (int i = 0; i < classes.length; i++) {
- Class c = classes[i];
- System.out.println("I:C:I: " + c);
- System.out.println("I:C:I:C: " + c.getClassLoader());
- }
- System.out.println("F: " + fields[j]);
- throw new IllegalStateException("Could not set field " + fields[j].getName() + " on " + m_serviceInstance);
- }
- }
- }
- serviceClazz = serviceClazz.getSuperclass();
- }
+ Object[] instances = null;
+ if (m_compositionManagerGetMethod != null) {
+ if (m_compositionManager != null) {
+ m_compositionManagerInstance = m_compositionManager;
+ }
+ else {
+ m_compositionManagerInstance = m_serviceInstance;
+ }
+ if (m_compositionManagerInstance != null) {
+ try {
+ Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
+ AccessibleObject.setAccessible(new AccessibleObject[] { m }, true);
+ instances = (Object[]) m.invoke(m_compositionManager, null);
+ }
+ catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ else {
+ instances = new Object[] { m_serviceInstance };
+ }
+ if (instances != null) {
+ for (int i = 0; i < instances.length; i++) {
+ Object serviceInstance = instances[i];
+ Class serviceClazz = serviceInstance.getClass();
+ while (serviceClazz != null) {
+ Field[] fields = serviceClazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int j = 0; j < fields.length; j++) {
+ if (fields[j].getType().equals(clazz)) {
+ try {
+ // synchronized makes sure the field is actually written to immediately
+ synchronized (new Object()) {
+ fields[j].set(serviceInstance, instance);
+ }
+ }
+ catch (Exception e) {
+ System.err.println("Exception while trying to set " + fields[j].getName() +
+ " of type " + fields[j].getType().getName() +
+ " by classloader " + fields[j].getType().getClassLoader() +
+ " which should equal type " + clazz.getName() +
+ " by classloader " + clazz.getClassLoader() +
+ " of type " + serviceClazz.getName() +
+ " by classloader " + serviceClazz.getClassLoader() +
+ " on " + serviceInstance +
+ " by classloader " + serviceInstance.getClass().getClassLoader() +
+ "\nDumping stack:"
+ );
+ e.printStackTrace();
+ System.out.println("C: " + clazz);
+ System.out.println("I: " + instance);
+ System.out.println("I:C: " + instance.getClass().getClassLoader());
+ Class[] classes = instance.getClass().getInterfaces();
+ for (int k = 0; k < classes.length; k++) {
+ Class c = classes[k];
+ System.out.println("I:C:I: " + c);
+ System.out.println("I:C:I:C: " + c.getClassLoader());
+ }
+ System.out.println("F: " + fields[j]);
+ throw new IllegalStateException("Could not set field " + fields[j].getName() + " on " + serviceInstance);
+ }
+ }
+ }
+ serviceClazz = serviceClazz.getSuperclass();
+ }
+ }
+ }
}
private void configureServices(State state) {