Fix FELIX-2580 iPOJO failed to create proxies on service which are not interface
and add a test.

Disabling proxies when a scalar dependency target a concrete or abstract class.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@995124 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 159182d..98834dd 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -52,32 +52,32 @@
      * Proxy settings property.
      */
     public static final String PROXY_SETTINGS_PROPERTY = "ipojo.proxy";
-    
+
     /**
      * Proxy type property.
      */
     public static final String PROXY_TYPE_PROPERTY = "ipojo.proxy.type";
-    
+
     /**
      * Proxy type value: smart.
      */
     public static final String SMART_PROXY = "smart";
-    
+
     /**
      * Proxy type value: dynamic-proxy.
      */
     public static final String DYNAMIC_PROXY = "dynamic-proxy";
-    
+
     /**
      * Proxy settings value: enabled.
      */
     public static final String PROXY_ENABLED = "enabled";
-    
+
     /**
      * Proxy settings value: disabled.
      */
     public static final String PROXY_DISABLED = "disabled";
-    
+
     /**
      * Dependency field type : Vector
      * The dependency will be injected as a vector.
@@ -89,7 +89,7 @@
      * The dependency will be injected as a list.
      */
     protected static final int LIST = 1;
-    
+
     /**
      * Dependency Field Type : Set.
      * The dependency will be injected as a set.
@@ -105,7 +105,7 @@
      * Is the handler started.
      */
     private boolean m_started;
-    
+
     /**
      * The handler description.
      */
@@ -204,7 +204,7 @@
      * @return true if the dependency is valid
      * @throws ConfigurationException : the checked dependency is not correct
      */
-    private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {       
+    private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
         // Check the internal type of dependency
         String field = dep.getField();
         DependencyCallback[] callbacks = dep.getCallbacks();
@@ -284,7 +284,16 @@
             }
             setSpecification(dep, type, true); // Throws an exception if the field type mismatch.
         }
-        
+
+        // Disable proxy on scalar dependency targeting non-interface specification
+        if (! dep.isAggregate()  && dep.isProxy()) {
+        	if (! dep.getSpecification().isInterface()) {
+        		warn("Proxies cannot be used on service dependency targetting non interface " +
+        				"service specification " + dep.getSpecification().getName());
+        		dep.setProxy(false);
+        	}
+        }
+
         // Disables proxy on null (nullable=false)
 //        if (dep.isProxy()  && dep.isOptional() && ! dep.supportsNullable()) {
 //            dep.setProxy(false);
@@ -333,7 +342,7 @@
                             + "] are not the same");
                     }
                 }
-            
+
                 try {
                     dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
                 } catch (ClassNotFoundException e) {
@@ -358,15 +367,15 @@
 
         // Create the dependency according to the component metadata
         Element[] deps = componentMetadata.getElements("Requires");
-        
+
         // Get instance filters.
         Dictionary filtersConfiguration = (Dictionary) configuration.get("requires.filters");
         Dictionary fromConfiguration = (Dictionary) configuration.get("requires.from");
-        
+
         for (int i = 0; deps != null && i < deps.length; i++) {
             // Create the dependency metadata
             String field = deps[i].getAttribute("field");
-            
+
             String serviceSpecification = deps[i].getAttribute("interface");
             // the 'interface' attribute is deprecated
             if (serviceSpecification != null) {
@@ -374,7 +383,7 @@
             } else {
                 serviceSpecification = deps[i].getAttribute("specification");
             }
-            
+
             String filter = deps[i].getAttribute("filter");
             String opt = deps[i].getAttribute("optional");
             boolean optional = opt != null && opt.equalsIgnoreCase("true");
@@ -383,10 +392,10 @@
             String agg = deps[i].getAttribute("aggregate");
             boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
             String identitity = deps[i].getAttribute("id");
-            
+
             String nul = deps[i].getAttribute("nullable");
             boolean nullable = nul == null || nul.equalsIgnoreCase("true");
-            
+
             boolean isProxy = true;
             // Detect proxy default value.
             String setting = getInstanceManager().getContext().getProperty(PROXY_SETTINGS_PROPERTY);
@@ -395,7 +404,7 @@
             } else if (setting != null  && PROXY_DISABLED.equals(setting)) {
                 isProxy = false;
             }
-            
+
             String proxy = deps[i].getAttribute("proxy");
             // If proxy == null, use default value
             if (proxy != null) {
@@ -406,9 +415,9 @@
                         warn("The configuration of a service dependency overrides the proxy mode");
                     }
                     isProxy = true;
-                }   
+                }
             }
-            
+
             String scope = deps[i].getAttribute("scope");
             BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
             if (scope != null) {
@@ -449,7 +458,7 @@
                     filter = fromFilter;
                 }
             }
-            
+
             Filter fil = null;
             if (filter != null) {
                 try {
@@ -458,7 +467,7 @@
                     throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
                 }
             }
-            
+
 
             Class spec = null;
             if (serviceSpecification != null) {
@@ -468,7 +477,7 @@
             int policy = DependencyModel.getPolicy(deps[i]);
             Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
 
-            
+
             Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, nullable, isProxy, identitity, context, policy, cmp, defaultImplem);
 
             // Look for dependency callback :
@@ -510,7 +519,7 @@
                 }
             }
         }
-        
+
         m_description = new DependencyHandlerDescription(this, m_dependencies); // Initialize the description.
     }
 
@@ -522,7 +531,7 @@
         // Start the dependencies
         for (int i = 0; i < m_dependencies.length; i++) {
             Dependency dep = m_dependencies[i];
-           
+
             dep.start();
         }
         // Check the state
diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
index a318fdc..0803a30 100644
--- a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
@@ -1,4 +1,4 @@
-/* 

+/*

  * 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

@@ -62,6 +62,7 @@
         ots.addTestSuite(ProxiedCollectionMultipleDependencies.class);

         ots.addTestSuite(ModifyDependencies.class);

         ots.addTestSuite(ProxyTest.class);

+        ots.addTestSuite(NonProxiedNotInterfaceDependencies.class);

         return ots;

     }

 

diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java
new file mode 100644
index 0000000..b15e578
--- /dev/null
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java
@@ -0,0 +1,64 @@
+/*

+ * 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.ipojo.test.scenarios.service.dependency;

+

+import java.util.AbstractMap;

+import java.util.HashMap;

+

+import junit.framework.Assert;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.InstanceManager;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.junit4osgi.helpers.IPOJOHelper;

+import org.apache.felix.ipojo.test.scenarios.service.dependency.service.CheckService;

+import org.osgi.framework.ServiceRegistration;

+

+public class NonProxiedNotInterfaceDependencies extends OSGiTestCase {

+

+    InstanceManager instance1;

+    ComponentInstance fooProvider;

+

+    ServiceRegistration reg, reg2;

+    IPOJOHelper helper;

+

+    public void setUp() {

+    	helper = new IPOJOHelper(this);

+    	reg = context.registerService(String.class.getName(), "ahahah", null);

+    	reg2 = context.registerService(AbstractMap.class.getName(), new HashMap(), null);

+

+    }

+

+    public void tearDown() {

+    	if (reg != null) {

+    		reg.unregister();

+    	}

+    	if (reg2 != null) {

+    		reg2.unregister();

+    	}

+    }

+

+    public void testInstanceCreation() {

+    	instance1 = (InstanceManager) helper

+    		.createComponentInstance("org.apache.felix.ipojo.test.scenarios.service.dependency.proxy.CheckServiceUsingStringService");

+    	Assert.assertTrue(instance1.getState() == ComponentInstance.VALID);

+    	Assert.assertTrue(((CheckService) instance1.getPojoObject()).check());

+    }

+

+}

diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java
new file mode 100644
index 0000000..f822b95
--- /dev/null
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java
@@ -0,0 +1,28 @@
+package org.apache.felix.ipojo.test.scenarios.service.dependency.proxy;
+
+import java.util.AbstractMap;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.test.scenarios.service.dependency.service.CheckService;
+
+public class CheckServiceUsingStringService implements CheckService {
+
+    private String string;
+    private AbstractMap map;
+
+
+    public CheckServiceUsingStringService() {
+    	System.out.println("Service : " + string);
+    	System.out.println("Map : " + map);
+    }
+
+    public boolean check() {
+        return string != null
+        	&& map != null;
+    }
+
+    public Properties getProps() {
+    	return null;
+    }
+
+}
diff --git a/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml b/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
index 83fd97b..1571e43 100644
--- a/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
+++ b/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
@@ -1,5 +1,5 @@
 <ipojo>

-<!-- 

+<!--

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"

   xmlns="org.apache.felix.ipojo"

@@ -9,7 +9,7 @@
     name="FooProviderType-1" architecture="true">

     <provides />

   </component>

-  

+

   <!--  Simple Dependencies -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

@@ -71,7 +71,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

     name="ProxiedSimpleCheckServiceProvider" architecture="true">

@@ -132,7 +132,7 @@
     </requires>

     <provides />

   </component>

-  

+

 

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

@@ -296,7 +296,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

     name="ProxiedSimpleOptionalCheckServiceProvider" architecture="true">

@@ -356,8 +356,8 @@
       <callback type="unbind" method="propertiesDictionaryUnbind" />

     </requires>

     <provides />

-  </component>	

-  

+  </component>

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

     name="BothOptionalNoNullableCheckServiceProvider" architecture="true">

@@ -582,7 +582,7 @@
     <requires field="fs" />

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

     name="VoidMultipleCheckServiceProvider" architecture="true">

@@ -637,7 +637,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

     name="BothMultipleCheckServiceProvider" architecture="true">

@@ -674,7 +674,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

     name="DictMultipleCheckServiceProvider" architecture="true" >

@@ -693,7 +693,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

     name="MObjectMultipleCheckServiceProvider" architecture="true">

@@ -780,7 +780,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

     name="ProxiedSimpleOptionalMultipleCheckServiceProvider"

@@ -818,7 +818,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

     name="MObjectOptionalMultipleCheckServiceProvider"

@@ -841,7 +841,7 @@
     </requires>

     <provides />

   </component>

-  

+

   <!-- Aggregate dependency as List -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.ListCheckService"

@@ -854,7 +854,7 @@
     classname="org.apache.felix.ipojo.test.scenarios.component.ListCheckService"

     name="OptionalListCheckServiceProvider"

     architecture="true">

-    <requires proxy="false" 

+    <requires proxy="false"

       specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />

     <provides />

   </component>

@@ -871,7 +871,7 @@
     <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />

     <provides />

   </component>

-  

+

   <!-- Aggregate dependency as Vector -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.VectorCheckService"

@@ -889,7 +889,7 @@
     <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />

     <provides />

   </component>

-  

+

   <!-- Aggregate dependency as Set -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.SetCheckService"

@@ -917,7 +917,7 @@
     <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />

     <provides />

   </component>

-  

+

   <!-- Aggregate dependency as Collection -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"

@@ -935,7 +935,7 @@
     classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"

     name="OptionalCollectionCheckServiceProvider"

     architecture="true">

-    <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" 

+    <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"

       proxy="false"

     />

     <provides />

@@ -944,22 +944,22 @@
     classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"

     name="ProxiedOptionalCollectionCheckServiceProvider"

     architecture="true">

-    <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" 

+    <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"

       proxy="false"

     />

     <provides />

   </component>

-  

-  

+

+

   <!-- Modify method test -->

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType2"

     name="FooProviderType-Updatable" architecture="true">

     <provides>

-      <property name="foo" field="m_foo" value="foo"/> 

+      <property name="foo" field="m_foo" value="foo"/>

     </provides>

   </component>

-  

+

   <component

     classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

     name="VoidModifyCheckServiceProvider" architecture="true">

@@ -1034,7 +1034,15 @@
       <provides/>

       <requires field="fs" optional="true"/>

       <callback transition="validate" method="start"/>

-    <callback transition="invalidate" method="stop"/>  

+    <callback transition="invalidate" method="stop"/>

   </component>

-  

+

+  <component

+  	classname="org.apache.felix.ipojo.test.scenarios.service.dependency.proxy.CheckServiceUsingStringService"

+  	immediate="true">

+    <provides/>

+    <requires field="string"/>

+    <requires field="map"/>

+  </component>

+

 </ipojo>