[picocontainer-scm] [scm-git][1/2] Whoops, missing added files from last night's work.
Michael Rimov <git-yCVjj/[email protected]> Fri, 31 May 2013 22:35:12 -0500 (CDT)
| Newsgroups | gmane.comp.java.picocontainer.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 75cc3e7a0db4911c9cdd047705fa648e0d8fdc35 Author: Michael Rimov <[email protected]> AuthorDate: Fri, 31 May 2013 20:30:41 -0700 Commit: Michael Rimov <[email protected]> CommitDate: Fri, 31 May 2013 20:30:41 -0700 Whoops, missing added files from last night's work. diff --git a/pico/container/src/java/org/picocontainer/injectors/Jsr330ConstructorInjection.java b/pico/container/src/java/org/picocontainer/injectors/Jsr330ConstructorInjection.java new file mode 100644 index 0000000..fa9a075 --- /dev/null +++ b/pico/container/src/java/org/picocontainer/injectors/Jsr330ConstructorInjection.java @@ -0,0 +1,96 @@ +package org.picocontainer.injectors; + +import org.picocontainer.ComponentMonitor; +import org.picocontainer.Parameter; +import org.picocontainer.containers.JSRPicoContainer; +import org.picocontainer.injectors.ConstructorInjection.ConstructorInjector; +import org.picocontainer.parameters.ComponentParameter; +import org.picocontainer.parameters.ConstructorParameters; +import org.picocontainer.parameters.JSR330ComponentParameter; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +import javax.inject.Named; + +@SuppressWarnings("serial") +public class Jsr330ConstructorInjection extends ConstructorInjection { + + @Override + protected <T> ConstructorInjector<T> newConstructorInjector(ComponentMonitor monitor, Object key, Class<T> impl, + boolean useNames, ConstructorParameters parameters) { + return new ConstructorInjectorWithForcedPublicCtors<T>(rememberChosenConstructor, monitor, useNames, key, impl, + parameters); + } + + public static class ConstructorInjectorWithForcedPublicCtors<T> extends ConstructorInjector<T> { + public ConstructorInjectorWithForcedPublicCtors(boolean rememberChosenConstructor, ComponentMonitor monitor, + boolean useNames, Object key, Class<T> impl, ConstructorParameters parameters) + throws NotConcreteRegistrationException { + super(monitor, useNames, rememberChosenConstructor, key, impl, parameters); + } + + @Override + protected boolean hasApplicableConstructorModifiers(int modifiers) { + return true; + } + + @Override + protected void changeAccessToModifierifNeeded(Constructor<T> ctor) { + if ((ctor.getModifiers() & Modifier.PUBLIC) == 0) { + ctor.setAccessible(true); + } + } + + /** + * If there is no Parameter defined for the constructor arg, (Other than + * Default), then checks to see if there are + * {@linkplain javax.inject.Named} annotations or Qualifier annotations + * attached to the argument and uses those as ComponentParameters + * instead. If not it uses the superclass default behavior. + */ + @Override + protected Parameter getParameterToUse(Constructor<?> constructorToExamine, int constructorParameterIndex, + Parameter parameter) { + if (isDefaultParameter(parameter)) { + + // Search for Named class + for (Annotation eachAnnotation : constructorToExamine.getParameterAnnotations()[constructorParameterIndex]) { + if (eachAnnotation.annotationType().equals(Named.class)) { + return new ComponentParameter(((Named) eachAnnotation).value()); + } + } + + // Search for a qualifier that isn't @Named annotation. + Annotation qualifier = JSRPicoContainer + .getQualifier(constructorToExamine.getParameterAnnotations()[constructorParameterIndex]); + if (qualifier != null) { + return new ComponentParameter(qualifier.annotationType().getName()); + } + + } + + return super.getParameterToUse(constructorToExamine, constructorParameterIndex, parameter); + } + + private boolean isDefaultParameter(Parameter parameter) { + if (parameter == ComponentParameter.DEFAULT || parameter == JSR330ComponentParameter.DEFAULT) { + return true; + } + + if (parameter instanceof ComponentParameter) { + return !((ComponentParameter) parameter).isKeyDefined(); + + } + return false; + } + + @Override + protected Parameter constructDefaultComponentParameter() { + return JSR330ComponentParameter.DEFAULT; + } + + } +} diff --git a/pico/container/src/java/org/picocontainer/parameters/AccessibleObjectParameterSet.java b/pico/container/src/java/org/picocontainer/parameters/AccessibleObjectParameterSet.java new file mode 100644 index 0000000..b792ed7 --- /dev/null +++ b/pico/container/src/java/org/picocontainer/parameters/AccessibleObjectParameterSet.java @@ -0,0 +1,65 @@ +package org.picocontainer.parameters; + +import java.io.Serializable; +import java.lang.reflect.AccessibleObject; +import java.util.Arrays; + +import org.picocontainer.Parameter; + +/*** + * Serialization Warning. While using a specific target type is more of an edge case, it + * isn't serializable and will have to be re-applied after deserialization. + * @author Michael Rimov + * + */ +@SuppressWarnings("serial") +public class AccessibleObjectParameterSet implements Serializable { + + + public static final AccessibleObjectParameterSet[] EMPTY = new AccessibleObjectParameterSet[]{}; + + /** + * Can't be serialized + */ + private transient Class<?> targetType; + + private final Parameter[] params; + + private final String name; + + + public AccessibleObjectParameterSet(String name, Parameter... params) { + this.name = name; + this.params = params; + } + + public AccessibleObjectParameterSet(Class<?> targetType, String name, Parameter... params) { + this.targetType = targetType; + this.name = name; + this.params = params; + } + + public Class<?> getTargetType() { + return targetType; + } + + public void setTargetType(Class<?> targetType) { + this.targetType = targetType; + } + + public Parameter[] getParams() { + return params; + } + + public String getName() { + return name; + } + + + @Override + public String toString() { + return "AccessibleObjectParameterSet [targetType=" + targetType + ", params=" + Arrays.toString(params) + + ", name=" + name + "]"; + } + +} \ No newline at end of file diff --git a/pico/container/src/java/org/picocontainer/parameters/BeanParameters.java b/pico/container/src/java/org/picocontainer/parameters/BeanParameters.java new file mode 100644 index 0000000..80724ba --- /dev/null +++ b/pico/container/src/java/org/picocontainer/parameters/BeanParameters.java @@ -0,0 +1,33 @@ +package org.picocontainer.parameters; + +import org.picocontainer.Parameter; + +/** + * Parameter where the name is the bean property name, and this class automatically converts the name to + * the setter method it is looking for. + * @author Mike + * + */ +@SuppressWarnings("serial") +public class BeanParameters extends MethodParameters { + + public BeanParameters(String name, Parameter... params) { + super(convertPropertyNameToSetterName(name), params); + } + + + public BeanParameters(Class<?> targetType, String name, Parameter... params) { + super(targetType, convertPropertyNameToSetterName(name), params); + } + + private static String convertPropertyNameToSetterName(String name) { + if (name == null) { + throw new NullPointerException("name"); + } + + + return "set" + Character.toUpperCase(name.charAt(0)) + + (name.length() > 1 ? name.substring(1) : ""); + } + +} diff --git a/pico/container/src/java/org/picocontainer/parameters/ConstructorParameters.java b/pico/container/src/java/org/picocontainer/parameters/ConstructorParameters.java new file mode 100644 index 0000000..e1f7bef --- /dev/null +++ b/pico/container/src/java/org/picocontainer/parameters/ConstructorParameters.java @@ -0,0 +1,47 @@ +/** + * + */ +package org.picocontainer.parameters; + +import java.util.Arrays; + +import org.picocontainer.Parameter; + +/** + * @author Mike + * + */ +@SuppressWarnings("serial") +public class ConstructorParameters extends AccessibleObjectParameterSet { + + /** + * Reference this in your constructor parameters if you wish the no-arg constructor to be used. + */ + public static final ConstructorParameters NO_ARG_CONSTRUCTOR = new ConstructorParameters(DefaultConstructorParameter.INSTANCE); + + + /** + * Constructs constructor parameters with the given component and constant parameters. + * @param params the parameters in constructor parmeter order. + */ + public ConstructorParameters(Parameter[] params) { + super(null, params); + } + + + public ConstructorParameters(Parameter parameter) { + super(null, new Parameter[] {parameter}); + } + + public ConstructorParameters() { + this((Parameter[])null); + } + + + @Override + public String toString() { + return "ConstructorParameters Parameters = " + Arrays.deepToString(this.getParams()); + } + + +} diff --git a/pico/container/src/java/org/picocontainer/parameters/FieldParameters.java b/pico/container/src/java/org/picocontainer/parameters/FieldParameters.java new file mode 100644 index 0000000..4df59f9 --- /dev/null +++ b/pico/container/src/java/org/picocontainer/parameters/FieldParameters.java @@ -0,0 +1,15 @@ +package org.picocontainer.parameters; + +import org.picocontainer.Parameter; + +public class FieldParameters extends AccessibleObjectParameterSet { + + public FieldParameters(Class<?> targetType, String name, Parameter... params) { + super(targetType, name, params); + } + + public FieldParameters(String name, Parameter... params) { + super(name, params); + } + +} diff --git a/pico/container/src/java/org/picocontainer/parameters/MethodParameters.java b/pico/container/src/java/org/picocontainer/parameters/MethodParameters.java new file mode 100644 index 0000000..e8c4315 --- /dev/null +++ b/pico/container/src/java/org/picocontainer/parameters/MethodParameters.java @@ -0,0 +1,22 @@ +package org.picocontainer.parameters; + +import org.picocontainer.Parameter; + +@SuppressWarnings("serial") +public class MethodParameters extends AccessibleObjectParameterSet { + + public MethodParameters(String name, Parameter... params) { + super(name, params); + } + + /** + * Allows you to specify a specific type that this parameter binds to, for example, allows + * @param targetType + * @param name + * @param params + */ + public MethodParameters(Class<?> targetType, String name, Parameter... params) { + super(targetType, name, params); + } + +} diff --git a/pico/container/src/test/org/picocontainer/injectors/Jsr330ConstructorInjectionTestCase.java b/pico/container/src/test/org/picocontainer/injectors/Jsr330ConstructorInjectionTestCase.java new file mode 100644 index 0000000..0bdb722 --- /dev/null +++ b/pico/container/src/test/org/picocontainer/injectors/Jsr330ConstructorInjectionTestCase.java @@ -0,0 +1,59 @@ +package org.picocontainer.injectors; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.picocontainer.monitors.NullComponentMonitor; + +public class Jsr330ConstructorInjectionTestCase { + + + public static class Something { + + public Something() { + + } + } + + + + public static class SomethingElse { + + /** + * Shouldn't be accessible to ConstructorInjection, SHOULD + * be accessible to JSR330 injection. (WHY JSR, WHY?!?!) + */ + private SomethingElse() { + + } + + } + + @Test + public void testBothPublicAndPrivateConstructorsMayBeAcessed() { + Jsr330ConstructorInjection.ConstructorInjectorWithForcedPublicCtors<Something> cica = + new Jsr330ConstructorInjection.ConstructorInjectorWithForcedPublicCtors<Something>( + false, + new NullComponentMonitor(), + false, + Something.class, + Something.class, + null); + + assertNotNull(cica.getComponentInstance(null, null)); + + + Jsr330ConstructorInjection.ConstructorInjectorWithForcedPublicCtors<SomethingElse> cica2 = + new Jsr330ConstructorInjection.ConstructorInjectorWithForcedPublicCtors<SomethingElse>( + false, + new NullComponentMonitor(), + false, + SomethingElse.class, + SomethingElse.class, + null); + + assertNotNull(cica2.getComponentInstance(null, null)); + + } + +} diff --git a/pico/container/src/test/org/picocontainer/parameters/BeanParametersTestCase.java b/pico/container/src/test/org/picocontainer/parameters/BeanParametersTestCase.java new file mode 100644 index 0000000..368f0a0 --- /dev/null +++ b/pico/container/src/test/org/picocontainer/parameters/BeanParametersTestCase.java @@ -0,0 +1,23 @@ +package org.picocontainer.parameters; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class BeanParametersTestCase { + + + @Test + public void testSetterificationOfPropertyName() { + BeanParameters param = new BeanParameters("test"); + assertEquals("setTest", param.getName()); + } + + public void testSetterConversionIfPropertyIsOneCharacterLong() { + BeanParameters param = new BeanParameters("i"); + assertEquals("setI", param.getName()); + } + +}