Author: marrs
Date: Sun Mar 29 19:36:29 2009
New Revision: 759760

URL: http://svn.apache.org/viewvc?rev=759760&view=rev
Log:
FELIX-987 implemented the request as documented, FELIX-992 merged the patch, 
resolved some issues findbugs found in the code.

Modified:
    felix/trunk/dependencymanager/pom.xml
    
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.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
    
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java

Modified: felix/trunk/dependencymanager/pom.xml
URL: 
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/pom.xml?rev=759760&r1=759759&r2=759760&view=diff
==============================================================================
--- felix/trunk/dependencymanager/pom.xml (original)
+++ felix/trunk/dependencymanager/pom.xml Sun Mar 29 19:36:29 2009
@@ -58,7 +58,6 @@
             <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
             <Export-Package>org.apache.felix.dependencymanager</Export-Package>
             
<Import-Package>!org.apache.felix.dependencymanager,*</Import-Package>
-            
<Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,org/osgi/util/tracker/=target/classes/org/osgi/util/tracker</Include-Resource>
           </instructions>
         </configuration>
       </plugin>

Modified: 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java?rev=759760&r1=759759&r2=759760&view=diff
==============================================================================
--- 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java
 (original)
+++ 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java
 Sun Mar 29 19:36:29 2009
@@ -143,7 +143,7 @@
      * there will never be a log service present since the system bundle is
      * started before every other bundle.
      */
-    private void startListeningForLogService() {
+    private synchronized void startListeningForLogService() {
         // Add a service listener for log services.
         try {
             m_context.addServiceListener(this, 
"(objectClass=org.osgi.service.log.LogService)");

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=759760&r1=759759&r2=759760&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
 Sun Mar 29 19:36:29 2009
@@ -22,15 +22,17 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
+import java.util.AbstractMap;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 /**
  * Service dependency that can track an OSGi service.
@@ -40,14 +42,14 @@
 public class ServiceDependency implements Dependency, 
ServiceTrackerCustomizer, ServiceComponentDependency {
     private boolean m_isRequired;
     private Service m_service;
-    private ServiceTracker m_tracker;
+    private volatile ServiceTracker m_tracker;
     private BundleContext m_context;
     private boolean m_isAvailable;
-    private Class m_trackedServiceName;
+    private volatile Class m_trackedServiceName;
     private Object m_nullObject;
-    private String m_trackedServiceFilter;
-    private ServiceReference m_trackedServiceReference;
-    private boolean m_isStarted;
+    private volatile String m_trackedServiceFilter;
+    private volatile ServiceReference m_trackedServiceReference;
+    private volatile boolean m_isStarted;
     private Object m_callbackInstance;
     private String m_callbackAdded;
     private String m_callbackChanged;
@@ -83,6 +85,78 @@
         }
     };
     
+    // Class used to wrap service properties behing a Map
+    private final static class ServicePropertiesMapEntry implements Map.Entry {
+        private final String m_key;
+        private Object m_value;
+
+        public ServicePropertiesMapEntry(String key, Object value) {
+            m_key = key;
+            m_value = value;
+        }
+
+        public Object getKey() {
+            return m_key;
+        }
+
+        public Object getValue() {
+            return m_value;
+        }
+
+        public String toString() {
+            return m_key + "=" + m_value;
+        }
+
+        public Object setValue(Object value) {
+            Object oldValue = m_value;
+            m_value = value;
+            return oldValue;
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof Map.Entry)) {
+                return false;
+            }
+            Map.Entry e = (Map.Entry) o;
+            return eq(m_key, e.getKey()) && eq(m_value, e.getValue());
+        }
+
+        public int hashCode() {
+            return ((m_key == null) ? 0 : m_key.hashCode()) ^ ((m_value == 
null) ? 0 : m_value.hashCode());
+        }
+
+        private static final boolean eq(Object o1, Object o2) {
+            return (o1 == null ? o2 == null : o1.equals(o2));
+        }
+    }
+
+    // Class used to wrap service properties behing a Map
+    private final static class ServicePropertiesMap extends AbstractMap {
+        private final ServiceReference m_ref;
+
+        public ServicePropertiesMap(ServiceReference ref) {
+            m_ref = ref;
+        }
+
+        public Object get(Object key) {
+            return m_ref.getProperty(key.toString());
+        }
+
+        public int size() {
+            return m_ref.getPropertyKeys().length;
+        }
+
+        public Set entrySet() {
+            Set set = new HashSet();
+            String[] keys = m_ref.getPropertyKeys();
+            for (int i = 0; i < keys.length; i++) {
+                set.add(new ServicePropertiesMapEntry(keys[i], 
m_ref.getProperty(keys[i])));
+            }
+            return set;
+        }
+    }
+    
+    
     /**
      * Creates a new service dependency.
      * 
@@ -377,8 +451,8 @@
                 trackedServiceName = m_trackedServiceName;
             }
             done = invokeMethod(instance, currentClazz, methodName,
-                new Class[][] {{ServiceReference.class, trackedServiceName}, 
{ServiceReference.class, Object.class}, {ServiceReference.class}, 
{trackedServiceName}, {Object.class}, {}},
-                new Object[][] {{reference, service}, {reference, service}, 
{reference}, {service}, {service}, {}},
+                new Class[][] {{ServiceReference.class, trackedServiceName}, 
{ServiceReference.class, Object.class}, {ServiceReference.class}, 
{trackedServiceName}, {Object.class}, {}, {Map.class}},
+                new Object[][] {{reference, service}, {reference, service}, 
{reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference)}},
                 false);
             if (!done) {
                 currentClazz = currentClazz.getSuperclass();

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=759760&r1=759759&r2=759760&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
 Sun Mar 29 19:36:29 2009
@@ -26,9 +26,11 @@
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.osgi.framework.BundleContext;
@@ -86,6 +88,8 @@
        // internal logging
     private final Logger m_logger;
     private ServiceRegistration m_serviceRegistration;
+    private Map m_autoConfig = new HashMap();
+    private Map m_autoConfigInstance = new HashMap();
 
     public ServiceImpl(BundleContext context, DependencyManager manager, 
Logger logger) {
        m_logger = logger;
@@ -97,6 +101,9 @@
         m_callbackStop = "stop";
         m_callbackDestroy = "destroy";
         m_implementation = null;
+        m_autoConfig.put(BundleContext.class, Boolean.TRUE);
+        m_autoConfig.put(ServiceRegistration.class, Boolean.TRUE);
+        m_autoConfig.put(DependencyManager.class, Boolean.TRUE);
     }
 
     private void calculateStateChanges(final State oldState, final State 
newState) {
@@ -575,13 +582,15 @@
                                if (factory == null) {
                         m_logger.log(Logger.LOG_ERROR, "Factory cannot be 
null.");
                                }
-                               try {
-                                               Method m = 
factory.getClass().getDeclaredMethod(m_instanceFactoryCreateMethod, null);
-                                               m_serviceInstance = 
m.invoke(factory, null);
-                                       }
-                               catch (Exception e) {
-                           m_logger.log(Logger.LOG_ERROR, "Could not create 
service instance using factory " + factory + " method " + 
m_instanceFactoryCreateMethod + ".", e);
-                                       }
+                               else {
+                               try {
+                                               Method m = 
factory.getClass().getDeclaredMethod(m_instanceFactoryCreateMethod, null);
+                                               m_serviceInstance = 
m.invoke(factory, null);
+                                       }
+                               catch (Exception e) {
+                           m_logger.log(Logger.LOG_ERROR, "Could not create 
service instance using factory " + factory + " method " + 
m_instanceFactoryCreateMethod + ".", e);
+                                       }
+                               }
                        }
                        if (m_implementation == null) {
                     m_logger.log(Logger.LOG_ERROR, "Implementation cannot be 
null.");
@@ -591,12 +600,27 @@
                        }
                }
                // configure the bundle context
-               configureImplementation(BundleContext.class, m_context);
-               configureImplementation(ServiceRegistration.class, 
NULL_REGISTRATION);
-               configureImplementation(DependencyManager.class, m_manager);
+               if (((Boolean) 
m_autoConfig.get(BundleContext.class)).booleanValue()) {
+                   configureImplementation(BundleContext.class, m_context, 
(String) m_autoConfigInstance.get(BundleContext.class));
+               }
+            if (((Boolean) 
m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
+                configureImplementation(ServiceRegistration.class, 
NULL_REGISTRATION, (String) 
m_autoConfigInstance.get(ServiceRegistration.class));
+            }
+            if (((Boolean) 
m_autoConfig.get(DependencyManager.class)).booleanValue()) {
+                configureImplementation(DependencyManager.class, m_manager, 
(String) m_autoConfigInstance.get(DependencyManager.class));
+            }
        }
     }
 
+    public void setAutoConfig(Class clazz, boolean autoConfig) {
+        m_autoConfig.put(clazz, Boolean.valueOf(autoConfig));
+    }
+    
+    public void setAutoConfig(Class clazz, String instanceName) {
+        m_autoConfig.put(clazz, Boolean.valueOf(instanceName != null));
+        m_autoConfigInstance.put(clazz, instanceName);
+    }
+    
     private void configureService(State state) {
         // configure all services (the optional dependencies might be 
configured
         // as null objects but that's what we want at this point)
@@ -612,7 +636,10 @@
         if (m_serviceName != null) {
             ServiceRegistrationImpl wrapper = new ServiceRegistrationImpl();
             m_registration = wrapper;
-            configureImplementation(ServiceRegistration.class, wrapper);
+            if (((Boolean) 
m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
+                configureImplementation(ServiceRegistration.class, 
m_registration, (String) m_autoConfigInstance.get(ServiceRegistration.class));
+            }
+            
             // service name can either be a string or an array of strings
             ServiceRegistration registration;
 

Modified: 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java?rev=759760&r1=759759&r2=759760&view=diff
==============================================================================
--- 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
 (original)
+++ 
felix/trunk/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
 Sun Mar 29 19:36:29 2009
@@ -162,7 +162,7 @@
         this.trackReference = null;
         this.trackClass = clazz;
         this.customizer = (customizer == null) ? this : customizer;
-        this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + 
clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")"; 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         try {
             this.filter = context.createFilter(listenerFilter);
         }


Reply via email to