Fix FELIX-3461 - Issue with collected metadata and manipulation metadata on re-manipulation
* Fix the constructor argument shift by not moving the annotations
* Fix the method name when it is a manipulated method
* Cleanup the manipulation metadata
(forgot to add files in my first commit)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1327154 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatedClassLoader.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatedClassLoader.java
new file mode 100644
index 0000000..f0f5c15
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatedClassLoader.java
@@ -0,0 +1,26 @@
+package org.apache.felix.ipojo.manipulation;
+
+/**
+ * A classloader used to load manipulated classes.
+ */
+class ManipulatedClassLoader extends ClassLoader {
+
+ private String name;
+ private byte[] clazz;
+
+ public ManipulatedClassLoader(String name, byte[] clazz) {
+ this.name = name;
+ this.clazz = clazz;
+ }
+
+ public Class findClass(String name) throws ClassNotFoundException {
+ if (name.equals(this.name)) {
+ return defineClass(name, clazz, 0, clazz.length);
+ }
+ return super.findClass(name);
+ }
+
+ public Class loadClass(String arg0) throws ClassNotFoundException {
+ return super.loadClass(arg0);
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/RemanipulationTest.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/RemanipulationTest.java
new file mode 100644
index 0000000..1b8945c
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/RemanipulationTest.java
@@ -0,0 +1,136 @@
+package org.apache.felix.ipojo.manipulation;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.AnnotationMetadataProvider;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * Test Case for FELIX-3461.
+ * Checks the consistency of multiple manipulation.
+ */
+public class RemanipulationTest extends TestCase {
+
+ /**
+ * Tests checking that the consecutive manipulation does still returns valid metadata (from annotations),
+ * and valid manipulation metadata.
+ *
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ public void testDoubleManipulationWithAnnotations() throws IOException, ClassNotFoundException {
+ Reporter reporter = mock(Reporter.class);
+ // Step 1 - First collection and manipulation
+ //1.1 Metadata collection
+ MiniStore store = new MiniStore()
+ .addClassToStore("test.PlentyOfAnnotations",
+ ManipulatorTest.getBytesFromFile(new File("target/test-classes/test/PlentyOfAnnotations.class")));
+ AnnotationMetadataProvider provider = new AnnotationMetadataProvider(store, reporter);
+ List<Element> originalMetadata = provider.getMetadatas();
+ // 1.2 Manipulation
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(
+ ManipulatorTest.getBytesFromFile(new File("target/test-classes/test/PlentyOfAnnotations.class")));
+ Element originalManipulationMetadata = manipulator.getManipulationMetadata();
+ // 1.3 Check that the class is valid
+ ManipulatedClassLoader classloader = new ManipulatedClassLoader("test.PlentyOfAnnotations", clazz);
+ Class cl = classloader.findClass("test.PlentyOfAnnotations");
+ Assert.assertNotNull(cl);
+
+ // ---------------
+
+ // Step 2 - Second collection and manipulation
+ // We use the output class as entry.
+ // 2.1 Metadata collection
+ store = new MiniStore().addClassToStore("test.PlentyOfAnnotations", clazz);
+ provider = new AnnotationMetadataProvider(store, reporter);
+ List<Element> metadataAfterOneManipulation = provider.getMetadatas();
+ // 2.2 Manipulation
+ manipulator = new Manipulator();
+ byte[] clazz2 = manipulator.manipulate(clazz);
+ Element manipulationMetadataAfterSecondManipulation = manipulator.getManipulationMetadata();
+ // 2.3 Check that the class is valid
+ classloader = new ManipulatedClassLoader("test.PlentyOfAnnotations", clazz);
+ cl = classloader.findClass("test.PlentyOfAnnotations");
+ Assert.assertNotNull(cl);
+
+ // ---------------
+
+ // Step 3 - Third collection and manipulation
+ // We use the output class of 2 as entry.
+ // 3.1 Metadata collection
+ store = new MiniStore().addClassToStore("test.PlentyOfAnnotations", clazz2);
+ provider = new AnnotationMetadataProvider(store, reporter);
+ List<Element> metadataAfterTwoManipulation = provider.getMetadatas();
+ // 3.2 Manipulation
+ manipulator = new Manipulator();
+ byte[] clazz3 = manipulator.manipulate(clazz2);
+ Element manipulationMetadataAfterThirdManipulation = manipulator.getManipulationMetadata();
+ // 3.3 Check that the class is valid
+ classloader = new ManipulatedClassLoader("test.PlentyOfAnnotations", clazz);
+ cl = classloader.findClass("test.PlentyOfAnnotations");
+ Assert.assertNotNull(cl);
+
+ // ---------------
+ // Verification
+
+ // Unchanged metadata
+ Assert.assertEquals(originalMetadata.toString(), metadataAfterOneManipulation.toString());
+ Assert.assertEquals(originalMetadata.toString(), metadataAfterTwoManipulation.toString());
+
+ // Unchanged manipulation metadata
+ Assert.assertEquals(originalManipulationMetadata.toString(),
+ manipulationMetadataAfterSecondManipulation.toString());
+ Assert.assertEquals(originalManipulationMetadata.toString(),
+ manipulationMetadataAfterThirdManipulation.toString());
+
+ }
+
+ private class MiniStore implements ResourceStore {
+
+ private Map<String, byte[]> resources;
+
+ public MiniStore addClassToStore(String qualifiedName, byte[] bytes) {
+ if (this.resources == null) {
+ this.resources = new HashMap<String, byte[]>();
+ }
+ this.resources.put(Strings.asResourcePath(qualifiedName), bytes);
+ return this;
+ }
+
+ public byte[] read(String path) throws IOException {
+ return resources.get(path);
+ }
+
+ public void accept(ResourceVisitor visitor) {
+ for (Map.Entry<String, byte[]> entry : resources.entrySet()) {
+ visitor.visit(entry.getKey());
+ }
+ }
+
+ public void open() throws IOException {
+ }
+
+ public void writeMetadata(Element metadata) {
+ }
+
+ public void write(String resourcePath, byte[] resource) throws IOException {
+ }
+
+ public void close() throws IOException {
+ }
+ }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/test/PlentyOfAnnotations.java b/ipojo/manipulator/manipulator/src/test/java/test/PlentyOfAnnotations.java
new file mode 100644
index 0000000..3697920
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/test/PlentyOfAnnotations.java
@@ -0,0 +1,40 @@
+package test;
+
+import org.apache.felix.ipojo.annotations.*;
+import test.ipojo.ExternalHandler;
+
+import java.util.List;
+
+@Component
+@Instantiate
+public class PlentyOfAnnotations {
+
+ @Requires
+ List list;
+ private String m_prop;
+ private Runnable m_runnable;
+ private String m_stuff;
+
+ @ExternalHandler
+ private String stuff2;
+
+
+ PlentyOfAnnotations(@Property String prop, @Requires Runnable runnable, @ExternalHandler String stuff) {
+
+ m_prop = prop;
+ m_runnable = runnable;
+ m_stuff = stuff;
+
+ }
+
+ @Validate
+ public void start() {
+ //...
+ }
+
+ @ExternalHandler
+ public void stuff() {
+ // ...
+ }
+
+}