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;