Integrate the constructor-injection branch into the trunk.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1052264 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/ComponentInstance.java
new file mode 100644
index 0000000..a81dea8
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -0,0 +1,12 @@
+package org.apache.felix.ipojo;
+
+
+/**
+ * Component Instance Fake.
+ * We're using a fake to avoid the cyclic build dependency:
+ * manipulator -> ipojo -> maven-ipojo-plugin -> manipulator
+ */
+public interface ComponentInstance {
+
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/InstanceManager.java
new file mode 100644
index 0000000..04281df
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/InstanceManager.java
@@ -0,0 +1,20 @@
+package org.apache.felix.ipojo;
+
+import java.util.Set;
+
+/**
+ * Instance Manager Fake.
+ * We're using a fake to avoid the cyclic build dependency:
+ * manipulator -> ipojo -> maven-ipojo-plugin -> manipulator
+ */
+public class InstanceManager {
+
+ public Set getRegistredFields() {
+ return null;
+ }
+
+ public Set getRegistredMethods() {
+ return null;
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/Pojo.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/Pojo.java
new file mode 100644
index 0000000..c7bcb59
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/Pojo.java
@@ -0,0 +1,10 @@
+package org.apache.felix.ipojo;
+
+/**
+ * POJO Interface fake.
+ * We're using a fake to avoid the cyclic build dependency:
+ * manipulator -> ipojo -> maven-ipojo-plugin -> manipulator
+ */
+public interface Pojo {
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatorTest.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatorTest.java
new file mode 100644
index 0000000..03576b1
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatorTest.java
@@ -0,0 +1,335 @@
+package org.apache.felix.ipojo.manipulation;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.Pojo;
+import org.apache.felix.ipojo.manipulation.annotations.MetadataCollector;
+import org.mockito.Mockito;
+import org.objectweb.asm.ClassReader;
+
+public class ManipulatorTest extends TestCase {
+
+ public void testManipulatingTheSimplePojo() throws Exception {
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(getBytesFromFile(new File("target/test-classes/test/SimplePojo.class")));
+ TestClassLoader classloader = new TestClassLoader("test.SimplePojo", clazz);
+ Class cl = classloader.findClass("test.SimplePojo");
+ Assert.assertNotNull(cl);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+
+ System.out.println(manipulator.getManipulationMetadata());
+
+ // The manipulation add stuff to the class.
+ Assert.assertTrue(clazz.length > getBytesFromFile(new File("target/test-classes/test/SimplePojo.class")).length);
+
+
+ boolean found = false;
+ Constructor cst = null;
+ Constructor[] csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 1 &&
+ csts[i].getParameterTypes()[0].equals(InstanceManager.class)) {
+ found = true;
+ cst = csts[i];
+ }
+ }
+ Assert.assertTrue(found);
+
+ // We still have the empty constructor
+ found = false;
+ csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 0) {
+ found = true;
+ }
+ }
+ Assert.assertTrue(found);
+
+ // Check the POJO interface
+ Assert.assertTrue(Arrays.asList(cl.getInterfaces()).contains(Pojo.class));
+
+ cst.setAccessible(true);
+ Object pojo = cst.newInstance(new Object[] {new InstanceManager()});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ Method method = cl.getMethod("doSomething", new Class[0]);
+ Assert.assertTrue(((Boolean) method.invoke(pojo, new Object[0])).booleanValue());
+
+ }
+
+ public void testManipulatingChild() throws Exception {
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(getBytesFromFile(new File("target/test-classes/test/Child.class")));
+ TestClassLoader classloader = new TestClassLoader("test.Child", clazz);
+ Class cl = classloader.findClass("test.Child");
+ Assert.assertNotNull(cl);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+
+ boolean found = false;
+ Constructor cst = null;
+ Constructor[] csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 1 &&
+ csts[i].getParameterTypes()[0].equals(InstanceManager.class)) {
+ found = true;
+ cst = csts[i];
+ }
+ }
+ Assert.assertTrue(found);
+
+ // We still have the regular constructor
+ found = false;
+ csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 2) {
+ found = true;
+ }
+ }
+ Assert.assertTrue(found);
+
+ // Check the POJO interface
+ Assert.assertTrue(Arrays.asList(cl.getInterfaces()).contains(Pojo.class));
+
+ InstanceManager im = (InstanceManager) Mockito.mock(InstanceManager.class);
+ cst.setAccessible(true);
+ Object pojo = cst.newInstance(new Object[] {im});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ Method method = cl.getMethod("doSomething", new Class[0]);
+ Assert.assertEquals(9, ((Integer) method.invoke(pojo, new Object[0])).intValue());
+
+ }
+
+ public void testManipulatingTheInner() throws Exception {
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(getBytesFromFile(new File("target/test-classes/test/PojoWithInner.class")));
+ TestClassLoader classloader = new TestClassLoader("test.PojoWithInner", clazz);
+ Class cl = classloader.findClass("test.PojoWithInner");
+ Assert.assertNotNull(cl);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+ Assert.assertFalse(manipulator.getInnerClasses().isEmpty());
+
+
+ System.out.println(manipulator.getManipulationMetadata());
+
+ // The manipulation add stuff to the class.
+ Assert.assertTrue(clazz.length > getBytesFromFile(new File("target/test-classes/test/PojoWithInner.class")).length);
+
+
+ boolean found = false;
+ Constructor cst = null;
+ Constructor[] csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 1 &&
+ csts[i].getParameterTypes()[0].equals(InstanceManager.class)) {
+ found = true;
+ cst = csts[i];
+ }
+ }
+ Assert.assertTrue(found);
+
+ // We still have the empty constructor
+ found = false;
+ csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 0) {
+ found = true;
+ }
+ }
+ Assert.assertTrue(found);
+
+ // Check the POJO interface
+ Assert.assertTrue(Arrays.asList(cl.getInterfaces()).contains(Pojo.class));
+
+ InstanceManager im = (InstanceManager) Mockito.mock(InstanceManager.class);
+ cst.setAccessible(true);
+ Object pojo = cst.newInstance(new Object[] {im});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ Method method = cl.getMethod("doSomething", new Class[0]);
+ Assert.assertTrue(((Boolean) method.invoke(pojo, new Object[0])).booleanValue());
+
+ }
+
+ public void testManipulatingWithConstructorModification() throws Exception {
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(getBytesFromFile(new File("target/test-classes/test/Child.class")));
+ TestClassLoader classloader = new TestClassLoader("test.Child", clazz);
+ Class cl = classloader.findClass("test.Child");
+ Assert.assertNotNull(cl);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+
+ boolean found = false;
+ Constructor cst = null;
+ Constructor[] csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 1 &&
+ csts[i].getParameterTypes()[0].equals(InstanceManager.class)) {
+ found = true;
+ cst = csts[i];
+ }
+ }
+ Assert.assertTrue(found);
+
+ // We still have the regular constructor
+ found = false;
+ csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 2) {
+ found = true;
+ }
+ }
+ Assert.assertTrue(found);
+
+ // Check that we have the IM, Integer, String constructor too
+ Constructor cst2 = cl.getDeclaredConstructor(new Class[] { InstanceManager.class, Integer.TYPE, String.class });
+ Assert.assertNotNull(cst2);
+
+ // Check the POJO interface
+ Assert.assertTrue(Arrays.asList(cl.getInterfaces()).contains(Pojo.class));
+
+
+ // Creation using cst
+ InstanceManager im = (InstanceManager) Mockito.mock(InstanceManager.class);
+ cst.setAccessible(true);
+ Object pojo = cst.newInstance(new Object[] {im});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ Method method = cl.getMethod("doSomething", new Class[0]);
+ Assert.assertEquals(9, ((Integer) method.invoke(pojo, new Object[0])).intValue());
+
+ // Try to create using cst2
+ im = (InstanceManager) Mockito.mock(InstanceManager.class);
+ cst2.setAccessible(true);
+ pojo = cst2.newInstance(new Object[] {im, new Integer(2), "bariton"});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ method = cl.getMethod("doSomething", new Class[0]);
+ Assert.assertEquals(10, ((Integer) method.invoke(pojo, new Object[0])).intValue());
+
+
+
+ }
+
+
+ public void testManipulatingWithNoValidConstructor() throws Exception {
+ Manipulator manipulator = new Manipulator();
+ byte[] clazz = manipulator.manipulate(getBytesFromFile(new File("target/test-classes/test/NoValidConstructor.class")));
+ TestClassLoader classloader = new TestClassLoader("test.NoValidConstructor", clazz);
+ Class cl = classloader.findClass("test.NoValidConstructor");
+ Assert.assertNotNull(cl);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+
+ System.out.println(manipulator.getManipulationMetadata());
+
+ // The manipulation add stuff to the class.
+ Assert.assertTrue(clazz.length > getBytesFromFile(new File("target/test-classes/test/NoValidConstructor.class")).length);
+
+
+ boolean found = false;
+ Constructor cst = null;
+ Constructor[] csts = cl.getDeclaredConstructors();
+ for (int i = 0; i < csts.length; i++) {
+ System.out.println(Arrays.asList(csts[i].getParameterTypes()));
+ if (csts[i].getParameterTypes().length == 1 &&
+ csts[i].getParameterTypes()[0].equals(InstanceManager.class)) {
+ found = true;
+ cst = csts[i];
+ }
+ }
+ Assert.assertTrue(found);
+
+ // Check the POJO interface
+ Assert.assertTrue(Arrays.asList(cl.getInterfaces()).contains(Pojo.class));
+
+ cst.setAccessible(true);
+ Object pojo = cst.newInstance(new Object[] {new InstanceManager()});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+
+ }
+
+ public void test() throws Exception {
+
+
+ byte[] clazz = getBytesFromFile(new File("target/test-classes/test/Constructor.class"));
+ ClassReader cr = new ClassReader(clazz);
+ MetadataCollector collector = new MetadataCollector();
+ cr.accept(collector, 0);
+
+ System.out.println(collector.getComponentTypeDeclaration());
+
+ }
+
+ public static byte[] getBytesFromFile(File file) throws IOException {
+ InputStream is = new FileInputStream(file);
+ long length = file.length();
+ byte[] bytes = new byte[(int)length];
+
+ // Read in the bytes
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length
+ && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+ offset += numRead;
+ }
+
+ // Ensure all the bytes have been read in
+ if (offset < bytes.length) {
+ throw new IOException("Could not completely read file "+file.getName());
+ }
+
+ // Close the input stream and return bytes
+ is.close();
+ return bytes;
+ }
+
+ class TestClassLoader extends ClassLoader {
+
+ private String name;
+ private byte[] clazz;
+
+ public TestClassLoader(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/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java
new file mode 100644
index 0000000..68d4b5e
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java
@@ -0,0 +1,43 @@
+package org.apache.felix.ipojo.manipulation;
+
+import java.io.File;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.manipulator.Pojoization;
+
+public class PojoizationTest extends TestCase {
+
+ public void testJarManipulation() {
+ Pojoization pojoization = new Pojoization();
+ File in = new File("target/test-classes/tests.manipulation-no-annotations.jar");
+ File out = new File("target/test-classes/tests.manipulation-no-annotations-manipulated.jar");
+ out.delete();
+ File metadata = new File("target/test-classes/metadata.xml");
+ pojoization.pojoization(in, out, metadata);
+
+ Assert.assertTrue(out.exists());
+ }
+
+ public void testManipulationWithAnnotations() {
+ Pojoization pojoization = new Pojoization();
+ File in = new File("target/test-classes/tests.manipulator-annotations.jar");
+ File out = new File("target/test-classes/tests.manipulation-annotations-manipulated.jar");
+ out.delete();
+ pojoization.pojoization(in, out, (File) null);
+
+ Assert.assertTrue(out.exists());
+ }
+
+ public void testJarManipulationJava5() {
+ Pojoization pojoization = new Pojoization();
+ File in = new File("target/test-classes/tests.manipulation.java5.jar");
+ File out = new File("target/test-classes/tests.manipulation.java5-manipulated.jar");
+ out.delete();
+ pojoization.pojoization(in, out, (File) null);
+
+ Assert.assertTrue(out.exists());
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/Child.java b/ipojo/manipulator/src/test/java/test/Child.java
new file mode 100644
index 0000000..1eda305
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/Child.java
@@ -0,0 +1,17 @@
+package test;
+
+public class Child extends Parent {
+
+ Child(int i, String f) {
+ super(i, f);
+ }
+
+ Child() {
+ super(5, "foo");
+ }
+
+ public int doSomething() {
+ return getIndex() + 1; // 9
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/Constructor.java b/ipojo/manipulator/src/test/java/test/Constructor.java
new file mode 100644
index 0000000..ccbaebe
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/Constructor.java
@@ -0,0 +1,15 @@
+package test;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+import org.apache.felix.ipojo.annotations.Requires;
+
+@Component
+public class Constructor {
+
+ public Constructor(@Property(name="foo") String s, @Requires(id="t") Thread t) {
+ // plop
+
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/NoValidConstructor.java b/ipojo/manipulator/src/test/java/test/NoValidConstructor.java
new file mode 100644
index 0000000..45d52cb
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/NoValidConstructor.java
@@ -0,0 +1,15 @@
+package test;
+
+public class NoValidConstructor {
+
+ String m_s;
+
+ public NoValidConstructor(String s) {
+ m_s = s;
+ }
+
+ public String getS() {
+ return m_s;
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/Parent.java b/ipojo/manipulator/src/test/java/test/Parent.java
new file mode 100644
index 0000000..51ac622
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/Parent.java
@@ -0,0 +1,15 @@
+package test;
+
+public class Parent {
+
+ private int m_index = 0;
+
+ public Parent(int i, String s) {
+ m_index = i + s.length();
+ }
+
+ public int getIndex() {
+ return m_index;
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/PojoWithInner.java b/ipojo/manipulator/src/test/java/test/PojoWithInner.java
new file mode 100644
index 0000000..ac5a052
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/PojoWithInner.java
@@ -0,0 +1,21 @@
+package test;
+
+public class PojoWithInner {
+
+ private MyInner m_result = new MyInner();
+
+ // This is a simple POJO
+
+ public boolean doSomething() {
+ return m_result.getInner();
+ }
+
+ public class MyInner {
+
+ public boolean getInner() {
+ return true;
+ }
+
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/java/test/SimplePojo.java b/ipojo/manipulator/src/test/java/test/SimplePojo.java
new file mode 100644
index 0000000..3c1d6fa
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/SimplePojo.java
@@ -0,0 +1,13 @@
+package test;
+
+public class SimplePojo {
+
+ private boolean m_result = true;
+
+ // This is a simple POJO
+
+ public boolean doSomething() {
+ return m_result;
+ }
+
+}
diff --git a/ipojo/manipulator/src/test/resources/metadata.xml b/ipojo/manipulator/src/test/resources/metadata.xml
new file mode 100644
index 0000000..b3e0262
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/metadata.xml
@@ -0,0 +1,37 @@
+<ipojo
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
+ xmlns="org.apache.felix.ipojo"
+>
+ <!-- Simple provider used for manipulation analysis -->
+ <component
+ classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+ name="Manipulation-FooProviderType-1" architecture="true">
+ <provides />
+ </component>
+
+ <!-- Non lazzy service provider, to check instantiation -->
+ <component
+ classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+ name="Manipulation-ImmediateFooProviderType" immediate="true"
+ architecture="true">
+ <provides />
+ </component>
+
+ <!-- Nested & Inner classes -->
+ <component name="inners" classname="org.apache.felix.ipojo.test.scenarios.component.InnerClasses">
+ <provides>
+ <property field="privateObject"/>
+ <property field="privateInt"/>
+
+ <property field="protectedObject"/>
+ <property field="protectedInt"/>
+
+ <property field="packageObject"/>
+ <property field="packageInt"/>
+
+ <property field="publicObject"/>
+ <property field="publicInt"/>
+ </provides>
+ </component>
+</ipojo>
diff --git a/ipojo/manipulator/src/test/resources/tests.manipulation-no-annotations.jar b/ipojo/manipulator/src/test/resources/tests.manipulation-no-annotations.jar
new file mode 100644
index 0000000..a701fc0
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/tests.manipulation-no-annotations.jar
Binary files differ
diff --git a/ipojo/manipulator/src/test/resources/tests.manipulation.java5.jar b/ipojo/manipulator/src/test/resources/tests.manipulation.java5.jar
new file mode 100644
index 0000000..456e356
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/tests.manipulation.java5.jar
Binary files differ
diff --git a/ipojo/manipulator/src/test/resources/tests.manipulator-annotations.jar b/ipojo/manipulator/src/test/resources/tests.manipulator-annotations.jar
new file mode 100644
index 0000000..45322aa
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/tests.manipulator-annotations.jar
Binary files differ