refactored some common features into an abstract superclass for all decorator patterns

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@891421 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
index ae494a4..20d4f90 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
@@ -170,11 +170,11 @@
     }
     
     //TODO rename iface en iface2 to adaptor en adaptee o.i.d.
-    public Service createAdapterService(Class iface, Class iface2, Class impl) {
+    public Service createAdapterService(Class serviceInterface, String serviceFilter, Class adapterInterface, Class impl, Dictionary adapterProperties) {
         return createService()
-            .setImplementation(new AdapterImpl(iface, iface2, impl))
+            .setImplementation(new AdapterImpl(serviceInterface, serviceFilter, impl, adapterInterface.getName(), adapterProperties))
             .add(createServiceDependency()
-                .setService(iface)
+                .setService(serviceInterface)
                 .setAutoConfig(false)
                 .setCallbacks("added", "removed")
                 );
@@ -184,7 +184,7 @@
     // (being a dependency on more than one, fi ServiceDendency, ResourceDependency
     public Service createResourceAdapterService(String resourceFilter, Class iface2, Object impl, boolean propagate) {
         return createService()
-            .setImplementation(new ResourceAdapterImpl(impl, iface2, propagate))
+            .setImplementation(new ResourceAdapterImpl(resourceFilter, impl, iface2.getName(), null, propagate))
             .add(createResourceDependency()
                 .setFilter(resourceFilter)
                 .setAutoConfig(false)
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
new file mode 100644
index 0000000..218d2e7
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
@@ -0,0 +1,79 @@
+/*
+ * 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.dm.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.resources.Resource;
+import org.apache.felix.dm.service.Service;
+import org.osgi.framework.ServiceReference;
+
+public abstract class AbstractDecorator {
+    protected volatile DependencyManager m_manager;
+    private final Map m_services = new HashMap();
+    
+    public abstract Service createService(Object[] properties);
+
+    // callbacks for resources
+    public void added(Resource resource) {
+        Service newService = createService(new Object[] { resource });
+        m_services.put(resource, newService);
+        m_manager.add(newService);
+    }
+
+    public void removed(Resource resource) {
+        Service newService = (Service) m_services.remove(resource);
+        if (newService == null) {
+            System.out.println("Service should not be null here, dumping stack.");
+            Thread.dumpStack();
+        }
+        else {
+            m_manager.remove(newService);
+        }
+    }
+    
+    // callbacks for services
+    public void added(ServiceReference ref, Object service) {
+        Service newService = createService(new Object[] { ref, service });
+        m_services.put(ref, newService);
+        m_manager.add(newService);
+    }
+    
+    public void removed(ServiceReference ref, Object service) {
+        Service newService = (Service) m_services.remove(ref);
+        if (newService == null) {
+            System.out.println("Service should not be null here, dumping stack.");
+            Thread.dumpStack();
+        }
+        else {
+            m_manager.remove(newService);
+        }
+    }
+    
+    public void stop() { 
+        Iterator i = m_services.values().iterator();
+        while (i.hasNext()) {
+            m_manager.remove((Service) i.next());
+        }
+        m_services.clear();
+    }
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterImpl.java
index 6dcec23..468e39c 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterImpl.java
@@ -18,43 +18,71 @@
  */
 package org.apache.felix.dm.impl;
 
-import java.util.List;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
 
-import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.ServiceReference;
 
-public class AdapterImpl {
-	private volatile DependencyManager m_manager;
+public class AdapterImpl extends AbstractDecorator {
 	private volatile Service m_service;
-	private final Class m_iface;
-	private final Class m_iface2;
-	private final Class m_impl;
+    private final Class m_serviceInterface;
+    private final String m_serviceFilter;
+    private final Object m_adapterImplementation;
+    private final Object m_adapterInterface;
+    private final Dictionary m_adapterProperties;
 	
-	// TODO adapts a "dependency" ... making it sort of a decorator factory
-	public AdapterImpl(Class iface, Class iface2, Class impl) {
-		m_iface = iface;
-		m_iface2 = iface2;
-		m_impl = impl;
-	}
+    public AdapterImpl(Class serviceInterface, String serviceFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties) {
+        m_serviceInterface = serviceInterface;
+        m_serviceFilter = serviceFilter;
+        m_adapterImplementation = adapterImplementation;
+        m_adapterInterface = adapterInterface;
+        m_adapterProperties = adapterProperties;
+    }
+
+    public AdapterImpl(Class serviceInterface, String serviceFilter, Object adapterImplementation, String[] adapterInterfaces, Dictionary adapterProperties) {
+        m_serviceInterface = serviceInterface;
+        m_serviceFilter = serviceFilter;
+        m_adapterImplementation = adapterImplementation;
+        m_adapterInterface = adapterInterfaces;
+        m_adapterProperties = adapterProperties;
+    }
 	
-	public void added(ServiceReference ref, Object service) {
-		// TODO decorator be smarter:
-		
-		// get any "global" dependencies
-		List dependencies = m_service.getDependencies();
-
-		m_manager.add(m_manager.createService()
-			.setInterface(m_iface2.getName(), null)
-			.setImplementation(m_impl)
-			.add(dependencies)
-			.add(m_manager.createServiceDependency()
-				.setService(m_iface, ref)
-				.setRequired(true)
-				)
-			);
-	}
-
-	public void removed(ServiceReference ref, Object service) {
+    public Service createService(Object[] properties) {
+        ServiceReference ref = (ServiceReference) properties[0]; 
+        Object service = properties[1];
+        Properties props = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            props.put(keys[i], ref.getProperty(keys[i]));
+        }
+        if (m_adapterProperties != null) {
+            Enumeration e = m_adapterProperties.keys();
+            while (e.hasMoreElements()) {
+                Object key = e.nextElement();
+                props.put(key, m_adapterProperties.get(key));
+            }
+        }
+        if (m_adapterInterface instanceof String) {
+            return m_manager.createService()
+                .setInterface((String) m_adapterInterface, props)
+                .setImplementation(m_adapterImplementation)
+                .add(m_service.getDependencies())
+                .add(m_manager.createServiceDependency()
+                    .setService(m_serviceInterface, ref)
+                    .setRequired(true)
+                );
+        }
+        else {
+            return m_manager.createService()
+            .setInterface((String[]) m_adapterInterface, props)
+            .setImplementation(m_adapterImplementation)
+            .add(m_service.getDependencies())
+            .add(m_manager.createServiceDependency()
+                .setService(m_serviceInterface, ref)
+                .setRequired(true)
+            );
+        }
 	}
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java
index bc3ab48..94e97d8 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java
@@ -1,23 +1,35 @@
+/*
+ * 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.dm.impl;
 
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Properties;
 
-import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.ServiceReference;
 
-public class AspectImpl {
-	private volatile DependencyManager m_manager;
+public class AspectImpl extends AbstractDecorator {
 	private volatile Service m_service;
 	private final Class m_serviceInterface;
 	private final String m_serviceFilter;
 	private final Object m_aspectImplementation;
-	private final Map m_services = new HashMap();
     private final Dictionary m_aspectProperties;
 	
 	public AspectImpl(Class serviceInterface, String serviceFilter, Object aspectImplementation, Dictionary properties) {
@@ -27,46 +39,27 @@
 		m_aspectProperties = properties;
 	}
 
-	public void added(ServiceReference ref, Object service) {
-		Properties props = new Properties();
-		String[] keys = ref.getPropertyKeys();
-		for (int i = 0; i < keys.length; i++) {
-		    props.put(keys[i], ref.getProperty(keys[i]));
-		}
-		Enumeration e = m_aspectProperties.keys();
-        while (e.hasMoreElements()) {
-            Object key = e.nextElement();
-            props.put(key, m_aspectProperties.get(key));
+    public Service createService(Object[] properties) {
+        ServiceReference ref = (ServiceReference) properties[0]; 
+        Object service = properties[1];
+        Properties props = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            props.put(keys[i], ref.getProperty(keys[i]));
         }
-
-		Service newService = m_manager.createService()
-			.setInterface(m_serviceInterface.getName(), props)
-			.setImplementation(m_aspectImplementation)
-			.add(m_service.getDependencies())
-			.add(m_manager.createServiceDependency()
-				.setService(m_serviceInterface, ref)
-				.setRequired(true)
-				);
-		m_services.put(ref, newService);
-		m_manager.add(newService);
-	}
-
-	public void removed(ServiceReference ref, Object service) {
-		Service newService = (Service) m_services.remove(ref);
-		if (newService == null) {
-			System.out.println("Service should not be null here, dumping stack.");
-			Thread.dumpStack();
-		}
-		else {
-			m_manager.remove(newService);
-		}
-	}
-	
-    public void stop() { 
-        Iterator i = m_services.values().iterator();
-        while (i.hasNext()) {
-            m_manager.remove((Service) i.next());
+        if (m_aspectProperties != null) {
+            Enumeration e = m_aspectProperties.keys();
+            while (e.hasMoreElements()) {
+                Object key = e.nextElement();
+                props.put(key, m_aspectProperties.get(key));
+            }
         }
-        m_services.clear();
+        return m_manager.createService()
+            .setInterface(m_serviceInterface.getName(), props)
+            .setImplementation(m_aspectImplementation)
+            .add(m_service.getDependencies())
+            .add(m_manager.createServiceDependency()
+                .setService(m_serviceInterface, ref)
+                .setRequired(true));
     }
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterImpl.java
index e5bb19e..09bc943 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterImpl.java
@@ -18,33 +18,68 @@
  */
 package org.apache.felix.dm.impl;
 
-import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.resources.Resource;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
 
-public class ResourceAdapterImpl {
-	private volatile DependencyManager m_manager;
-	private final Object m_impl;
-	private final Class m_iface;
+import org.apache.felix.dm.resources.Resource;
+import org.apache.felix.dm.service.Service;
+
+public class ResourceAdapterImpl extends AbstractDecorator {
+    private volatile Service m_service;
+    private final String m_resourceFilter;
+    private final Object m_adapterImplementation;
+    private final Object m_adapterInterface;
+    private final Dictionary m_adapterProperties;
     private final boolean m_propagate;
 
-	public ResourceAdapterImpl(Object impl, Class iface, boolean propagate) {
-		m_impl = impl;
-		m_iface = iface;
-		m_propagate = propagate;
-	}
+    public ResourceAdapterImpl(String resourceFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties, boolean propagate) {
+        m_resourceFilter = resourceFilter;
+        m_adapterImplementation = adapterImplementation;
+        m_adapterInterface = adapterInterface;
+        m_adapterProperties = adapterProperties;
+        m_propagate = propagate;
+    }
 
-	public void added(Resource resource) {
-		m_manager.add(m_manager.createService()
-			.setInterface(m_iface.getName(), null)
-			.setImplementation(m_impl)
-			.add(m_manager.createResourceDependency()
-				.setResource(resource)
-				.setRequired(true)
-				.setPropagate(m_propagate)
-				)
-			);
-	}
+    public ResourceAdapterImpl(String resourceFilter, Object adapterImplementation, String[] adapterInterfaces, Dictionary adapterProperties, boolean propagate) {
+        m_resourceFilter = resourceFilter;
+        m_adapterImplementation = adapterImplementation;
+        m_adapterInterface = adapterInterfaces;
+        m_adapterProperties = adapterProperties;
+        m_propagate = propagate;
+    }	    
 
-	public void removed(Resource resource) {
-	}
+    public Service createService(Object[] properties) {
+        Resource resource = (Resource) properties[0]; 
+        Properties props = new Properties();
+        if (m_adapterProperties != null) {
+            Enumeration e = m_adapterProperties.keys();
+            while (e.hasMoreElements()) {
+                Object key = e.nextElement();
+                props.put(key, m_adapterProperties.get(key));
+            }
+        }
+        if (m_adapterInterface instanceof String) {
+            return m_manager.createService()
+                .setInterface((String) m_adapterInterface, props)
+                .setImplementation(m_adapterImplementation)
+                .add(m_service.getDependencies())
+                .add(m_manager.createResourceDependency()
+                    .setResource(resource)
+                    .setPropagate(m_propagate)
+                    .setRequired(true)
+                );
+        }
+        else {
+            return m_manager.createService()
+                .setInterface((String[]) m_adapterInterface, props)
+                .setImplementation(m_adapterImplementation)
+                .add(m_service.getDependencies())
+                .add(m_manager.createResourceDependency()
+                    .setResource(resource)
+                    .setPropagate(m_propagate)
+                    .setRequired(true)
+                );
+        }
+    }
 }