felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r696805 - /felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/
Date Thu, 18 Sep 2008 21:13:20 GMT
Author: marrs
Date: Thu Sep 18 14:13:20 2008
New Revision: 696805

URL: http://svn.apache.org/viewvc?rev=696805&view=rev
Log:
Added initial support for externally querying the status of services managed by the dependency
manager. Added initial support for supplying your own default implementation. Made null object
creation more robust. Added support for specifying the name of the property in case you're
injecting dependencies so you can inject multiple instances of a service to specific properties.

Added:
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
Modified:
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
    felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java

Modified: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java?rev=696805&r1=696804&r2=696805&view=diff
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
(original)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
Thu Sep 18 14:13:20 2008
@@ -47,7 +47,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ConfigurationDependency implements Dependency, ManagedService {
+public class ConfigurationDependency implements Dependency, ManagedService, ServiceComponentDependency
{
 	private BundleContext m_context;
 	private String m_pid;
 	private ServiceRegistration m_registration;
@@ -171,4 +171,16 @@
     public String toString() {
     	return "ConfigurationDependency[" + m_pid + "]";
     }
+
+    public String getName() {
+        return m_pid;
+    }
+
+    public int getState() {
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+    }
+
+    public String getType() {
+        return "configuration";
+    }
 }

Modified: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java?rev=696805&r1=696804&r2=696805&view=diff
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
(original)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
Thu Sep 18 14:13:20 2008
@@ -95,7 +95,7 @@
      * @return the new service
      */
     public Service createService() {
-        return new ServiceImpl(m_context, m_logger);
+        return new ServiceImpl(m_context, m_manager, m_logger);
     }
     
     /**

Modified: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java?rev=696805&r1=696804&r2=696805&view=diff
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
(original)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
Thu Sep 18 14:13:20 2008
@@ -73,7 +73,7 @@
      * @return the new service
      */
     public Service createService() {
-        return new ServiceImpl(m_context, m_logger);
+        return new ServiceImpl(m_context, this, m_logger);
     }
     
     /**

Added: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java?rev=696805&view=auto
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
(added)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
Thu Sep 18 14:13:20 2008
@@ -0,0 +1,10 @@
+package org.apache.felix.dependencymanager;
+
+public interface ServiceComponent {
+    public static final String[] STATE_NAMES = { "unregistered", "registered" };
+    public static final int STATE_UNREGISTERED = 0;
+    public static final int STATE_REGISTERED = 1;
+    public ServiceComponentDependency[] getComponentDependencies();
+    public String getName();
+    public int getState();
+}

Added: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java?rev=696805&view=auto
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
(added)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
Thu Sep 18 14:13:20 2008
@@ -0,0 +1,12 @@
+package org.apache.felix.dependencymanager;
+
+public interface ServiceComponentDependency {
+    public static final String[] STATE_NAMES = { "unavailable optional", "available optional",
"unavailable required", "available required" };
+    public static final int STATE_UNAVAILABLE_OPTIONAL = 0;
+    public static final int STATE_AVAILABLE_OPTIONAL = 1;
+    public static final int STATE_UNAVAILABLE_REQUIRED = 2;
+    public static final int STATE_AVAILABLE_REQUIRED = 3;
+    public String getName();
+    public String getType();
+    public int getState();
+}

Modified: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java?rev=696805&r1=696804&r2=696805&view=diff
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
(original)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
Thu Sep 18 14:13:20 2008
@@ -32,7 +32,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceDependency implements Dependency, ServiceTrackerCustomizer {
+public class ServiceDependency implements Dependency, ServiceTrackerCustomizer, ServiceComponentDependency
{
     private boolean m_isRequired;
     private Service m_service;
     private ServiceTracker m_tracker;
@@ -51,6 +51,9 @@
     private ServiceReference m_reference;
     private Object m_serviceInstance;
     private final Logger m_logger;
+    private String m_autoConfigInstance;
+    private Object m_defaultImplementation;
+    private Object m_defaultImplementationInstance;
     
     /**
      * Creates a new service dependency.
@@ -82,7 +85,10 @@
             service = m_tracker.getService();
         }
         if (service == null) {
-            service = getNullObject(); 
+            service = getDefaultImplementation();
+            if (service == null) {
+                service = getNullObject();
+            }
         }
         return service;
     }
@@ -93,11 +99,33 @@
             synchronized (this) {
                 trackedServiceName = m_trackedServiceName;
             }
-            m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(), new
Class[] {trackedServiceName}, new DefaultNullObject()); 
+            try {
+                m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(),
new Class[] {trackedServiceName}, new DefaultNullObject()); 
+            }
+            catch (Exception e) {
+                m_logger.log(Logger.LOG_ERROR, "Could not create null object for " + trackedServiceName
+ ".", e);
+            }
         }
         return m_nullObject;
     }
     
+    private Object getDefaultImplementation() {
+        if (m_defaultImplementation != null) {
+            if (m_defaultImplementation instanceof Class) {
+                try {
+                    m_defaultImplementationInstance = ((Class) m_defaultImplementation).newInstance();
+                }
+                catch (Exception e) {
+                    m_logger.log(Logger.LOG_ERROR, "Could not create default implementation
instance of class " + m_defaultImplementation + ".", e);
+                }
+            }
+            else {
+                m_defaultImplementationInstance = m_defaultImplementation;
+            }
+        }
+        return m_defaultImplementationInstance;
+    }
+    
     public synchronized Class getInterface() {
         return m_trackedServiceName;
     }
@@ -373,6 +401,22 @@
         m_trackedServiceFilter = null;
         return this;
     }
+    
+    /**
+     * Sets the default implementation for this service dependency. You can use this to supply
+     * your own implementation that will be used instead of a Null Object when the dependency
is
+     * not available. This is also convenient if the service dependency is not an interface
+     * (which would cause the Null Object creation to fail) but a class.
+     * 
+     * @param implementation the instance to use or the class to instantiate if you want
to lazily
+     *     instantiate this implementation
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setDefaultImplementation(Object implementation)
{
+        ensureNotActive();
+        m_defaultImplementation = implementation;
+        return this;
+    }
 
     /**
      * Sets the required flag which determines if this service is required or not.
@@ -401,6 +445,21 @@
     }
     
     /**
+     * Sets auto configuration for this service. Auto configuration allows the
+     * dependency to fill in the attribute in the service implementation that
+     * has the same type and instance name.
+     * 
+     * @param instanceName the name of attribute to auto config
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setAutoConfig(String instanceName) {
+        ensureNotActive();
+        m_autoConfig = (instanceName != null);
+        m_autoConfigInstance = instanceName;
+        return this;
+    }
+    
+    /**
      * Sets the callbacks for this service. These callbacks can be used as hooks whenever
      * a dependency is added or removed. They are called on the service implementation.
      * 
@@ -447,4 +506,20 @@
     public synchronized String toString() {
         return "ServiceDependency[" + m_trackedServiceName + " " + m_trackedServiceFilter
+ "]";
     }
+
+    public String getAutoConfigName() {
+        return m_autoConfigInstance;
+    }
+
+    public String getName() {
+        return m_trackedServiceName.getName();
+    }
+
+    public int getState() {
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+    }
+
+    public String getType() {
+        return "service";
+    }
 }

Modified: felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java?rev=696805&r1=696804&r2=696805&view=diff
==============================================================================
--- felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
(original)
+++ felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
Thu Sep 18 14:13:20 2008
@@ -39,12 +39,13 @@
  *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceImpl implements Service {
+public class ServiceImpl implements Service, ServiceComponent {
     private static final Class[] VOID = new Class[] {};
 	private static final ServiceRegistration NULL_REGISTRATION;
     private static final ServiceStateListener[] SERVICE_STATE_LISTENER_TYPE = new ServiceStateListener[]
{};
 
     private final BundleContext m_context;
+    private final DependencyManager m_manager;
 
     // configuration (static)
     private String m_callbackInit;
@@ -84,11 +85,13 @@
 	
 	// internal logging
     private final Logger m_logger;
+    private ServiceRegistration m_serviceRegistration;
 
-    public ServiceImpl(BundleContext context, Logger logger) {
+    public ServiceImpl(BundleContext context, DependencyManager manager, Logger logger) {
     	m_logger = logger;
         m_state = new State((List) m_dependencies.clone(), false);
         m_context = context;
+        m_manager = manager;
         m_callbackInit = "init";
         m_callbackStart = "start";
         m_callbackStop = "stop";
@@ -237,6 +240,7 @@
     }
 
     public synchronized void start() {
+        m_serviceRegistration = m_context.registerService(ServiceComponent.class.getName(),
this, null);
     	State oldState, newState;
         synchronized (m_dependencies) {
         	oldState = m_state;
@@ -254,6 +258,7 @@
             m_state = newState;
         }
         calculateStateChanges(oldState, newState);
+        m_serviceRegistration.unregister();
     }
 
     public synchronized Service setInterface(String serviceName, Dictionary properties) {
@@ -588,6 +593,7 @@
 	        // configure the bundle context
 	        configureImplementation(BundleContext.class, m_context);
 	        configureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
+	        configureImplementation(DependencyManager.class, m_manager);
     	}
     }
 
@@ -676,7 +682,7 @@
             // update the dependency in the service instance (it will use
             // a null object if necessary)
             if (sd.isAutoConfig()) {
-                configureImplementation(sd.getInterface(), sd.getService());
+                configureImplementation(sd.getInterface(), sd.getService(), sd.getAutoConfigName());
             }
         }
         else if (dependency instanceof ConfigurationDependency) {
@@ -696,8 +702,9 @@
      *
      * @param clazz the class to search for
      * @param instance the instance to fill in
+     * @param instanceName the name of the instance to fill in, or <code>null</code>
if not used
      */
-    private void configureImplementation(Class clazz, Object instance) {
+    private void configureImplementation(Class clazz, Object instance, String instanceName)
{
     	Object[] instances = null;
     	if (m_compositionManagerGetMethod != null) {
 			if (m_compositionManager != null) {
@@ -728,7 +735,7 @@
 		        while (serviceClazz != null) {
 		            Field[] fields = serviceClazz.getDeclaredFields();
 		            for (int j = 0; j < fields.length; j++) {
-		                if (fields[j].getType().equals(clazz)) {
+		                if (fields[j].getType().equals(clazz) && (instanceName == null
|| fields[j].getName().equals(instanceName))) {
 		                    try {
 		                    	fields[j].setAccessible(true);
 		                        // synchronized makes sure the field is actually written to immediately
@@ -747,6 +754,10 @@
 	    	}
     	}
     }
+    
+    private void configureImplementation(Class clazz, Object instance) {
+        configureImplementation(clazz, instance, null);
+    }
 
     private void configureServices(State state) {
         Iterator i = state.getDependencies().iterator();
@@ -755,7 +766,7 @@
             if (dependency instanceof ServiceDependency) {
                 ServiceDependency sd = (ServiceDependency) dependency;
                 if (sd.isAutoConfig()) {
-                    configureImplementation(sd.getInterface(), sd.getService());
+                    configureImplementation(sd.getInterface(), sd.getService(), sd.getAutoConfigName());
                 }
                 // for required dependencies, we invoke any callbacks here
                 if (sd.isRequired()) {
@@ -796,6 +807,58 @@
         return (state.isTrackingOptional());
     }
 
+    // ServiceComponent interface
+    
+    static class SCDImpl implements ServiceComponentDependency {
+        private final String m_name;
+        private final int m_state;
+        private final String m_type;
+
+        public SCDImpl(String name, int state, String type) {
+            m_name = name;
+            m_state = state;
+            m_type = type;
+        }
+
+        public String getName() {
+            return m_name;
+        }
+
+        public int getState() {
+            return m_state;
+        }
+
+        public String getType() {
+            return m_type;
+        }
+    }
+    
+    public ServiceComponentDependency[] getComponentDependencies() {
+        List deps = getDependencies();
+        if (deps != null) {
+            ServiceComponentDependency[] result = new ServiceComponentDependency[deps.size()];
+            for (int i = 0; i < result.length; i++) {
+                Dependency dep = (Dependency) deps.get(i);
+                if (dep instanceof ServiceComponentDependency) {
+                    result[i] = (ServiceComponentDependency) dep;
+                }
+                else {
+                    result[i] = new SCDImpl(dep.toString(), (dep.isAvailable() ? 1 : 0) +
(dep.isRequired() ? 2 : 0), dep.getClass().getName());
+                }
+            }
+            return result;
+        }
+        return null;
+    }
+
+    public String getName() {
+        return (String) (m_serviceName != null ? m_serviceName : m_serviceInstance);
+    }
+
+    public int getState() {
+        return (isRegistered() ? 1 : 0);
+    }
+    
     static {
         NULL_REGISTRATION = (ServiceRegistration) Proxy.newProxyInstance(ServiceImpl.class.getClassLoader(),
new Class[] {ServiceRegistration.class}, new DefaultNullObject());
     }



Mime
View raw message