Applied patches (FELIX-251) to add more support for reflecting on the 
POJOs.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@519012 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
index 315b16b..289ccb9 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
@@ -18,7 +18,9 @@
  */
 package org.apache.felix.ipojo.manipulation;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.Attribute;
@@ -44,6 +46,11 @@
 	 * Field hashmap [field name, type] discovered in the component class.
 	 */
 	private HashMap m_fields = new HashMap();
+	
+	/**
+	 * Method List of method descriptor discovered in the component class. 
+	 */
+	private List m_methods = new ArrayList()/*<MethodDesciptor>*/;
 
 	/** Check if the _cm field already exists.
 	 * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
@@ -77,7 +84,7 @@
      */
     public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)  {
     	//Store the interfaces :
-        m_itfs = interfaces;
+    	m_itfs = interfaces;
     }
 
     /**
@@ -108,7 +115,10 @@
     /**
      * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
      */
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return null; }
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 
+    	if(!name.equals("<init>")) { m_methods.add(new MethodDescriptor(name, desc)); }
+    	return null; 
+    }
 
     /**
      * @see org.objectweb.asm.ClassVisitor#visitEnd()
@@ -123,10 +133,18 @@
     }
 
 	/**
-	 * @return the field hashmap [field_name, type]
+	 * @return the field hashmap [field_name, type].
 	 */
 	public HashMap getFields() {
 		return m_fields;
 	}
+	
+	
+	/**
+	 * @return the method list of [method, signature].
+	 */
+	public List getMethods() {
+		return m_methods;
+	}
 
 }
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index 0b7c4bc..30fb273 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -22,7 +22,9 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.logging.Level;
 
 import org.apache.felix.ipojo.plugin.IPojoPluginConfiguration;
@@ -44,6 +46,11 @@
 	 * Store the interface implemented by the class.
 	 */
 	private String[] m_interfaces = new String[0];
+	
+	/**
+	 * Store the methods list.
+	 */
+	private List m_methods = new ArrayList();
 
 	/**
 	 * Return the hashmap [name of the field, type of the field].
@@ -62,6 +69,11 @@
 	 * @return the hashmap [name of the field, type of the field].
 	 */
 	public String[] getInterfaces() { return (String[])m_interfaces.clone(); }
+	
+	/**
+	 * @return the method list.
+	 */
+	public List getMethods() { return m_methods; }
 
 	/**
      * Manipulate the class.
@@ -91,9 +103,31 @@
         is1.close();
         
         m_fields = ck.getFields();
-        m_interfaces = new String[ck.getInterfaces().length];
+        
+        // Get interface and remove POJO interface is presents
+        String[] its = ck.getInterfaces();
+        ArrayList l = new ArrayList();
+        for(int i = 0; i < its.length; i++) {
+        	l.add(its[i]);
+        }
+        l.remove("org/apache/felix/ipojo/Pojo");
+        
+        m_interfaces = new String[l.size()];
         for (int i = 0; i < m_interfaces.length; i++) {
-        	m_interfaces[i] = ck.getInterfaces()[i].replace('/', '.');
+        	m_interfaces[i] = ((String) l.get(i)).replace('/', '.');
+        }
+        
+        
+        // Get the method list
+        // Remove iPOJO methods
+        for(int i = 0; i < ck.getMethods().size(); i++) {
+        	MethodDescriptor method = (MethodDescriptor) ck.getMethods().get(i);
+        	if(!(method.getName().startsWith("_get") ||  //Avoid getter method 
+        			method.getName().startsWith("_set") || // Avoid setter method
+        			method.getName().equals("_setComponentManager") || // Avoid the set method
+        			method.getName().equals("getComponentInstance"))){ // Avoid the getComponentInstance method
+        		m_methods.add(method);
+        	}
         }
         
         if(!ck.isalreadyManipulated()) {
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
new file mode 100644
index 0000000..7d1922d
--- /dev/null
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
@@ -0,0 +1,74 @@
+package org.apache.felix.ipojo.manipulation;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
+
+public class MethodDescriptor {
+	
+	private String m_name;
+	private String m_returnType;
+	private String[] m_arguments;
+	
+	public MethodDescriptor(String name, String desc) {
+		m_name = name;
+		Type ret = Type.getReturnType(desc);
+		Type[] args = Type.getArgumentTypes(desc);
+		
+		m_returnType = getType(ret);
+		m_arguments = new String[args.length];
+		for(int i = 0; i < args.length; i++) {
+			m_arguments[i] = getType(args[i]);
+		}
+	}
+
+	public Element getElement() {
+		Element method = new Element("method", "");
+		method.addAttribute(new Attribute("name", m_name));
+		method.addAttribute(new Attribute("return", m_returnType));
+		String args = "{";
+		if(m_arguments.length > 0) {
+			args += m_arguments[0];
+			for(int i = 1; i < m_arguments.length; i++) {
+				args += "," + m_arguments[i];
+			}
+		}
+		args += "}";
+		method.addAttribute(new Attribute("arguments", args));
+		return method;
+	}
+	
+	
+	private String getType(Type type) {
+		switch(type.getSort()) {
+		case Type.ARRAY : 
+			Type elemType = type.getElementType();
+			return getType(elemType)+"[]";
+		case Type.BOOLEAN : 
+			return "boolean";
+		case Type.BYTE :
+			return "byte";
+		case Type.CHAR : 
+			return "char";
+		case Type.DOUBLE : 
+			return "double";
+		case Type.FLOAT : 
+			return "float";
+		case Type.INT : 
+			return "int";
+		case Type.LONG : 
+			return "long";
+		case Type.OBJECT : 
+			return type.getClassName();
+		case Type.SHORT : 
+			return "short";
+		case Type.VOID : 
+			return "void";
+		default : 
+			return "unknown";
+		}
+	}
+	
+	public String getName() { return m_name; }
+
+}
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
index b3f926b..ef7014a 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
@@ -41,6 +41,9 @@
  *
  */
 public class PreprocessClassAdapter extends ClassAdapter implements Opcodes {
+	
+	
+		private final String POJO_INTERFACE =  "org/apache/felix/ipojo/Pojo";
 
         /**
          * The owner.
@@ -84,8 +87,33 @@
             
             // Create the _cmSetter(ComponentManager cm) method
             createComponentManagerSetter();
+            
+            // Add the getComponentInstance
+            createGetComponentInstanceMethod();
+            
+            // Add the POJO interface to the interface list
+            // Check that the POJO interface isnot already in the list
+            boolean found = false;
+            for(int i = 0; i < interfaces.length; i++) {
+            	if(interfaces[i].equals(POJO_INTERFACE)) { found = true; }
+            }
+            String[] itfs;
+            if(!found) {
+            	itfs = new String[interfaces.length + 1];
+            	for(int i = 0; i < interfaces.length; i++) {
+                	itfs[i] = interfaces[i];
+                }
+            	itfs[interfaces.length] = POJO_INTERFACE;
+            } else {
+            	itfs = interfaces;
+            }
+            
+            String str = "";
+            for(int i = 0; i < itfs.length; i++) {
+            	str += itfs[i] + " ";
+            }
 
-            super.visit(version, access, name, signature, superName, interfaces);
+            super.visit(version, access, name, signature, superName, itfs);
         }
         
 
@@ -140,6 +168,20 @@
             mv.visitMaxs(0, 0);
             mv.visitEnd();
         }
+        
+        /**
+         * Create the getComponentInstance method.
+         */
+        private void createGetComponentInstanceMethod() {
+        	MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getComponentInstance", "()Lorg/apache/felix/ipojo/ComponentInstance;", null, null);
+        	
+        	mv.visitVarInsn(ALOAD, 0);
+        	mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        	mv.visitInsn(ARETURN);
+        	
+        	mv.visitMaxs(0, 0);
+        	mv.visitEnd();
+        }
 
         /** visit Field method.
          * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
index 4acf4d4..29b9659 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/OsgiJarMojo.java
@@ -35,6 +35,7 @@
 import java.net.URL;
 
 import org.apache.felix.ipojo.manipulation.Manipulator;
+import org.apache.felix.ipojo.manipulation.MethodDescriptor;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
@@ -940,7 +941,6 @@
 		if(namespaces == null) { namespaces = new String[original_meta.length][]; } //NO
         for(int i = 0; i < original_meta.length; i++) {
         	if(original_meta[i].getName().equalsIgnoreCase("component")) { 
-        		getLog().info("Component Class Name : " + original_meta[i].getAttribute("className"));
         		namespaces[i] = original_meta[i].getNamespaces(); 
         		try {
         			manipulator.preProcess(original_meta[i].getAttribute("className"), outputDirectory);
@@ -949,7 +949,6 @@
         			throw new MojoExecutionException("[iPOJO] Manipulation error in the class : " + original_meta[i].getAttribute("className"));
         		}
         	
-        		getLog().info("Add manipulation metadata for : " + original_meta[i].getAttribute("className"));
         		// Insert information to metadata
         		Element elem = new Element("Manipulation", "");
         		for(int j = 0; j < manipulator.getInterfaces().length; j++) {
@@ -970,6 +969,11 @@
         			field.addAttribute(attType);
         			elem.addElement(field);
         		}
+        		
+        		for(int j= 0; j < manipulator.getMethods().size(); j++) {
+        			MethodDescriptor method = (MethodDescriptor) manipulator.getMethods().get(j);
+        			elem.addElement(method.getElement());
+        		}
 
         		original_meta[i].addElement(elem);
         	} else { namespaces[i] = new String[0]; }
@@ -980,13 +984,11 @@
         	meta = meta + metadata[i];
         }
         
-        getLog().info("Metadata of the bundles : " + meta);
 	    archiveConfig.addManifestEntry("iPOJO-Components", meta);
 	        
-	    getLog().info("Set the bundle activator");
 	    setBundleActivator();
 			
-	    getLog().info("iPOJO Manipulation ... SUCCESS");
+	    getLog().info("iPOJO Packaging ... SUCCESS");
 	}
 
 	private String buildManifestMetadata(Element element, String actual) {
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
index 299c058..3fd4acd 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -21,6 +21,7 @@
 import java.util.Dictionary;
 
 import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -67,6 +68,11 @@
      * Each handler can participate to the component description.
      */
     ComponentDescription getComponentDescription();
+    
+    /**
+     * @return the instance description of the current instance
+     */
+    InstanceDescription getInstanceDescription();
 
     /**
      * @return the factory of the component instance.
@@ -95,6 +101,5 @@
      * @param configuration : the new configuration.
      */
     void reconfigure(Dictionary configuration);
-
-
+    
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index 4fdaf13..29e885f 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -118,8 +118,7 @@
         }
 
         // ComponentInfo initialization
-        m_componentDesc = new ComponentDescription();
-        m_componentDesc.setClassName(m_className);
+        m_componentDesc = new ComponentDescription(m_factory.getName(), m_className);
         
         // Add the name
         m_name = (String) configuration.get("name");
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/Pojo.java b/ipojo/src/main/java/org/apache/felix/ipojo/Pojo.java
new file mode 100644
index 0000000..bf5d5d8
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/Pojo.java
@@ -0,0 +1,33 @@
+/* 
+ * 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;
+
+/**
+ * Interface implemented by each object created through an manipulated class.
+ * This interface allow to get the component instance from the object.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public interface Pojo {
+	
+	/**
+	 * @return the component instance who create this object.
+	 */
+	ComponentInstance getComponentInstance();
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
index ab702b2..8598404 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
@@ -40,11 +40,26 @@
     private PropertyDescription[] m_properties = new PropertyDescription[0];
 
     /**
+     * Get the name of this component type.
+     */
+    private String m_name;
+    
+    /**
+     * Constructor.
+     * @param name : name of the component type (factory name). 
+     * @param className : implementation class.
+     */
+    public ComponentDescription(String name, String className) {
+    	m_name = name;
+    	m_className = className;
+    }
+    
+    /**
      * @see java.lang.Object#toString()
      */
     public String toString() {
         String res = "";
-        res += "Component : " + m_className + "\n";
+        res += "Component Type : " + m_name + " (" + m_className + ") \n";
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             res += "\tProvides : " + m_providedServiceSpecification[i] + "\n";
         }
@@ -60,12 +75,6 @@
     public String getClassName() { return m_className; }
 
     /**
-     * Set the component type implementation class name.
-     * @param name : the name of the implementation class
-     */
-    public void setClassName(String name) { m_className = name; }
-
-    /**
      * @return the list of configuration properties accepted by the component type.
      */
     public PropertyDescription[] getProperties() { return m_properties; }
@@ -101,6 +110,11 @@
         m_providedServiceSpecification = newSs;
     }
     
+    /**
+     * @return the name of this component type
+     */
+    public String getName() { return m_name; }
+    
     
 
 
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
index 84ebf3b..19294f9 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
@@ -33,6 +33,9 @@
 		// Remove { and }
 		if (str.startsWith("{") && str.endsWith("}")) {
 			String m = str.substring(1, str.length() - 1);
+			// Check empty array
+			m = m.trim();
+			if (m.length() == 0) { return new String[0]; }
 			String[] values = m.split(",");
 			for (int i = 0; i < values.length; i++) {
 				values[i] = values[i].trim();
diff --git a/ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java b/ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
index dc0c6ec..6d5119f 100644
--- a/ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
+++ b/ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
@@ -18,7 +18,9 @@
 
 package org.osgi.service.cm;
 
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;