Several smaller bugfixes and performance updates for resources. Added a test that demonstrates how to create a custom dependency (and did some refactorings to make that easier).

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@983639 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/pom.xml b/dependencymanager/core/pom.xml
index 3114a2d..8d0b40f 100644
--- a/dependencymanager/core/pom.xml
+++ b/dependencymanager/core/pom.xml
@@ -55,9 +55,9 @@
             <Export-Package>org.apache.felix.dm;version="3.0.0"</Export-Package>
             <Import-Package>!org.apache.felix.dm,*</Import-Package>
 	        <Private-Package>org.apache.felix.dm.impl,org.apache.felix.dm.impl.dependencies,org.apache.felix.dm.impl.tracker,org.apache.felix.dm.impl.metatype</Private-Package>
-	        <!-- Uncomment this line to include source code in the bundle.
+	        <!-- Uncomment this line to include source code in the bundle.-->
             <Include-Resource>src/main/java</Include-Resource>
-            -->
+            <!-- -->
           </instructions>
         </configuration>
       </plugin>
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/Dependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/Dependency.java
index f79f304..8388eeb 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/Dependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/Dependency.java
@@ -20,7 +20,6 @@
 
 import java.util.Dictionary;
 
-import org.apache.felix.dm.impl.dependencies.DependencyService;
 
 /**
  * Generic dependency for a service. A dependency can be required or not.
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivation.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivation.java
new file mode 100644
index 0000000..e15fd92
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivation.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+public interface DependencyActivation {
+  public void start(DependencyService service);
+  public void stop(DependencyService service);
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyService.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyService.java
similarity index 93%
rename from dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyService.java
rename to dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyService.java
index 0b8f37a..74a7fa4 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyService.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyService.java
@@ -16,10 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.impl.dependencies;
+package org.apache.felix.dm;
 
-import org.apache.felix.dm.Dependency;
-import org.apache.felix.dm.Service;
 
 public interface DependencyService {
     /**
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java
index aa76552..431003c 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java
@@ -21,7 +21,7 @@
 import java.net.URL;
 
 
-public interface ResourceDependency extends Dependency, ResourceHandler {
+public interface ResourceDependency extends Dependency, ServiceComponentDependency, ResourceHandler {
     /**
      * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
      * dependency is added or removed. When you specify callbacks, the auto configuration 
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceHandler.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceHandler.java
index 9b758ca..ad83d39 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceHandler.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceHandler.java
@@ -26,6 +26,8 @@
 public interface ResourceHandler {
     /** Name of the property that's used to describe the filter condition for a resource. */
     public static final String FILTER = "filter";
+    /** Exact URL that this handler is looking for. Can be used instead of a filter to be very explicit about the resource you're looking for. */
+    public static final String URL = "url";
     
     /** The host part of the URL. */
     public static final String HOST = "host";
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceUtil.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceUtil.java
index 04d849e..ebb1c55 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceUtil.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceUtil.java
@@ -1,3 +1,21 @@
+/*
+ * 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;
 
 import java.net.URL;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/Service.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/Service.java
index 66397f5..b7bfd24 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/Service.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/Service.java
@@ -238,4 +238,39 @@
 	 * Returns the dependency manager associated with this service.
 	 */
 	public DependencyManager getDependencyManager();
+
+	/**
+	 * Configures auto configuration of injected classes in the service instance.
+	 * The following injections are currently performed, unless you explicitly
+	 * turn them off:
+	 * <dl>
+	 * <dt>BundleContext</dt><dd>the bundle context of the bundle</dd>
+     * <dt>ServiceRegistration</dt><dd>the service registration used to register your service</dd>
+     * <dt>DependencyManager</dt><dd>the dependency manager instance</dd>
+     * <dt>Service</dt><dd>the service instance of the dependency manager</dd>
+	 * </dl>
+	 * 
+	 * @param clazz the class (from the list above)
+	 * @param autoConfig <code>false</code> to turn off auto configuration
+	 */
+    public Service setAutoConfig(Class clazz, boolean autoConfig);
+    
+    /**
+     * Configures auto configuration of injected classes in the service instance.
+     * 
+     * @param clazz the class (from the list above)
+     * @param instanceName the name of the instance to inject the class into
+     * @see setAutoConfig(Class, boolean)
+     */
+    public Service setAutoConfig(Class clazz, String instanceName);
+
+    /**
+     * Returns the status of auto configuration of the specified class.
+     */
+    public boolean getAutoConfig(Class clazz);
+    
+    /**
+     * Returns the instance variable name of auto configuration of the specified class.
+     */
+    public String getAutoConfigInstance(Class clazz);
 }
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
index 09c7cc8..c889744 100644
--- 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
@@ -30,7 +30,9 @@
 import org.apache.felix.dm.Service;
 import org.apache.felix.dm.ServiceStateListener;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
 
 public abstract class AbstractDecorator  {
@@ -233,4 +235,21 @@
         }
         m_services.clear();
     }    
+    
+    public void configureAutoConfigState(Service target, Service source) {
+        configureAutoConfigState(target, source, BundleContext.class);
+        configureAutoConfigState(target, source, ServiceRegistration.class);
+        configureAutoConfigState(target, source, DependencyManager.class);
+        configureAutoConfigState(target, source, Service.class);
+    }
+
+    private void configureAutoConfigState(Service target, Service source, Class clazz) {
+        String name = source.getAutoConfigInstance(clazz);
+        if (name != null) {
+            target.setAutoConfig(clazz, name);
+        }
+        else {
+            target.setAutoConfig(clazz, source.getAutoConfig(clazz));
+        }
+    }
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
index 725c704..e4f6b25 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
@@ -85,6 +85,8 @@
                      .setService(m_adapteeInterface, ref)
                      .setRequired(true));
             
+            configureAutoConfigState(service, m_service);
+            
             for (int i = 0; i < dependencies.size(); i++) {
                 service.add(((Dependency) dependencies.get(i)).createCopy());
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
index 2076ad4..26196bb 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
@@ -88,6 +88,8 @@
                 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
                 .add(getAspectDependency());
             
+            configureAutoConfigState(service, m_service);
+            
             for (int i = 0; i < dependencies.size(); i++) {
                 service.add(((Dependency) dependencies.get(i)).createCopy());
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java
index 896f529..05a1a9f 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java
@@ -260,4 +260,22 @@
     public DependencyManager getDependencyManager() {
         return m_service.getDependencyManager();
     }
+
+    public Service setAutoConfig(Class clazz, boolean autoConfig) {
+        m_service.setAutoConfig(clazz, autoConfig);
+        return this;
+    }
+
+    public Service setAutoConfig(Class clazz, String instanceName) {
+        m_service.setAutoConfig(clazz, instanceName);
+        return this;
+    }
+    
+    public boolean getAutoConfig(Class clazz) {
+        return m_service.getAutoConfig(clazz);
+    }
+    
+    public String getAutoConfigInstance(Class clazz) {
+        return m_service.getAutoConfigInstance(clazz);
+    };
 }
\ No newline at end of file
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
index d72c18c..9e1966b 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
@@ -33,13 +33,13 @@
 import java.util.Properties;
 
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.Service;
 import org.apache.felix.dm.ServiceComponent;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.ServiceStateListener;
-import org.apache.felix.dm.impl.dependencies.DependencyActivation;
-import org.apache.felix.dm.impl.dependencies.DependencyService;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
@@ -768,13 +768,24 @@
     	}
     }
 
-    public void setAutoConfig(Class clazz, boolean autoConfig) {
+    public synchronized Service setAutoConfig(Class clazz, boolean autoConfig) {
         m_autoConfig.put(clazz, Boolean.valueOf(autoConfig));
+        return this;
     }
     
-    public void setAutoConfig(Class clazz, String instanceName) {
+    public synchronized Service setAutoConfig(Class clazz, String instanceName) {
         m_autoConfig.put(clazz, Boolean.valueOf(instanceName != null));
         m_autoConfigInstance.put(clazz, instanceName);
+        return this;
+    }
+    
+    public boolean getAutoConfig(Class clazz) {
+        Boolean result = (Boolean) m_autoConfig.get(clazz);
+        return (result != null && result.booleanValue());
+    }
+    
+    public String getAutoConfigInstance(Class clazz) {
+        return (String) m_autoConfigInstance.get(clazz);
     }
     
     private void configureService(State state) {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
index 0482cec..07b90bb 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
@@ -26,6 +26,7 @@
 
 import org.apache.felix.dm.BundleDependency;
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
 import org.apache.felix.dm.impl.InvocationUtil;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
index 267cd85..3ffb0d4 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
@@ -28,6 +28,8 @@
 
 import org.apache.felix.dm.ConfigurationDependency;
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.PropertyMetaData;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.impl.InvocationUtil;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyActivation.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyActivation.java
deleted file mode 100644
index 189e0a0..0000000
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyActivation.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.apache.felix.dm.impl.dependencies;
-
-public interface DependencyActivation {
-  public void start(DependencyService service);
-  public void stop(DependencyService service);
-}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
index 70217c5..a3a1f7a 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
@@ -1,6 +1,7 @@
 package org.apache.felix.dm.impl.dependencies;
 
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
 import org.apache.felix.dm.impl.Logger;
 
 public abstract class DependencyBase implements Dependency, DependencyActivation {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
index df09ddc..d074404 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
@@ -26,6 +26,8 @@
 import java.util.Properties;
 
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.ResourceDependency;
 import org.apache.felix.dm.ResourceHandler;
 import org.apache.felix.dm.Service;
@@ -95,10 +97,14 @@
 	        }
 	    }
 	    if (needsStarting) {
-	        Properties props = null;
-	        if (m_resourceFilter != null) {
+	        Dictionary props = null;
+	        if (m_trackedResource != null) {
+                props = new Properties();
+                props.put(ResourceHandler.URL, m_trackedResource);
+	        }
+	        else if (m_resourceFilter != null) {
 	            props = new Properties();
-	            props.setProperty(ResourceHandler.FILTER, m_resourceFilter);
+	            props.put(ResourceHandler.FILTER, m_resourceFilter);
 	        }
 	        m_registration = m_context.registerService(ResourceHandler.class.getName(), this, props);
 	    }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
index 76a3306..2e87c95 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
@@ -32,6 +32,7 @@
 import java.util.Set;
 
 import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.ServiceDependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/TemporalServiceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/TemporalServiceDependencyImpl.java
index 3a54c4b..6aeafc3 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/TemporalServiceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/TemporalServiceDependencyImpl.java
@@ -16,6 +16,7 @@
 import java.lang.reflect.Proxy;
 
 import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyService;
 import org.apache.felix.dm.TemporalServiceDependency;
 import org.apache.felix.dm.impl.Logger;
 import org.osgi.framework.BundleContext;