Follow up on FELIX-3621
The runtime must also adapts its method id computation.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1387917 13f79535-47bb-0310-9956-ffa450edef68
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 063ae2b..eb2e9eb 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
@@ -23,6 +23,7 @@
import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
/**
* A Method Metadata represents a method from the implementation class.
@@ -99,13 +100,16 @@
StringBuffer identifier = new StringBuffer(m_name);
for (int i = 0; i < m_arguments.length; i++) {
String arg = m_arguments[i];
- identifier.append('$');
if (arg.endsWith("[]")) {
- arg = arg.substring(0, arg.length() - 2);
- identifier.append(arg.replace('.', '_'));
- identifier.append("__"); // Replace [] by __
+ // We have to replace all []
+ String acc = "";
+ while (arg.endsWith("[]")) {
+ arg = arg.substring(0, arg.length() - 2);
+ acc += "__";
+ }
+ identifier.append("$" + arg.replace('.', '_') + acc);
} else {
- identifier.append(arg.replace('.', '_'));
+ identifier.append("$" + arg.replace('.', '_'));
}
}
return identifier.toString();
@@ -122,14 +126,27 @@
for (int i = 0; i < args.length; i++) {
identifier.append('$'); // Argument separator.
if (args[i].isArray()) {
+ String acc = "__";
if (args[i].getComponentType().isPrimitive()) {
// Primitive array
identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+ } else if (args[i].getComponentType().isArray()) {
+ // Multi-directional array.
+ Class current = args[i].getComponentType();
+ while (current.isArray()) {
+ acc += "__";
+ current = current.getComponentType();
+ }
+ if (current.isPrimitive()) {
+ acc = FieldMetadata.getPrimitiveTypeByClass(current) + acc;
+ } else {
+ acc = current.getName().replace('.', '_') + acc;
+ }
} else {
// Object array
identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
}
- identifier.append("__"); // Add __ (array)
+ identifier.append(acc); // Add __ (array)
} else {
if (args[i].isPrimitive()) {
// Primitive type
@@ -160,14 +177,22 @@
identifier.append('$'); // Argument separator.
if (args[i].isArray()) {
+ String acc = "__";
if (args[i].getComponentType().isPrimitive()) {
// Primitive array
identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+ } else if (args[i].getComponentType().isArray()) {
+ // Multi-directional array.
+ Class current = args[i].getComponentType();
+ while (current.isArray()) {
+ acc += "__";
+ current = current.getComponentType();
+ }
} else {
// Object array
identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
}
- identifier.append("__"); // Add __ (array)
+ identifier.append(acc); // Add __ (array)
} else {
if (args[i].isPrimitive()) {
// Primitive type
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java
new file mode 100644
index 0000000..203f1d9
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java
@@ -0,0 +1,109 @@
+package org.apache.felix.ipojo.parser;
+
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.lang.reflect.Method;
+
+public class MethodMetadataTest extends TestCase {
+
+ public void testIdComputationForArrays() throws NoSuchMethodException {
+ Method method = this.getClass().getMethod("withOneArray", new String[0].getClass());
+ String id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withOneArray$java_lang_String__", id);
+
+ method = this.getClass().getMethod("withDoubleArray", new String[0][0].getClass());
+ id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withDoubleArray$java_lang_String____", id);
+
+ method = this.getClass().getMethod("withTripleArray", new String[0][0][0].getClass());
+ id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withTripleArray$java_lang_String______", id);
+ }
+
+ public void testIdComputationForArraysUsingPrimitive() throws NoSuchMethodException {
+ Method method = this.getClass().getMethod("withPrimitiveArray", new int[0].getClass());
+ String id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withPrimitiveArray$int__", id);
+
+ method = this.getClass().getMethod("withPrimitiveArray", new int[0][0].getClass());
+ id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withPrimitiveArray$int____", id);
+
+ method = this.getClass().getMethod("withPrimitiveArray", new int[0][0][0].getClass());
+ id = MethodMetadata.computeMethodId(method);
+ Assert.assertEquals("withPrimitiveArray$int______", id);
+ }
+
+ public void testComputationForArraysUsingObjectsFromElement() {
+ Element metadata1 = new Element("method", null);
+ metadata1.addAttribute(new Attribute("name", "withOneArray"));
+ metadata1.addAttribute(new Attribute("arguments", "{java.lang.String[]}"));
+
+ Element metadata2 = new Element("method", null);
+ metadata2.addAttribute(new Attribute("name", "withOneArray"));
+ metadata2.addAttribute(new Attribute("arguments", "{java.lang.String[][]}"));
+
+ Element metadata3 = new Element("method", null);
+ metadata3.addAttribute(new Attribute("name", "withOneArray"));
+ metadata3.addAttribute(new Attribute("arguments", "{java.lang.String[][][]}"));
+
+ MethodMetadata methodMetadata1 = new MethodMetadata(metadata1);
+ Assert.assertEquals("withOneArray$java_lang_String__", methodMetadata1.getMethodIdentifier());
+
+ MethodMetadata methodMetadata2 = new MethodMetadata(metadata2);
+ Assert.assertEquals("withOneArray$java_lang_String____", methodMetadata2.getMethodIdentifier());
+
+ MethodMetadata methodMetadata3 = new MethodMetadata(metadata3);
+ Assert.assertEquals("withOneArray$java_lang_String______", methodMetadata3.getMethodIdentifier());
+ }
+
+ public void testComputationForArraysUsingPrimitiveFromElement() {
+ Element metadata1 = new Element("method", null);
+ metadata1.addAttribute(new Attribute("name", "withOneArray"));
+ metadata1.addAttribute(new Attribute("arguments", "{int[]}"));
+
+ Element metadata2 = new Element("method", null);
+ metadata2.addAttribute(new Attribute("name", "withOneArray"));
+ metadata2.addAttribute(new Attribute("arguments", "{int[][]}"));
+
+ Element metadata3 = new Element("method", null);
+ metadata3.addAttribute(new Attribute("name", "withOneArray"));
+ metadata3.addAttribute(new Attribute("arguments", "{int[][][]}"));
+
+ MethodMetadata methodMetadata1 = new MethodMetadata(metadata1);
+ Assert.assertEquals("withOneArray$int__", methodMetadata1.getMethodIdentifier());
+
+ MethodMetadata methodMetadata2 = new MethodMetadata(metadata2);
+ Assert.assertEquals("withOneArray$int____", methodMetadata2.getMethodIdentifier());
+
+ MethodMetadata methodMetadata3 = new MethodMetadata(metadata3);
+ Assert.assertEquals("withOneArray$int______", methodMetadata3.getMethodIdentifier());
+ }
+
+
+ // Method analyzed for testing
+
+ public void withOneArray(String[] arr) { }
+ public void withPrimitiveArray(int[] arr) { }
+ public void withDoubleArray(String[][] arr) { }
+ public void withPrimitiveArray(int[][] arr) { }
+ public void withPrimitiveArray(int[][][] arr) { }
+ public void withTripleArray(String[][][] arr) { }
+
+ public MethodMetadataTest() {
+ super();
+ }
+
+ // Constructor used for testing
+ public MethodMetadataTest(String[] arr) { }
+ public MethodMetadataTest(String[][] arr) { }
+ public MethodMetadataTest(int[] arr) { }
+ public MethodMetadataTest(int[][] arr) { }
+ public MethodMetadataTest(int[][][] arr) { }
+
+
+}