[picocontainer-scm] [5564] java/2.x/trunk/pico/container/src/test/org/picocontainer: start of emjection
paul-yCVjj/[email protected]
| Newsgroups | gmane.comp.java.picocontainer.cvs |
|---|---|
| Message-ID | <[email protected]> |
Revision 5564
Author paul
Date 2009-11-30 13:23:36 -0600 (Mon, 30 Nov 2009)
Log Message
start of emjection
Modified Paths
- java/2.x/trunk/pico/container/src/java/org/picocontainer/Characteristics.java
- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjection.java
- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java
- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/Reinjector.java
- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java
- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ReinjectionTestCase.java
Added Paths
- java/2.x/trunk/pico/container/src/java/org/picocontainer/Emjection.java
- java/2.x/trunk/pico/container/src/test/org/picocontainer/foo/
- java/2.x/trunk/pico/container/src/test/org/picocontainer/foo/EmjectionTestCase.java
Diff
Modified: java/2.x/trunk/pico/container/src/java/org/picocontainer/Characteristics.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/java/org/picocontainer/Characteristics.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/Characteristics.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -38,6 +38,7 @@
private static final String _USE_NAMES = "use-parameter-names";
private static final String _ENABLE_CIRCULAR = "enable-circular";
private static final String _GUARD = "guard";
+ private static final String _EMJECTION = "emjection_enabled";
/**
* Since properties use strings, we supply String constants for Boolean conditions.
@@ -152,6 +153,8 @@
public static final Properties USE_NAMES = immutable(_USE_NAMES, TRUE);
+ public static final Properties EMJECTION_ENABLED = immutable(_EMJECTION, TRUE);
+
public static final Properties GUARD = immutable(_GUARD, "guard");
public static final Properties GUARD(String with) {
Added: java/2.x/trunk/pico/container/src/java/org/picocontainer/Emjection.java (0 => 5564)
--- java/2.x/trunk/pico/container/src/java/org/picocontainer/Emjection.java (rev 0)
+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/Emjection.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -0,0 +1,55 @@
+package org.picocontainer;
+
+import org.picocontainer.containers.ImmutablePicoContainer;
+import org.picocontainer.containers.TransientPicoContainer;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+public class Emjection {
+
+ private PicoContainer pico;
+
+ public void setPico(ImmutablePicoContainer container) {
+ if (pico != null) {
+ throw new PicoCompositionException("Emjection can only be setup once per component");
+ }
+ pico = container;
+ }
+
+ public static <T> T neu(Class<T> type, Emjection emjection, Object... args) {
+ if (emjection.pico == null) {
+ throw new PicoCompositionException("blah");
+ }
+ TransientPicoContainer tpc = new TransientPicoContainer(emjection.pico);
+ for (Object arg : args) {
+ tpc.addComponent(arg);
+ }
+ T inst = tpc.getComponent(type);
+ if (inst == null) {
+ tpc.addComponent(type);
+ inst = tpc.getComponent(type);
+ }
+ setPico(inst, tpc);
+ return inst;
+ }
+
+ private static <T> void setPico(Object inst, PicoContainer container) {
+ try {
+ Field field = inst.getClass().getDeclaredField("emjection");
+ field.setAccessible(true);
+ Emjection e2 = (Emjection) field.get(inst);
+ e2.setPico(new ImmutablePicoContainer(container));
+ } catch (NoSuchFieldException e) {
+ throw new PicoCompositionException("Components created via emjection have to have a field 'private Emjection emjection'. " + inst.getClass() + " is missing that field");
+ } catch (IllegalAccessException e) {
+ throw new PicoCompositionException("unable to access field called emjection on " + inst.getClass());
+ }
+ }
+
+ public static void setupEmjection(Object inst, PicoContainer container) {
+ setPico(inst, container);
+ }
+
+
+}
Modified: java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjection.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjection.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjection.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -56,6 +56,8 @@
public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties properties, Object componentKey,
Class<T> componentImplementation, Parameter... parameters) throws PicoCompositionException {
boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(properties, Characteristics.USE_NAMES, true);
- return componentMonitor.newInjector(new ConstructorInjector(componentKey, componentImplementation, parameters, componentMonitor, lifecycleStrategy, useNames, rememberChosenConstructor));
+ ConstructorInjector injector = new ConstructorInjector(componentKey, componentImplementation, parameters, componentMonitor, lifecycleStrategy, useNames, rememberChosenConstructor);
+ injector.enableEmjection(AbstractBehaviorFactory.removePropertiesIfPresent(properties, Characteristics.EMJECTION_ENABLED));
+ return componentMonitor.newInjector(injector);
}
}
Modified: java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -10,21 +10,12 @@
package org.picocontainer.injectors;
-import org.picocontainer.ComponentMonitor;
-import org.picocontainer.LifecycleStrategy;
-import org.picocontainer.Parameter;
-import org.picocontainer.PicoCompositionException;
-import org.picocontainer.PicoContainer;
-import org.picocontainer.ComponentAdapter;
-import org.picocontainer.NameBinding;
+import org.picocontainer.*;
+import org.picocontainer.containers.ImmutablePicoContainer;
import org.picocontainer.lifecycle.NullLifecycleStrategy;
import org.picocontainer.monitors.NullComponentMonitor;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
+import java.lang.reflect.*;
import java.lang.annotation.Annotation;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -55,6 +46,7 @@
private transient ThreadLocalCyclicDependencyGuard<T> instantiationGuard;
private boolean rememberChosenConstructor = true;
private transient CtorAndAdapters<T> chosenConstructor;
+ private boolean enableEmjection = false;
/**
* Constructor injector that uses no monitor and no lifecycle adapter. This is a more
@@ -199,6 +191,10 @@
return new CtorAndAdapters<T>(greediestConstructor, greediestConstructorsParameters, greediestConstructorsParametersComponentAdapters);
}
+ public void enableEmjection(boolean enableEmjection) {
+ this.enableEmjection = enableEmjection;
+ }
+
private static final class ResolverKey {
private final Type expectedType;
private final String pName;
@@ -336,9 +332,17 @@
};
}
instantiationGuard.setGuardedContainer(container);
- return instantiationGuard.observe(getComponentImplementation());
+ T inst = instantiationGuard.observe(getComponentImplementation());
+ decorate(inst, container);
+ return inst;
}
+ private void decorate(T inst, PicoContainer container) {
+ if (enableEmjection) {
+ Emjection.setupEmjection(inst, container);
+ }
+ }
+
private List<Constructor<T>> getSortedMatchingConstructors() {
List<Constructor<T>> matchingConstructors = new ArrayList<Constructor<T>>();
Constructor<T>[] allConstructors = getConstructors();
Modified: java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/Reinjector.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/Reinjector.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/Reinjector.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -8,14 +8,14 @@
*****************************************************************************/
package org.picocontainer.injectors;
-import org.picocontainer.PicoContainer;
-import org.picocontainer.ComponentMonitor;
-import org.picocontainer.ComponentMonitorStrategy;
-import org.picocontainer.InjectionFactory;
+import org.picocontainer.*;
import org.picocontainer.lifecycle.NullLifecycleStrategy;
import org.picocontainer.monitors.NullComponentMonitor;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Properties;
/**
@@ -62,6 +62,37 @@
/**
* Reinjecting into a method.
+ * @param key the component-key from the parent set of components to inject into
+ * @param reinjectionMethodEnum the enum for the reflection method to use for injection.
+ * @return the result of the reinjection-method invocation.
+ */
+ public Object reinject(Class<?> key, Enum reinjectionMethodEnum) {
+ return reinject(key, key, parent.getComponent(key), NO_PROPERTIES, new MethodInjection(toMethod(reinjectionMethodEnum)));
+ }
+
+ private Method toMethod(final Enum reinjectionMethodEnum) {
+ Object methodOrException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ try {
+ return reinjectionMethodEnum.getClass().getMethod("toMethod").invoke(reinjectionMethodEnum);
+ } catch (IllegalAccessException e) {
+ return new PicoCompositionException("Illegal access to " + reinjectionMethodEnum.name());
+ } catch (InvocationTargetException e) {
+ return new PicoCompositionException("Invocation Target Exception " + reinjectionMethodEnum.name(), e.getCause());
+ } catch (NoSuchMethodException e) {
+ return new PicoCompositionException("Expected generated method toMethod() on enum");
+ }
+ }
+ });
+ if (methodOrException instanceof Method) {
+ return (Method) methodOrException;
+ } else {
+ throw (PicoCompositionException) methodOrException;
+ }
+ }
+
+ /**
+ * Reinjecting into a method.
* @param key the component-key from the parent set of components to inject into (key and impl are the same)
* @param reinjectionFactory the InjectionFactory to use for reinjection.
* @return the result of the reinjection-method invocation.
@@ -74,7 +105,7 @@
/**
* Reinjecting into a method.
* @param key the component-key from the parent set of components to inject into
- * @param implementation the implementation of the component that is going to result.
+ * @param impl the implementation of the component that is going to result.
* @param reinjectionFactory the InjectionFactory to use for reinjection.
* @return
*/
Added: java/2.x/trunk/pico/container/src/test/org/picocontainer/foo/EmjectionTestCase.java (0 => 5564)
--- java/2.x/trunk/pico/container/src/test/org/picocontainer/foo/EmjectionTestCase.java (rev 0)
+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/foo/EmjectionTestCase.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -0,0 +1,70 @@
+package org.picocontainer.foo;
+
+import org.junit.Test;
+import org.picocontainer.Characteristics;
+import org.picocontainer.DefaultPicoContainer;
+import org.picocontainer.Emjection;
+import org.picocontainer.MutablePicoContainer;
+
+import static junit.framework.Assert.assertEquals;
+
+public class EmjectionTestCase {
+
+ @Test
+ public void basicEmjection() {
+
+ StringBuilder sb = new StringBuilder();
+ MutablePicoContainer pico = new DefaultPicoContainer();
+ pico.addComponent(Antelope.class);
+ pico.as(Characteristics.EMJECTION_ENABLED).addComponent(ZooKeeper.class);
+ pico.addComponent(sb);
+ ZooKeeper zooKeeper = pico.getComponent(ZooKeeper.class);
+ zooKeeper.doHeadCount();
+
+ assertEquals("giraffe=true, antelope=true", sb.toString());
+
+ }
+
+
+ public static class Zoo {
+ private final Emjection emjection = new Emjection();
+
+ private Giraffe giraffe;
+ private Antelope antelope;
+ private StringBuilder sb;
+
+ public Zoo(Giraffe giraffe, Antelope antelope, StringBuilder sb) {
+ this.giraffe = giraffe;
+ this.antelope = antelope;
+ this.sb = sb;
+ }
+
+ public void headCount() {
+ sb.append("giraffe=").append(giraffe != null);
+ sb.append(", antelope=").append(antelope != null);
+ }
+ }
+
+
+ public static class ZooKeeper {
+
+ private final Emjection emjection = new Emjection();
+
+ public void doHeadCount() {
+ Zoo zoo = neu(Zoo.class, this, new Giraffe());
+ zoo.headCount();
+ }
+
+ <T> T neu(Class<T> type, Object... args) {
+ return Emjection.neu(type, emjection, args);
+ }
+
+ }
+
+ public static class Giraffe {
+ }
+ public static class Antelope {
+ }
+
+
+}
Modified: java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -125,6 +125,7 @@
" <lifecycleStrategy class=RLS/>\n" +
" <useNames>false</useNames>\n" +
" <rememberChosenConstructor>true</rememberChosenConstructor>\n" +
+ " <enableEmjection>false</enableEmjection>\n" +
"</Constructor-Injection>", foo);
Modified: java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ReinjectionTestCase.java (5563 => 5564)
--- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ReinjectionTestCase.java 2009-11-04 01:13:42 UTC (rev 5563)
+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ReinjectionTestCase.java 2009-11-30 19:23:36 UTC (rev 5564)
@@ -77,6 +77,21 @@
public Object getString() {
return string;
}
+ public static enum M {
+ doIt("doIt", String.class);
+ private Method method;
+
+ M(String s, Class... paramTypes) {
+ try {
+ method = NeedsShoe.class.getMethod(s, paramTypes);
+ } catch (NoSuchMethodException e) {
+ throw new UnsupportedOperationException(e);
+ }
+ }
+ public Method toMethod() {
+ return method;
+ }
+ }
}
public static class Shoe {
@@ -228,12 +243,26 @@
final ComponentMonitor cm = new NullComponentMonitor();
Reinjector reinjector = new Reinjector(parent, cm);
- int result = (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD);
+ //int result = (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD);
assertEquals(6, (int) (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD));
assertEquals(6, (int) (Integer) reinjector.reinject(NeedsShoe.class, new MethodInjection(DOIT_METHOD)));
}
+ @Test public void testOverloadedReinjectMethodsAreIdentical2() {
+ final DefaultPicoContainer parent = new DefaultPicoContainer(new Caching().wrap(new ConstructorInjection()));
+ parent.addComponent(INeedsShoe.class, NeedsShoe.class);
+ parent.addComponent(Shoe.class);
+ parent.addComponent("12");
+
+ final ComponentMonitor cm = new NullComponentMonitor();
+ Reinjector reinjector = new Reinjector(parent, cm);
+
+ assertEquals(6, (int) (Integer) reinjector.reinject(NeedsShoe.class, NeedsShoe.M.doIt));
+ assertEquals(6, (int) (Integer) reinjector.reinject(NeedsShoe.class, new MethodInjection(DOIT_METHOD)));
+
+ }
+
@Test public void testReinjectorCanBeOverridenByComponentMonitor() {
final DefaultPicoContainer parent = new DefaultPicoContainer(new Caching().wrap(new ConstructorInjection()));
parent.addComponent(INeedsShoe.class, NeedsShoe.class);
@@ -247,7 +276,6 @@
};
Reinjector reinjector = new Reinjector(parent, cm);
- int result = (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD);
assertEquals(4444, (int) (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD));
}
@@ -265,7 +293,6 @@
};
Reinjector reinjector = new Reinjector(parent, cm);
- int result = (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD);
assertEquals(6, (int) (Integer) reinjector.reinject(NeedsShoe.class, DOIT_METHOD));
}
----------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email