FELIX-4215 Extend manipulation metadata with argument names
Extract argument's name from the byte code (local variables) and extends the MethodMetadata to handle them.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1520078 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
index 84509ea..a477560 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
@@ -19,12 +19,8 @@
package org.apache.felix.ipojo.manipulation;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
import org.apache.felix.ipojo.manipulation.ClassChecker.AnnotationDescriptor;
import org.apache.felix.ipojo.metadata.Attribute;
import org.apache.felix.ipojo.metadata.Element;
@@ -85,6 +81,12 @@
private final boolean m_isStatic;
/**
+ * The local variables by index.
+ * This map is used to detect the argument names.
+ */
+ private LinkedHashMap<Integer, LocalVariableNode> m_locals = new LinkedHashMap<Integer, LocalVariableNode>();
+
+ /**
* Constructor.
* @param name : name of the method.
* @param desc : descriptor of the method.
@@ -164,13 +166,23 @@
// Add arguments
if (m_arguments.length > 0) {
- StringBuffer args = new StringBuffer("{");
+ StringBuilder args = new StringBuilder("{");
+ StringBuilder names = new StringBuilder("{");
args.append(m_arguments[0]);
+ if (m_locals.containsKey(1)) {
+ names.append(m_locals.get(1).name); // index +1 as the 0 is this
+ }
for (int i = 1; i < m_arguments.length; i++) {
- args.append("," + m_arguments[i]);
+ args.append(",").append(m_arguments[i]);
+ if (m_locals.containsKey(i +1)) {
+ names.append(",").append(m_locals.get(i +1).name);
+ }
}
args.append("}");
+ names.append("}");
+
method.addAttribute(new Attribute("arguments", args.toString()));
+ method.addAttribute(new Attribute("names", names.toString()));
}
return method;
@@ -221,6 +233,7 @@
}
public void addLocalVariable(String name, String desc, String signature, int index) {
+ m_locals.put(index, new LocalVariableNode(name, desc, signature, null, null, index));
if (index >= m_argsVarLength) {
// keep only argument-related local variables definitions (others relate to code which isn't in this method)
return;
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
index eb2e9eb..0002611 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
@@ -20,6 +20,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+import java.util.Map;
import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.metadata.Element;
@@ -47,20 +49,27 @@
*/
public static final String CONSTRUCTOR_PREFIX = "$init";
+
/**
* The name of the method.
*/
- private String m_name;
+ private final String m_name;
/**
* The argument type array.
*/
- private String[] m_arguments = new String[0];
+ private final String[] m_arguments;
/**
* The returned type.
*/
- private String m_return = "void";
+ private final String m_return;
+
+ /**
+ * The argument names if there were contained in the manifest.
+ * @since 1.10.2
+ */
+ private final String[] m_names;
/**
* Creates a Method Metadata.
@@ -69,12 +78,23 @@
MethodMetadata(Element metadata) {
m_name = metadata.getAttribute("name");
String arg = metadata.getAttribute("arguments");
+ String names = metadata.getAttribute("names");
String result = metadata.getAttribute("return");
if (arg != null) {
m_arguments = ParseUtils.parseArrays(arg);
+ } else {
+ m_arguments = new String[0];
}
+ if (names != null) {
+ m_names = ParseUtils.parseArrays(names);
+ } else {
+ m_names = new String[0];
+ }
+
if (result != null) {
m_return = result;
+ } else {
+ m_return = "void";
}
}
@@ -86,6 +106,24 @@
return m_arguments;
}
+ public String[] getMethodArgumentNames() {
+ return m_names;
+ }
+
+ /**
+ * Gets the method arguments.
+ * The keys are the argument names, while the values are the argument type.
+ * @return the map of argument
+ * @since 1.10.2
+ */
+ public Map<String, String> getArguments() {
+ LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+ for (int i = 0; i < m_names.length; i++) {
+ map.put(m_names[i], m_arguments[i]);
+ }
+ return map;
+ }
+
public String getMethodReturn() {
return m_return;
}