pax_global_header00006660000000000000000000000064124224764430014522gustar00rootroot0000000000000052 comment=a5f19524e12199dfc0c15d48851eb07e72673e45 libpicocontainer-java-2.15/000077500000000000000000000000001242247644300157145ustar00rootroot00000000000000libpicocontainer-java-2.15/META-INF/000077500000000000000000000000001242247644300170545ustar00rootroot00000000000000libpicocontainer-java-2.15/META-INF/MANIFEST.MF000066400000000000000000000001731242247644300205070ustar00rootroot00000000000000Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: paul Build-Jdk: 1.7.0_09 libpicocontainer-java-2.15/org/000077500000000000000000000000001242247644300165035ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/000077500000000000000000000000001242247644300213405ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/Behavior.java000066400000000000000000000020001242247644300237320ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammant * *****************************************************************************/ package org.picocontainer; /** * Behaviors modify the components created by a Injector with additional behaviors * * @author Paul Hammant * @author Jörg Schaible * @author Mauro Talevi * @see LifecycleStrategy */ public interface Behavior extends ComponentAdapter, ComponentLifecycle { } libpicocontainer-java-2.15/org/picocontainer/BehaviorFactory.java000066400000000000000000000022741242247644300252770ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import java.util.Properties; /** * Extends ComponentFactory to provide factory methods for Behaviors * * @author Paul Hammant * @author Mauro Talevi */ public interface BehaviorFactory extends ComponentFactory { ComponentFactory wrap(ComponentFactory delegate); ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter); } libpicocontainer-java-2.15/org/picocontainer/BindKey.java000066400000000000000000000040141242247644300235270ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Committers. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Joerg Schaibe * *****************************************************************************/ package org.picocontainer; import java.io.Serializable; import java.lang.annotation.Annotation; /** @author Paul Hammant */ @SuppressWarnings("serial") public class BindKey implements Serializable { private final Class type; private final Class annotation; public BindKey(Class type, Class annotation) { this.type = type; this.annotation = annotation; } public Class getType() { return type; } public Class getAnnotation() { return annotation; } public String toString() { return type.getName() + ":" + annotation.getName(); } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BindKey bindKey = (BindKey)o; if (!annotation.equals(bindKey.annotation)) return false; if (!type.equals(bindKey.type)) return false; return true; } public int hashCode() { int result; result = type.hashCode(); result = 31 * result + annotation.hashCode(); return result; } public static BindKey bindKey(Class type, Class annotation) { return new BindKey(type, annotation); } } libpicocontainer-java-2.15/org/picocontainer/Characteristics.java000066400000000000000000000213401242247644300253160ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import java.util.Map; import java.util.Properties; /** * Collection of immutable properties, holding behaviour characteristics. See * The PicoContainer Website for details on the usage * of Characteristics. * * @author Paul Hammant * @see org.picocontainer.ComponentAdapter * @see org.picocontainer.Behavior */ @SuppressWarnings("serial") public final class Characteristics { private static final String _INJECTION = "injection"; private static final String _NONE = "none"; private static final String _CONSTRUCTOR = "constructor"; private static final String _METHOD = "method"; private static final String _SETTER = "setter"; private static final String _CACHE = "cache"; private static final String _SYNCHRONIZING = "synchronizing"; private static final String _LOCKING = "locking"; private static final String _HIDE_IMPL = "hide-impl"; private static final String _PROPERTY_APPLYING = "property-applying"; private static final String _AUTOMATIC = "automatic"; 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. */ public static final String FALSE = "false"; /** * Since properties use strings, we supply String constants for Boolean conditions. */ public static final String TRUE = "true"; /** * Turns on constructor injection. * @see org.picocontainer.injectors.ConstructorInjection */ public static final Properties CDI = immutable(_INJECTION, _CONSTRUCTOR); /** * Turns on Setter Injection. * @see org.picocontainer.injectors.SetterInjection */ public static final Properties SDI = immutable(_INJECTION, _SETTER); /** * Turns on Method Injection. */ public static final Properties METHOD_INJECTION = immutable(_INJECTION, _METHOD); /** * Turns off Caching of component instances. (Often referred to in other circles * as singleton). * @see org.picocontainer.behaviors.Caching */ public static final Properties NO_CACHE = immutable(_CACHE, FALSE); /** * Turns on Caching of component instances. (Often referred to in other circles * as singleton) * @see org.picocontainer.behaviors.Caching */ public static final Properties CACHE = immutable(_CACHE, TRUE); /** * Turns on synchronized access to the component instance. (Under JDK 1.5 conditions, * it will be better to use {@link #LOCK} instead. * @see org.picocontainer.behaviors.Synchronizing */ public static final Properties SYNCHRONIZE = immutable(_SYNCHRONIZING, TRUE); /** * Turns off synchronized access to the component instance. * @see org.picocontainer.behaviors.Synchronizing */ public static final Properties NO_SYNCHRONIZE = immutable(_SYNCHRONIZING, FALSE); /** * Uses a java.util.concurrent.Lock to provide faster access than synchronized. * @see org.picocontainer.behaviors.Locking */ public static final Properties LOCK = immutable(_LOCKING, TRUE); /** * Turns off locking synchronization. * @see org.picocontainer.behaviors.Locking */ public static final Properties NO_LOCK = immutable(_LOCKING, FALSE); /** * Synonym for {@link #CACHE CACHE}. * @see org.picocontainer.behaviors.Caching */ public static final Properties SINGLE = CACHE; /** * Synonym for {@link #NO_CACHE NO_CACHE}. * @see org.picocontainer.behaviors.Caching */ public static final Properties NO_SINGLE = NO_CACHE; /** * Turns on implementation hiding. You may use the JDK Proxy implementation included * in this version, or the ASM-based implementation hiding method * included in PicoContainer Gems. However, you cannot use both in a single PicoContainer * instance. */ public static final Properties HIDE_IMPL = immutable(_HIDE_IMPL, TRUE); /** * Turns off implementation hiding. * @see #HIDE_IMPL for more information. */ public static final Properties NO_HIDE_IMPL = immutable(_HIDE_IMPL, FALSE); public static final Properties ENABLE_CIRCULAR = immutable(_ENABLE_CIRCULAR, TRUE); public static final Properties NONE = immutable(_NONE, ""); /** * Turns on bean-setting property applications where certain simple properties are set * after the object is created based. */ public static final Properties PROPERTY_APPLYING = immutable(_PROPERTY_APPLYING, TRUE); /** * Turns off bean-setting property applications. * @see org.picocontainer.behaviors.PropertyApplying */ public static final Properties NO_PROPERTY_APPLYING = immutable(_PROPERTY_APPLYING, FALSE); public static final Properties AUTOMATIC = immutable(_AUTOMATIC, TRUE); 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) { return immutable(_GUARD, with); }; /** * Transforms a single name value pair unto a read only {@linkplain java.util.Properties} * instance. *

Example Usage:

*
     * 		Properties readOnly = immutable("oneKey","oneValue"};
     * 		assert readOnly.getProperty("oneKey") != null);
     * 
* @param name the property key. * @param value the property value. * @return Read Only properties instance. */ public static Properties immutable(String name, String value) { return new ImmutableProperties(name, value); } /** * Read only property set. Once constructed, all methods that modify state will * throw UnsupportedOperationException. * @author Paul Hammant. */ public static class ImmutableProperties extends Properties { private boolean sealed = false; public ImmutableProperties(String name, String value) { super.setProperty(name, value); sealed = true; } /** * Read Only Object: will throw UnsupportedOperationException. */ @Override @SuppressWarnings("unused") public Object remove( Object o) { throw new UnsupportedOperationException("immutable properties are read only"); } /** * Read Only Object: will throw UnsupportedOperationException. */ @Override @SuppressWarnings("unused") public synchronized Object setProperty(String string, String string1) { throw new UnsupportedOperationException("immutable properties are read only"); } /** * Read Only Object: will throw UnsupportedOperationException. */ @Override public synchronized void clear() { throw new UnsupportedOperationException("immutable properties are read only"); } /** * Once object is constructed, this will throw UnsupportedOperationException because * this class is a read only wrapper. */ @Override public synchronized Object put(Object key, Object value) { if (!sealed) { //setProperty calls put, so until the object is fully constructed, we //cannot seal it. return super.put(key, value); } throw new UnsupportedOperationException("immutable properties are read only"); } /** * Read Only Object: will throw UnsupportedOperationException. */ @Override @SuppressWarnings("unused") public synchronized void putAll(Map t) { throw new UnsupportedOperationException("immutable properties are read only"); } } } libpicocontainer-java-2.15/org/picocontainer/ComponentAdapter.java000066400000000000000000000134511242247644300254520ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer; import java.lang.reflect.Type; /** * A component adapter is responsible for providing a specific component * instance of type <T>. An instance of an implementation of this interface is * used inside a {@link PicoContainer} for every registered component or * instance. Each ComponentAdapter instance has to have a key * which is unique within that container. The key itself is either a class type * (normally an interface) or an identifier. *

In a overly simplistic sense, the ComponentAdapter can be thought of us a type of * an object factory. If you need to modify how your object is constructed, use and appropriate * ComponentAdapter or roll your own since the API is purposely kept rather simple. See * http://www.picocontainer.org/adapters.html * for more information.

* * @author Jon Tirsén * @author Paul Hammant * @author Aslak Hellesøy */ public interface ComponentAdapter { public class NOTHING { private NOTHING(){ } }; /** * Retrieve the key associated with the component. * * @return the component's key. Should either be a class type (normally an interface) or an identifier that is * unique (within the scope of the current PicoContainer). */ Object getComponentKey(); /** * Retrieve the class of the component. * * @return the component's implementation class. Should normally be a concrete class (ie, a class that can be * instantiated). */ Class getComponentImplementation(); /** * Retrieve the component instance. This method will usually create a new instance each time it is called, but that * is not required. For example, {@link org.picocontainer.behaviors.Cached} will always return the * same instance. * * @param container the {@link PicoContainer}, that is used to resolve any possible dependencies of the instance. * @return the component instance. * @throws PicoCompositionException if the component has dependencies which could not be resolved, or * instantiation of the component lead to an ambigous situation within the * container. * @deprecated since PicoContainer 2.2. Use {@link getComponentInstance(PicoContainer,Type)} with {@link ComponentAdapter.NOTHING.class} as type * if no type available. */ T getComponentInstance(PicoContainer container) throws PicoCompositionException; /** * Retrieve the component instance. This method will usually create a new instance each time it is called, but that * is not required. For example, {@link org.picocontainer.behaviors.Cached} will always return the * same instance. * * @param container the {@link org.picocontainer.PicoContainer}, that is used to resolve any possible dependencies of the instance. * @param into the class that is about to be injected into. Use ComponentAdapter.NOTHING.class if this is not important to you. * @return the component instance. * @throws PicoCompositionException if the component has dependencies which could not be resolved, or * instantiation of the component lead to an ambiguous situation within the * container. */ T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException; /** * Verify that all dependencies for this adapter can be satisfied. Normally, the adapter should verify this by * checking that the associated PicoContainer contains all the needed dependencies. * * @param container the {@link PicoContainer}, that is used to resolve any possible dependencies of the instance. * @throws PicoCompositionException if one or more dependencies cannot be resolved. */ void verify(PicoContainer container) throws PicoCompositionException; /** * Accepts a visitor for this ComponentAdapter. The method is normally called by visiting a {@link PicoContainer}, that * cascades the visitor also down to all its ComponentAdapter instances. * * @param visitor the visitor. */ void accept(PicoVisitor visitor); /** * Component adapters may be nested in a chain, and this method is used to grab the next ComponentAdapter in the chain. * @return the next component adapter in line or null if there is no delegate ComponentAdapter. */ ComponentAdapter getDelegate(); /** * Locates a component adapter of type componentAdapterType in the ComponentAdapter chain. Will return null * if there is no adapter of the given type. * @param the type of ComponentAdapter being located. * @param adapterType the class of the adapter type being located. Never null. * @return the appropriate component adapter of type U. May return null if the component adapter type is not * returned. */ U findAdapterOfType(Class adapterType); /** * Get a string key descriptor of the component adapter for use in toString() * @return the descriptor */ String getDescriptor(); } libpicocontainer-java-2.15/org/picocontainer/ComponentFactory.java000066400000000000000000000077711242247644300255110ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import java.util.Properties; /** *

* A component factory is responsible for creating * {@link ComponentAdapter} component adapters. The main use of the component factory is * inside {@link DefaultPicoContainer#DefaultPicoContainer(ComponentFactory)}, where it can * be used to customize the default component adapter that is used when none is specified * explicitly. *

* * @author Paul Hammant * @author Mauro Talevi * @author Jon Tirsén */ public interface ComponentFactory { /** * Create a new component adapter based on the specified arguments. * * @param componentMonitor the component monitor * @param lifecycleStrategy te lifecycle strategy * @param componentProperties the component properties * @param componentKey the key to be associated with this adapter. This * value should be returned from a call to * {@link ComponentAdapter#getComponentKey()} on the created * adapter. * @param componentImplementation the implementation class to be associated * with this adapter. This value should be returned from a call * to {@link ComponentAdapter#getComponentImplementation()} on * the created adapter. Should not be null. * @param parameters additional parameters to use by the component adapter * in constructing component instances. These may be used, for * example, to make decisions about the arguments passed into the * component constructor. These should be considered hints; they * may be ignored by some implementations. May be null, and may * be of zero length. * @return a new component adapter based on the specified arguments. Should * not return null. * @throws PicoCompositionException if the creation of the component adapter * results in a {@link PicoCompositionException}. * @return The component adapter */ ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException; /** * Verification for the ComponentFactory - subject to implementation. * * @param container the {@link PicoContainer}, that is used for verification. * @throws PicoCompositionException if one or more dependencies cannot be resolved. */ void verify(PicoContainer container); /** * Accepts a visitor for this ComponentFactory. The method is normally called by visiting a {@link PicoContainer}, that * cascades the visitor also down to all its ComponentFactory instances. * * @param visitor the visitor. */ void accept(PicoVisitor visitor); } libpicocontainer-java-2.15/org/picocontainer/ComponentLifecycle.java000066400000000000000000000026651242247644300257760ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer; /** * * */ public interface ComponentLifecycle { /** * Invoke the "start" method on the component. * * @param container the container to "start" the component */ void start(PicoContainer container); /** * Invoke the "stop" method on the component. * * @param container the container to "stop" the component */ void stop(PicoContainer container); /** * Invoke the "dispose" method on the component. * * @param container the container to "dispose" the component */ void dispose(PicoContainer container); /** * Test if a component honors a lifecycle. * * @return true if the component has a lifecycle */ boolean componentHasLifecycle(); boolean isStarted(); } libpicocontainer-java-2.15/org/picocontainer/ComponentMonitor.java000066400000000000000000000132571242247644300255250ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammant & Obie Fernandez & Aslak * *****************************************************************************/ package org.picocontainer; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; /** * A component monitor is responsible for monitoring the component instantiation * and method invocation. * * @author Paul Hammant * @author Obie Fernandez * @author Aslak Hellesøy * @author Mauro Talevi */ public interface ComponentMonitor { Object KEEP = new Object(); /** * Event thrown as the component is being instantiated using the given constructor * * @param container * @param componentAdapter * @param constructor the Constructor used to instantiate the addComponent @return the constructor to use in instantiation (nearly always the same one as passed in) */ Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor ); /** * Event thrown after the component has been instantiated using the given constructor. * This should be called for both Constructor and Setter DI. * * @param container * @param componentAdapter * @param constructor the Constructor used to instantiate the addComponent * @param instantiated the component that was instantiated by PicoContainer * @param injected the components during instantiation. * @param duration the duration in milliseconds of the instantiation */ void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] injected, long duration); /** * Event thrown if the component instantiation failed using the given constructor * * @param container * @param componentAdapter * @param constructor the Constructor used to instantiate the addComponent * @param cause the Exception detailing the cause of the failure */ void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception cause); /** * Event thrown as the component method is being invoked on the given instance * * @param container * @param componentAdapter * @param member * @param instance the component instance * @param args */ Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args); /** * Event thrown after the component method has been invoked on the given instance * * @param container * @param componentAdapter * @param member * @param instance the component instance * @param duration * @param args * @param retVal */ void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal); /** * Event thrown if the component method invocation failed on the given instance * * @param member * @param instance the component instance * @param cause the Exception detailing the cause of the failure */ void invocationFailed(Member member, Object instance, Exception cause); /** * Event thrown if a lifecycle method invocation - start, stop or dispose - * failed on the given instance * * @param container * @param componentAdapter * @param method the lifecycle Method invoked on the component instance * @param instance the component instance * @param cause the RuntimeException detailing the cause of the failure */ void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause); /** * No Component has been found for the key in question. Implementers of this have a last chance opportunity to * specify something for the need. This is only relevant to component dependencies, and not to * container.getComponent() in your user code. * * @param container * @param componentKey */ Object noComponentFound(MutablePicoContainer container, Object componentKey); /** * A mechanism to monitor or override the Injectors being made for components. * * @param injector * @return an Injector. For most implementations, the same one as was passed in. */ Injector newInjector(Injector injector); /** * A mechanism to monitor or override the Behaviors being made for components. * * @param behavior * @return an Behavior. For most implementations, the same one as was passed in. */ Behavior newBehavior(Behavior behavior); } libpicocontainer-java-2.15/org/picocontainer/ComponentMonitorStrategy.java000066400000000000000000000026501242247644300272430ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer; /** *

* Interface responsible for changing monitoring strategy. * It may be implemented by {@link org.picocontainer.PicoContainer containers} and * single {@link org.picocontainer.ComponentAdapter component adapters}. * The choice of supporting the monitor strategy is left to the * implementers of the container and adapters. *

* * @author Paul Hammant * @author Joerg Schaible * @author Mauro Talevi */ public interface ComponentMonitorStrategy { /** * Changes the component monitor used * @param monitor the new ComponentMonitor to use */ void changeMonitor(ComponentMonitor monitor); /** * Returns the monitor currently used * @return The ComponentMonitor currently used */ ComponentMonitor currentMonitor(); } libpicocontainer-java-2.15/org/picocontainer/Converters.java000066400000000000000000000025161242247644300243410ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer; import java.lang.reflect.Type; /** * A facade for a collection of converters that provides string-to-type conversions. * * @author Paul Hammant * @author Michael Rimov */ public interface Converters { /** * Returns true if a converters is available to convert to the given object type * * @param type the object Type to convert to * @return true if the type can be converted to */ boolean canConvert(Type type); /** * Converts a particular string value into the target type * * @param value the String value to convert * @param type the object Type to convert to * @return The converted Object instance */ Object convert(String value, Type type); } libpicocontainer-java-2.15/org/picocontainer/Converting.java000066400000000000000000000005621242247644300243240ustar00rootroot00000000000000package org.picocontainer; /** * Interface for containers that can handle string-to-object conversion in object parameters. * @author Paul Hammant */ public interface Converting { /** * Retrieve the set of converters for transforming string parameters * into objects. * @return converter set instance. */ Converters getConverters(); } libpicocontainer-java-2.15/org/picocontainer/DefaultPicoContainer.java000066400000000000000000001346331242247644300262570ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import org.picocontainer.adapters.AbstractAdapter; import org.picocontainer.adapters.InstanceAdapter; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.behaviors.AdaptingBehavior; import org.picocontainer.behaviors.Cached; import org.picocontainer.behaviors.Caching; import org.picocontainer.behaviors.HiddenImplementation; import org.picocontainer.containers.AbstractDelegatingMutablePicoContainer; import org.picocontainer.containers.AbstractDelegatingPicoContainer; import org.picocontainer.containers.EmptyPicoContainer; import org.picocontainer.containers.ImmutablePicoContainer; import org.picocontainer.converters.BuiltInConverters; import org.picocontainer.converters.ConvertsNothing; import org.picocontainer.injectors.AbstractInjector; import org.picocontainer.injectors.AdaptingInjection; import org.picocontainer.injectors.FactoryInjector; import org.picocontainer.lifecycle.DefaultLifecycleState; import org.picocontainer.lifecycle.LifecycleState; import org.picocontainer.lifecycle.StartableLifecycleStrategy; import org.picocontainer.monitors.NullComponentMonitor; import org.picocontainer.parameters.DefaultConstructorParameter; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.ref.WeakReference; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import static org.picocontainer.parameters.BasicComponentParameter.findInjectorOrInstanceAdapter; import static org.picocontainer.parameters.BasicComponentParameter.makeFoundAmbiguousStrings; /** *

* The Standard {@link PicoContainer}/{@link MutablePicoContainer} implementation. * Constructing a container c with a parent p container will cause c to look up components * in p if they cannot be found inside c itself. *

*

* Using {@link Class} objects as keys to the various registerXXX() methods makes * a subtle semantic difference: *

*

* If there are more than one registered components of the same type and one of them are * registered with a {@link java.lang.Class} key of the corresponding type, this addComponent * will take precedence over other components during type resolution. *

*

* Another place where keys that are classes make a subtle difference is in * {@link HiddenImplementation}. *

*

* This implementation of {@link MutablePicoContainer} also supports * {@link ComponentMonitorStrategy}. *

* * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén * @author Thomas Heller * @author Mauro Talevi */ @SuppressWarnings("serial") public class DefaultPicoContainer implements MutablePicoContainer, Converting, ComponentMonitorStrategy, Serializable { private String name; /** * Component factory instance. */ protected final ComponentFactory componentFactory; /** * Parent picocontainer */ private PicoContainer parent; /** * All picocontainer children. */ private final Set children = new HashSet(); /** * Current state of the container. */ private LifecycleState lifecycleState = new DefaultLifecycleState(); /** * Keeps track of child containers started status. */ private final Set> childrenStarted = new HashSet>(); /** * Lifecycle strategy instance. */ protected final LifecycleStrategy lifecycleStrategy; /** * Properties set at the container level, that will affect subsequent components added. */ private final Properties containerProperties = new Properties(); /** * Component monitor instance. Receives event callbacks. */ protected ComponentMonitor componentMonitor; /** * Map used for looking up component adapters by their key. */ private final Map> componentKeyToAdapterCache = new HashMap >(); private final Set> componentAdapters = new LinkedHashSet>(); protected final List> orderedComponentAdapters = new ArrayList>(); private transient IntoThreadLocal intoThreadLocal; private Converters converters; /** * Creates a new container with a custom ComponentFactory and a parent container. *

* * Important note about caching: If you intend the components to be cached, you should pass * in a factory that creates {@link Cached} instances, such as for example * {@link Caching}. Caching can delegate to * other ComponentAdapterFactories. * * * @param componentFactory the factory to use for creation of ComponentAdapters. * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final ComponentFactory componentFactory, final PicoContainer parent) { this(componentFactory, new StartableLifecycleStrategy(new NullComponentMonitor()), parent, new NullComponentMonitor()); } /** * Creates a new container with a custom ComponentFactory, LifecycleStrategy for instance registration, * and a parent container. *

* * Important note about caching: If you intend the components to be cached, you should pass * in a factory that creates {@link Cached} instances, such as for example * {@link Caching}. Caching can delegate to * other ComponentAdapterFactories. * * * @param componentFactory the factory to use for creation of ComponentAdapters. * @param lifecycleStrategy * the lifecycle strategy chosen for registered * instance (not implementations!) * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final ComponentFactory componentFactory, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { this(componentFactory, lifecycleStrategy, parent, new NullComponentMonitor() ); } public DefaultPicoContainer(final ComponentFactory componentFactory, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent, final ComponentMonitor componentMonitor) { if (componentFactory == null) { throw new NullPointerException("componentFactory"); } if (lifecycleStrategy == null) { throw new NullPointerException("lifecycleStrategy"); } this.componentFactory = componentFactory; this.lifecycleStrategy = lifecycleStrategy; this.parent = parent; if (parent != null && !(parent instanceof EmptyPicoContainer)) { this.parent = new ImmutablePicoContainer(parent); } this.componentMonitor = componentMonitor; } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor * * @param monitor the ComponentMonitor to use * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final ComponentMonitor monitor, final PicoContainer parent) { this(new AdaptingBehavior(), new StartableLifecycleStrategy(monitor), parent, monitor); } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor and lifecycle strategy * * @param monitor the ComponentMonitor to use * @param lifecycleStrategy the lifecycle strategy to use. * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final ComponentMonitor monitor, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { this(new AdaptingBehavior(), lifecycleStrategy, parent, monitor); } /** * Creates a new container with the AdaptingInjection using a * custom lifecycle strategy * * @param lifecycleStrategy the lifecycle strategy to use. * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { this(new NullComponentMonitor(), lifecycleStrategy, parent); } /** * Creates a new container with a custom ComponentFactory and no parent container. * * @param componentFactory the ComponentFactory to use. */ public DefaultPicoContainer(final ComponentFactory componentFactory) { this(componentFactory, null); } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor * * @param monitor the ComponentMonitor to use */ public DefaultPicoContainer(final ComponentMonitor monitor) { this(monitor, new StartableLifecycleStrategy(monitor), null); } /** * Creates a new container with a (caching) {@link AdaptingInjection} * and a parent container. * * @param parent the parent container (used for component dependency lookups). */ public DefaultPicoContainer(final PicoContainer parent) { this(new AdaptingBehavior(), parent); } /** Creates a new container with a {@link AdaptingBehavior} and no parent container. */ public DefaultPicoContainer() { this(new AdaptingBehavior(), null); } /** {@inheritDoc} **/ public Collection> getComponentAdapters() { return Collections.unmodifiableSet(getModifiableComponentAdapterList()); } /** {@inheritDoc} **/ public final ComponentAdapter getComponentAdapter(final Object componentKey) { ComponentAdapter adapter = getComponentKeyToAdapterCache().get(componentKey); if (adapter == null && parent != null) { adapter = getParent().getComponentAdapter(componentKey); if (adapter != null) { adapter = new KnowsContainerAdapter(adapter, getParent()); } } if (adapter == null) { Object inst = componentMonitor.noComponentFound(this, componentKey); if (inst != null) { adapter = new LateInstance(componentKey, inst); } } return adapter; } public static class LateInstance extends AbstractAdapter { private final Object instance; private LateInstance(Object componentKey, Object instance) { super(componentKey, instance.getClass()); this.instance = instance; } public Object getComponentInstance() { return instance; } public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return instance; } public void verify(PicoContainer container) throws PicoCompositionException { } public String getDescriptor() { return "LateInstance"; } } public static class KnowsContainerAdapter implements ComponentAdapter { private final ComponentAdapter ca; private final PicoContainer ctr; public KnowsContainerAdapter(ComponentAdapter ca, PicoContainer ctr) { this.ca = ca; this.ctr = ctr; } public T getComponentInstance(Type into) throws PicoCompositionException { return getComponentInstance(ctr, into); } public Object getComponentKey() { return ca.getComponentKey(); } public Class getComponentImplementation() { return ca.getComponentImplementation(); } public T getComponentInstance(PicoContainer container) throws PicoCompositionException { return ca.getComponentInstance(container); } public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return ca.getComponentInstance(container, into); } public void verify(PicoContainer container) throws PicoCompositionException { ca.verify(container); } public void accept(PicoVisitor visitor) { ca.accept(visitor); } public ComponentAdapter getDelegate() { return ca.getDelegate(); } public U findAdapterOfType(Class adapterType) { return ca.findAdapterOfType(adapterType); } public String getDescriptor() { return null; } } /** {@inheritDoc} **/ public ComponentAdapter getComponentAdapter(final Class componentType, final NameBinding componentNameBinding) { return getComponentAdapter(componentType, componentNameBinding, null); } /** {@inheritDoc} **/ private ComponentAdapter getComponentAdapter(final Class componentType, final NameBinding componentNameBinding, final Class binding) { // See http://jira.codehaus.org/secure/ViewIssue.jspa?key=PICO-115 ComponentAdapter adapterByKey = getComponentAdapter(componentType); if (adapterByKey != null) { return typeComponentAdapter(adapterByKey); } List> found = binding == null ? getComponentAdapters(componentType) : getComponentAdapters(componentType, binding); if (found.size() == 1) { return found.get(0); } else if (found.isEmpty()) { if (parent != null) { return getParent().getComponentAdapter(componentType, componentNameBinding); } else { return null; } } else { if (componentNameBinding != null) { String parameterName = componentNameBinding.getName(); if (parameterName != null) { ComponentAdapter ca = getComponentAdapter(parameterName); if (ca != null && componentType.isAssignableFrom(ca.getComponentImplementation())) { return typeComponentAdapter(ca); } } } String[] foundStrings = makeFoundAmbiguousStrings(found); throw new AbstractInjector.AmbiguousComponentResolutionException(componentType, foundStrings); } } /** {@inheritDoc} **/ public ComponentAdapter getComponentAdapter(final Class componentType, final Class binding) { // 1 return getComponentAdapter(componentType, null, binding); } /** {@inheritDoc} **/ public List> getComponentAdapters(final Class componentType) { return getComponentAdapters(componentType, null); } /** {@inheritDoc} **/ public List> getComponentAdapters(final Class componentType, final Class binding) { if (componentType == null) { return Collections.emptyList(); } List> found = new ArrayList>(); for (ComponentAdapter componentAdapter : getComponentAdapters()) { Object k = componentAdapter.getComponentKey(); if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation()) && (!(k instanceof BindKey) || (k instanceof BindKey && (((BindKey)k).getAnnotation() == null || binding == null || ((BindKey)k).getAnnotation() == binding)))) { found.add((ComponentAdapter)typeComponentAdapter(componentAdapter)); } } return found; } protected MutablePicoContainer addAdapterInternal(ComponentAdapter componentAdapter) { Object componentKey = componentAdapter.getComponentKey(); if (getComponentKeyToAdapterCache().containsKey(componentKey)) { throw new PicoCompositionException("Duplicate Keys not allowed. Duplicate for '" + componentKey + "'"); } getModifiableComponentAdapterList().add(componentAdapter); getComponentKeyToAdapterCache().put(componentKey, componentAdapter); return this; } /** * {@inheritDoc} * This method can be used to override the ComponentAdapter created by the {@link ComponentFactory} * passed to the constructor of this container. */ public MutablePicoContainer addAdapter(final ComponentAdapter componentAdapter) { return addAdapter(componentAdapter, this.containerProperties); } /** {@inheritDoc} **/ public MutablePicoContainer addAdapter(final ComponentAdapter componentAdapter, final Properties properties) { Properties tmpProperties = (Properties)properties.clone(); AbstractBehaviorFactory.removePropertiesIfPresent(tmpProperties, Characteristics.USE_NAMES); if (AbstractBehaviorFactory.removePropertiesIfPresent(tmpProperties, Characteristics.NONE) == false && componentFactory instanceof BehaviorFactory) { MutablePicoContainer container = addAdapterInternal(((BehaviorFactory)componentFactory).addComponentAdapter( componentMonitor, lifecycleStrategy, tmpProperties, componentAdapter)); throwIfPropertiesLeft(tmpProperties); return container; } else { return addAdapterInternal(componentAdapter); } } /** {@inheritDoc} **/ public ComponentAdapter removeComponent(final Object componentKey) { lifecycleState.removingComponent(); ComponentAdapter adapter = (ComponentAdapter) getComponentKeyToAdapterCache().remove(componentKey); getModifiableComponentAdapterList().remove(adapter); getOrderedComponentAdapters().remove(adapter); return adapter; } /** * {@inheritDoc} * The returned ComponentAdapter will be an {@link org.picocontainer.adapters.InstanceAdapter}. */ public MutablePicoContainer addComponent(final Object implOrInstance) { return addComponent(implOrInstance, this.containerProperties); } private MutablePicoContainer addComponent(final Object implOrInstance, final Properties props) { Class clazz; if (implOrInstance instanceof String) { return addComponent(implOrInstance, implOrInstance); } if (implOrInstance instanceof Class) { clazz = (Class)implOrInstance; } else { clazz = implOrInstance.getClass(); } return addComponent(clazz, implOrInstance, props); } public MutablePicoContainer addConfig(final String name, final Object val) { return addAdapterInternal(new InstanceAdapter(name, val, lifecycleStrategy, componentMonitor)); } /** * {@inheritDoc} * The returned ComponentAdapter will be instantiated by the {@link ComponentFactory} * passed to the container's constructor. */ public MutablePicoContainer addComponent(final Object componentKey, final Object componentImplementationOrInstance, final Parameter... parameters) { return this.addComponent(componentKey, componentImplementationOrInstance, this.containerProperties, parameters); } private MutablePicoContainer addComponent(final Object componentKey, final Object componentImplementationOrInstance, final Properties properties, Parameter... parameters) { if (parameters != null && parameters.length == 0) { parameters = null; // backwards compatibility! solve this better later - Paul } //New replacement for Parameter.ZERO. if (parameters != null && parameters.length == 1 && DefaultConstructorParameter.INSTANCE.equals(parameters[0])) { parameters = new Parameter[0]; } if (componentImplementationOrInstance instanceof Class) { Properties tmpProperties = (Properties) properties.clone(); ComponentAdapter adapter = componentFactory.createComponentAdapter(componentMonitor, lifecycleStrategy, tmpProperties, componentKey, (Class)componentImplementationOrInstance, parameters); AbstractBehaviorFactory.removePropertiesIfPresent(tmpProperties, Characteristics.USE_NAMES); throwIfPropertiesLeft(tmpProperties); if (lifecycleState.isStarted()) { addAdapterIfStartable(adapter); potentiallyStartAdapter(adapter); } return addAdapterInternal(adapter); } else { ComponentAdapter adapter = new InstanceAdapter(componentKey, componentImplementationOrInstance, lifecycleStrategy, componentMonitor); if (lifecycleState.isStarted()) { addAdapterIfStartable(adapter); potentiallyStartAdapter(adapter); } return addAdapter(adapter, properties); } } private void throwIfPropertiesLeft(final Properties tmpProperties) { if(tmpProperties.size() > 0) { throw new PicoCompositionException("Unprocessed Characteristics:" + tmpProperties +", please refer to http://picocontainer.org/unprocessed-properties-help.html"); } } private synchronized void addOrderedComponentAdapter(final ComponentAdapter componentAdapter) { if (!getOrderedComponentAdapters().contains(componentAdapter)) { getOrderedComponentAdapters().add(componentAdapter); } } public List getComponents() throws PicoException { return getComponents(Object.class); } public List getComponents(final Class componentType) { if (componentType == null) { return Collections.emptyList(); } Map, T> adapterToInstanceMap = new HashMap, T>(); List result = new ArrayList(); synchronized(this) { for (ComponentAdapter componentAdapter : getModifiableComponentAdapterList()) { if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) { ComponentAdapter typedComponentAdapter = typeComponentAdapter(componentAdapter); T componentInstance = getLocalInstance(typedComponentAdapter); adapterToInstanceMap.put(typedComponentAdapter, componentInstance); } } for (ComponentAdapter componentAdapter : getOrderedComponentAdapters()) { final T componentInstance = adapterToInstanceMap.get(componentAdapter); if (componentInstance != null) { // may be null in the case of the "implicit" addAdapter // representing "this". result.add(componentInstance); } } } return result; } private T getLocalInstance(final ComponentAdapter typedComponentAdapter) { T componentInstance = typedComponentAdapter.getComponentInstance(this, ComponentAdapter.NOTHING.class); // This is to ensure all are added. (Indirect dependencies will be added // from InstantiatingComponentAdapter). addOrderedComponentAdapter(typedComponentAdapter); return componentInstance; } @SuppressWarnings({ "unchecked" }) private static ComponentAdapter typeComponentAdapter(final ComponentAdapter componentAdapter) { return (ComponentAdapter)componentAdapter; } public Object getComponent(final Object componentKeyOrType) { return getComponent(componentKeyOrType, null); } public Object getComponent(final Object componentKeyOrType, Type into) { synchronized (this) { if (intoThreadLocal == null) { intoThreadLocal = new IntoThreadLocal(); } } intoThreadLocal.set(into); try { return getComponent(componentKeyOrType, (Class) null); } finally { intoThreadLocal.set(null); } } public Object getComponent(final Object componentKeyOrType, final Class annotation) { ComponentAdapter componentAdapter = null; Object component; try { if (annotation != null) { componentAdapter = getComponentAdapter((Class)componentKeyOrType, annotation); component = componentAdapter == null ? null : getInstance(componentAdapter, null); } else if (componentKeyOrType instanceof Class) { componentAdapter = getComponentAdapter((Class)componentKeyOrType, (NameBinding) null); component = componentAdapter == null ? null : getInstance(componentAdapter, (Class)componentKeyOrType); } else { componentAdapter = getComponentAdapter(componentKeyOrType); component = componentAdapter == null ? null : getInstance(componentAdapter, null); } } catch (AbstractInjector.AmbiguousComponentResolutionException e) { if (componentAdapter != null) { e.setComponent(findInjectorOrInstanceAdapter(componentAdapter).toString()); } throw e; } return decorateComponent(component, componentAdapter); } /** * This is invoked when getComponent(..) is called. It allows extendees to decorate a * component before it is returned to the caller. * @param component the component that will be returned for getComponent(..) * @param componentAdapter the component adapter that made that component * @return the component (the same as that passed in by default) */ protected Object decorateComponent(Object component, ComponentAdapter componentAdapter) { if (componentAdapter instanceof ComponentLifecycle && lifecycleStrategy.isLazy(componentAdapter) // is Lazy && !((ComponentLifecycle) componentAdapter).isStarted()) { ((ComponentLifecycle)componentAdapter).start(this); } return component; } public T getComponent(final Class componentType) { Object o = getComponent((Object)componentType, null); return componentType.cast(o); } public T getComponent(final Class componentType, final Class binding) { Object o = getComponent((Object)componentType, binding); return componentType.cast(o); } private Object getInstance(final ComponentAdapter componentAdapter, Class componentKey) { // check whether this is our adapter // we need to check this to ensure up-down dependencies cannot be followed final boolean isLocal = getModifiableComponentAdapterList().contains(componentAdapter); if (isLocal || componentAdapter instanceof LateInstance) { Object instance; try { if (componentAdapter instanceof FactoryInjector) { instance = ((FactoryInjector) componentAdapter).getComponentInstance(this, getInto()); } else { instance = componentAdapter.getComponentInstance(this, getInto()); } } catch (AbstractInjector.CyclicDependencyException e) { if (parent != null) { instance = getParent().getComponent(componentAdapter.getComponentKey()); if (instance != null) { return instance; } } throw e; } addOrderedComponentAdapter(componentAdapter); return instance; } else if (parent != null) { Object key = componentKey; if (key == null) { key = componentAdapter.getComponentKey(); } return getParent().getComponent(key); } return null; } private Type getInto() { if (intoThreadLocal == null) { return null; } return intoThreadLocal.get(); } /** {@inheritDoc} **/ public PicoContainer getParent() { return parent; } /** {@inheritDoc} **/ public ComponentAdapter removeComponentByInstance(final T componentInstance) { for (ComponentAdapter componentAdapter : getModifiableComponentAdapterList()) { if (getLocalInstance(componentAdapter).equals(componentInstance)) { return removeComponent(componentAdapter.getComponentKey()); } } return null; } /** * Start the components of this PicoContainer and all its logical child containers. * The starting of the child container is only attempted if the parent * container start successfully. The child container for which start is attempted * is tracked so that upon stop, only those need to be stopped. * The lifecycle operation is delegated to the component adapter, * if it is an instance of {@link Behavior lifecycle manager}. * The actual {@link LifecycleStrategy lifecycle strategy} supported * depends on the concrete implementation of the adapter. * * @see Behavior * @see LifecycleStrategy * @see #makeChildContainer() * @see #addChildContainer(PicoContainer) * @see #removeChildContainer(PicoContainer) */ public synchronized void start() { lifecycleState.starting(); startAdapters(); childrenStarted.clear(); for (PicoContainer child : children) { childrenStarted.add(new WeakReference(child)); if (child instanceof Startable) { ((Startable)child).start(); } } } /** * Stop the components of this PicoContainer and all its logical child containers. * The stopping of the child containers is only attempted for those that have been * started, possibly not successfully. * The lifecycle operation is delegated to the component adapter, * if it is an instance of {@link Behavior lifecycle manager}. * The actual {@link LifecycleStrategy lifecycle strategy} supported * depends on the concrete implementation of the adapter. * * @see Behavior * @see LifecycleStrategy * @see #makeChildContainer() * @see #addChildContainer(PicoContainer) * @see #removeChildContainer(PicoContainer) */ public synchronized void stop() { lifecycleState.stopping(); for (PicoContainer child : children) { if (childStarted(child)) { if (child instanceof Startable) { ((Startable)child).stop(); } } } stopAdapters(); lifecycleState.stopped(); } /** * Checks the status of the child container to see if it's been started * to prevent IllegalStateException upon stop * * @param child the child PicoContainer * * @return A boolean, true if the container is started */ private boolean childStarted(final PicoContainer child) { for (WeakReference eachChild : childrenStarted) { PicoContainer ref = eachChild.get(); if (ref == null) { continue; } if (child.equals(ref)) { return true; } } return false; } /** * Dispose the components of this PicoContainer and all its logical child containers. * The lifecycle operation is delegated to the component adapter, * if it is an instance of {@link Behavior lifecycle manager}. * The actual {@link LifecycleStrategy lifecycle strategy} supported * depends on the concrete implementation of the adapter. * * @see Behavior * @see LifecycleStrategy * @see #makeChildContainer() * @see #addChildContainer(PicoContainer) * @see #removeChildContainer(PicoContainer) */ public synchronized void dispose() { if (lifecycleState.isStarted()) { stop(); } lifecycleState.disposing(); for (PicoContainer child : children) { if (child instanceof MutablePicoContainer) { ((Disposable)child).dispose(); } } disposeAdapters(); lifecycleState.disposed(); } public synchronized void setLifecycleState(LifecycleState lifecycleState) { this.lifecycleState = lifecycleState; } public MutablePicoContainer makeChildContainer() { DefaultPicoContainer pc = new DefaultPicoContainer(componentFactory, lifecycleStrategy, this, componentMonitor); addChildContainer(pc); return pc; } /** * Checks for identical references in the child container. It doesn't * traverse an entire hierarchy, namely it simply checks for child containers * that are equal to the current container. * @param child */ private void checkCircularChildDependencies(PicoContainer child) { final String MESSAGE = "Cannot have circular dependency between parent %s and child: %s"; if (child == this) { throw new IllegalArgumentException(String.format(MESSAGE,this,child)); } //Todo: Circular Import Dependency on AbstractDelegatingPicoContainer if (child instanceof AbstractDelegatingPicoContainer) { AbstractDelegatingPicoContainer delegateChild = (AbstractDelegatingPicoContainer) child; while(delegateChild != null) { PicoContainer delegateInstance = delegateChild.getDelegate(); if (this == delegateInstance) { throw new IllegalArgumentException(String.format(MESSAGE,this,child)); } if (delegateInstance instanceof AbstractDelegatingPicoContainer) { delegateChild = (AbstractDelegatingPicoContainer) delegateInstance; } else { delegateChild = null; } } } } public MutablePicoContainer addChildContainer(final PicoContainer child) { checkCircularChildDependencies(child); if (children.add(child)) { // TODO Should only be added if child container has also be started if (lifecycleState.isStarted()) { childrenStarted.add(new WeakReference(child)); } } return this; } public boolean removeChildContainer(final PicoContainer child) { final boolean result = children.remove(child); WeakReference foundRef = null; for (WeakReference eachChild : childrenStarted) { PicoContainer ref = eachChild.get(); if (ref.equals(child)) { foundRef = eachChild; break; } } if (foundRef != null) { childrenStarted.remove(foundRef); } return result; } public MutablePicoContainer change(final Properties... properties) { for (Properties c : properties) { Enumeration e = (Enumeration) c.propertyNames(); while (e.hasMoreElements()) { String s = e.nextElement(); containerProperties.setProperty(s,c.getProperty(s)); } } return this; } public MutablePicoContainer as(final Properties... properties) { return new AsPropertiesPicoContainer(properties); } public void accept(final PicoVisitor visitor) { //TODO Pico 3 : change accept signatures to allow abort at any point in the traversal. boolean shouldContinue = visitor.visitContainer(this); if (!shouldContinue) { return; } componentFactory.accept(visitor); // will cascade through behaviors final List> componentAdapters = new ArrayList>(getComponentAdapters()); for (ComponentAdapter componentAdapter : componentAdapters) { componentAdapter.accept(visitor); } final List allChildren = new ArrayList(children); for (PicoContainer child : allChildren) { child.accept(visitor); } } /** * Changes monitor in the ComponentFactory, the component adapters * and the child containers, if these support a ComponentMonitorStrategy. * {@inheritDoc} */ public void changeMonitor(final ComponentMonitor monitor) { this.componentMonitor = monitor; if (lifecycleStrategy instanceof ComponentMonitorStrategy) { ((ComponentMonitorStrategy)lifecycleStrategy).changeMonitor(monitor); } for (ComponentAdapter adapter : getModifiableComponentAdapterList()) { if (adapter instanceof ComponentMonitorStrategy) { ((ComponentMonitorStrategy)adapter).changeMonitor(monitor); } } for (PicoContainer child : children) { if (child instanceof ComponentMonitorStrategy) { ((ComponentMonitorStrategy)child).changeMonitor(monitor); } } } /** * Returns the first current monitor found in the ComponentFactory, the component adapters * and the child containers, if these support a ComponentMonitorStrategy. * {@inheritDoc} * * @throws PicoCompositionException if no component monitor is found in container or its children */ public ComponentMonitor currentMonitor() { return componentMonitor; } /** * Loops over all component adapters and invokes * start(PicoContainer) method on the ones which are LifecycleManagers */ private void startAdapters() { Collection> adapters = getComponentAdapters(); for (ComponentAdapter adapter : adapters) { addAdapterIfStartable(adapter); } adapters = getOrderedComponentAdapters(); // clone the adapters List> adaptersClone = new ArrayList>(adapters); for (final ComponentAdapter adapter : adaptersClone) { potentiallyStartAdapter(adapter); } } protected void potentiallyStartAdapter(ComponentAdapter adapter) { if (adapter instanceof ComponentLifecycle) { if (!lifecycleStrategy.isLazy(adapter)) { ((ComponentLifecycle)adapter).start(this); } } } private void addAdapterIfStartable(ComponentAdapter adapter) { if (adapter instanceof ComponentLifecycle) { ComponentLifecycle componentLifecycle = (ComponentLifecycle)adapter; if (componentLifecycle.componentHasLifecycle()) { // create an instance, it will be added to the ordered CA list instantiateComponentAsIsStartable(adapter); addOrderedComponentAdapter(adapter); } } } protected void instantiateComponentAsIsStartable(ComponentAdapter adapter) { if (!lifecycleStrategy.isLazy(adapter)) { adapter.getComponentInstance(DefaultPicoContainer.this, ComponentAdapter.NOTHING.class); } } /** * Loops over started component adapters (in inverse order) and invokes * stop(PicoContainer) method on the ones which are LifecycleManagers */ private void stopAdapters() { for (int i = getOrderedComponentAdapters().size() - 1; 0 <= i; i--) { ComponentAdapter adapter = getOrderedComponentAdapters().get(i); if (adapter instanceof ComponentLifecycle) { ComponentLifecycle componentLifecycle = (ComponentLifecycle)adapter; if (componentLifecycle.componentHasLifecycle() && componentLifecycle.isStarted()) { componentLifecycle.stop(DefaultPicoContainer.this); } } } } /** * Loops over all component adapters (in inverse order) and invokes * dispose(PicoContainer) method on the ones which are LifecycleManagers */ private void disposeAdapters() { for (int i = getOrderedComponentAdapters().size() - 1; 0 <= i; i--) { ComponentAdapter adapter = getOrderedComponentAdapters().get(i); if (adapter instanceof ComponentLifecycle) { ComponentLifecycle componentLifecycle = (ComponentLifecycle)adapter; componentLifecycle.dispose(DefaultPicoContainer.this); } } } /** * @return the orderedComponentAdapters */ protected List> getOrderedComponentAdapters() { return orderedComponentAdapters; } /** * @return the componentKeyToAdapterCache */ protected Map> getComponentKeyToAdapterCache() { return componentKeyToAdapterCache; } /** * @return the componentAdapters */ protected Set> getModifiableComponentAdapterList() { return componentAdapters; } public synchronized void setName(String name) { this.name = name; } @Override public String toString() { return String.format("%s:%d<%s", (name != null ? name : super.toString()), this.componentAdapters.size(), (parent != null && !(parent instanceof EmptyPicoContainer)? parent.toString() : "|")); } /** * If this container has a set of converters, then return it. * If it does not, and the parent (or their parent ..) does, use that * If they do not, return a NullObject implementation (ConversNothing) * @return the converters */ public synchronized Converters getConverters() { if (converters == null) { if (parent == null || (parent instanceof Converting && ((Converting) parent).getConverters() instanceof ConvertsNothing)) { converters = new BuiltInConverters(); } else { return ((Converting) parent).getConverters(); } } return converters; } @SuppressWarnings("synthetic-access") private class AsPropertiesPicoContainer extends AbstractDelegatingMutablePicoContainer { private final Properties properties; public AsPropertiesPicoContainer(final Properties... props) { super(DefaultPicoContainer.this); properties = (Properties) containerProperties.clone(); for (Properties c : props) { Enumeration e = c.propertyNames(); while (e.hasMoreElements()) { String s = (String)e.nextElement(); properties.setProperty(s,c.getProperty(s)); } } } @Override @SuppressWarnings("unused") public MutablePicoContainer as( Properties... props) { throw new PicoCompositionException("Syntax 'as(FOO).as(BAR)' not allowed, do 'as(FOO, BAR)' instead"); } @Override public MutablePicoContainer makeChildContainer() { return getDelegate().makeChildContainer(); } @Override public MutablePicoContainer addComponent(final Object componentKey, final Object componentImplementationOrInstance, final Parameter... parameters) throws PicoCompositionException { return DefaultPicoContainer.this.addComponent(componentKey, componentImplementationOrInstance, properties, parameters); } @Override public MutablePicoContainer addComponent(final Object implOrInstance) throws PicoCompositionException { return DefaultPicoContainer.this.addComponent(implOrInstance, properties); } @Override public MutablePicoContainer addAdapter(final ComponentAdapter componentAdapter) throws PicoCompositionException { return DefaultPicoContainer.this.addAdapter(componentAdapter, properties); } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getLifecycleState() */ @Override public LifecycleState getLifecycleState() { return DefaultPicoContainer.this.getLifecycleState(); } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getName() */ @Override public String getName() { return DefaultPicoContainer.this.getName(); } } private static class IntoThreadLocal extends ThreadLocal implements Serializable { @Override protected Type initialValue() { return ComponentAdapter.NOTHING.class; } } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getLifecycleState() */ public synchronized LifecycleState getLifecycleState() { return lifecycleState; } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getName() */ public synchronized String getName() { return this.name; } } libpicocontainer-java-2.15/org/picocontainer/Disposable.java000066400000000000000000000031261242247644300242720ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the license.html file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer; /** * An interface which is implemented by components that need to dispose of resources during the shutdown of that * component. The {@link Disposable#dispose()} must be called once during shutdown, directly after {@link * Startable#stop()} (if the component implements the {@link Startable} interface). * @see org.picocontainer.Startable the Startable interface if you need to start() and * stop() semantics. * @see org.picocontainer.PicoContainer the main PicoContainer interface (and hence its subinterfaces and * implementations like {@link DefaultPicoContainer}) implement this interface. */ public interface Disposable { /** * Dispose this component. The component should deallocate all resources. The contract for this method defines a * single call at the end of this component's life. */ void dispose(); } libpicocontainer-java-2.15/org/picocontainer/Emjection.java000066400000000000000000000037111242247644300241220ustar00rootroot00000000000000package org.picocontainer; import org.picocontainer.containers.ImmutablePicoContainer; import org.picocontainer.containers.TransientPicoContainer; import org.picocontainer.injectors.ConstructorInjection; 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 neu(Class type, Emjection emjection, Object... args) { if (emjection.pico == null) { throw new PicoCompositionException("blah"); } TransientPicoContainer tpc = new TransientPicoContainer(new ConstructorInjection(), 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 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); } } libpicocontainer-java-2.15/org/picocontainer/InjectionFactory.java000066400000000000000000000014431242247644300254570ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; public interface InjectionFactory extends ComponentFactory { } libpicocontainer-java-2.15/org/picocontainer/Injector.java000066400000000000000000000023171242247644300237630ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer; import java.lang.reflect.Type; /** * Implementers are responsible for instantiating and injecting dependancies into * Constructors, Methods and Fields. */ public interface Injector extends ComponentAdapter { /** * A preexiting component instance can be injected into after instantiation * * * @param container the container that can provide injectable dependencies * @param into * @param instance the instance to * @return */ Object decorateComponentInstance(PicoContainer container, Type into, T instance); } libpicocontainer-java-2.15/org/picocontainer/LifecycleStrategy.java000066400000000000000000000046601242247644300256330ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer; /** * An interface which specifies the lifecycle strategy on the component instance. * Lifecycle strategies are used by component adapters to delegate the lifecycle * operations on the component instances. * * @author Paul Hammant * @author Peter Royal * @author Jörg Schaible * @author Mauro Talevi * @see org.picocontainer.Startable * @see org.picocontainer.Disposable */ public interface LifecycleStrategy { /** * Invoke the "start" method on the component instance if this is startable. * It is up to the implementation of the strategy what "start" and "startable" means. * * @param component the instance of the component to start */ void start(Object component); /** * Invoke the "stop" method on the component instance if this is stoppable. * It is up to the implementation of the strategy what "stop" and "stoppable" means. * * @param component the instance of the component to stop */ void stop(Object component); /** * Invoke the "dispose" method on the component instance if this is disposable. * It is up to the implementation of the strategy what "dispose" and "disposable" means. * * @param component the instance of the component to dispose */ void dispose(Object component); /** * Test if a component instance has a lifecycle. * @param type the component's type * * @return true if the component has a lifecycle */ boolean hasLifecycle(Class type); /** * Is a component eager (not lazy) in that it should start when start() or equivalent is called, * or lazy (it will only start on first getComponent() ). * The default is the first of those two. * * @param adapter * @return true if lazy, false if not lazy */ boolean isLazy(ComponentAdapter adapter); } libpicocontainer-java-2.15/org/picocontainer/MutablePicoContainer.java000066400000000000000000000224761242247644300262650ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by various * *****************************************************************************/ package org.picocontainer; import org.picocontainer.lifecycle.LifecycleState; import java.util.Properties; /** * This is the core interface used for registration of components with a container. It is possible to register * implementations and instances here * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén * @see See package description for basic overview how to use PicoContainer. */ public interface MutablePicoContainer extends PicoContainer, Startable, Disposable { /** * Register a component and creates specific instructions on which constructor to use, along with * which components and/or constants to provide as constructor arguments. These "directives" are * provided through an array of Parameter objects. Parameter[0] correspondes to the first constructor * argument, Parameter[N] corresponds to the N+1th constructor argument. *

Tips for Parameter usage

*
    *
  • Partial Autowiring: If you have two constructor args to match and you only wish to specify one of the constructors and * let PicoContainer wire the other one, you can use as parameters: * new ComponentParameter(), new ComponentParameter("someService") * The default constructor for the component parameter indicates auto-wiring should take place for * that parameter. *
  • *
  • Force No-Arg constructor usage: If you wish to force a component to be constructed with * the no-arg constructor, use a zero length Parameter array. Ex: new Parameter[0] *
      * * @param componentKey a key that identifies the component. Must be unique within the container. The type * of the key object has no semantic significance unless explicitly specified in the * documentation of the implementing container. * @param componentImplementationOrInstance * the component's implementation class. This must be a concrete class (ie, a * class that can be instantiated). Or an intance of the compoent. * @param parameters the parameters that gives the container hints about what arguments to pass * to the constructor when it is instantiated. Container implementations may ignore * one or more of these hints. * * @return the same instance of MutablePicoContainer * * @throws PicoCompositionException if registration of the component fails. * @see org.picocontainer.Parameter * @see org.picocontainer.parameters.ConstantParameter * @see org.picocontainer.parameters.ComponentParameter */ MutablePicoContainer addComponent(Object componentKey, Object componentImplementationOrInstance, Parameter... parameters); /** * Register an arbitrary object. The class of the object will be used as a key. Calling this method is equivalent to * calling addComponent(componentImplementation, componentImplementation). * * @param implOrInstance Component implementation or instance * * @return the same instance of MutablePicoContainer * * @throws PicoCompositionException if registration fails. */ MutablePicoContainer addComponent(Object implOrInstance); /** * Register a config item. * * @param name the name of the config item * @param val the value of the config item * * @return the same instance of MutablePicoContainer * * @throws PicoCompositionException if registration fails. */ MutablePicoContainer addConfig(String name, Object val); /** * Register a component via a ComponentAdapter. Use this if you need fine grained control over what * ComponentAdapter to use for a specific component. The adapter will be wrapped in whatever behaviors that the * the container has been set up with. If you want to bypass that behavior for the adapter you are adding, * you should use Characteristics.NONE like so pico.as(Characteristics.NONE).addAdapter(...) * * @param componentAdapter the adapter * * @return the same instance of MutablePicoContainer * * @throws PicoCompositionException if registration fails. */ MutablePicoContainer addAdapter(ComponentAdapter componentAdapter); /** * Unregister a component by key. * * @param componentKey key of the component to unregister. * * @return the ComponentAdapter that was associated with this component. */ ComponentAdapter removeComponent(Object componentKey); /** * Unregister a component by instance. * * @param componentInstance the component instance to unregister. * * @return the same instance of MutablePicoContainer */ ComponentAdapter removeComponentByInstance(T componentInstance); /** * Make a child container, using both the same implementation of MutablePicoContainer as the parent * and identical behaviors as well. * It will have a reference to this as parent. This will list the resulting MPC as a child. * Lifecycle events will be cascaded from parent to child * as a consequence of this. *

      Note that for long-lived parent containers, you need to unregister child containers * made with this call before disposing or you will leak memory. (Experience * speaking here! )

      *

      Incorrect Example:

      *
           *   MutablePicoContainer parent = new PicoBuilder().withCaching().withLifecycle().build();
           *   MutablePicoContainer child = parent.makeChildContainer();
           *   child = null; //Child still retains in memory because parent still holds reference.
           * 
      *

      Correct Example:

      *
           *   MutablePicoContainer parent = new PicoBuilder().withCaching().withLifecycle().build();
           *   MutablePicoContainer child = parent.makeChildContainer();
           *   parent.removeChildContainer(child); //Remove the bi-directional references.
           *   child = null; 
           * 
      * @return the new child container. */ MutablePicoContainer makeChildContainer(); /** * Add a child container. This action will list the the 'child' as exactly that in the parents scope. * It will not change the child's view of a parent. That is determined by the constructor arguments of the child * itself. Lifecycle events will be cascaded from parent to child * as a consequence of calling this method. * * @param child the child container * * @return the same instance of MutablePicoContainer * */ MutablePicoContainer addChildContainer(PicoContainer child); /** * Remove a child container from this container. It will not change the child's view of a parent. * Lifecycle event will no longer be cascaded from the parent to the child. * * @param child the child container * * @return true if the child container has been removed. * */ boolean removeChildContainer(PicoContainer child); /** * You can change the characteristic of registration of all subsequent components in this container. * * @param properties * @return the same Pico instance with changed properties */ MutablePicoContainer change(Properties... properties); /** * You can set for the following operation only the characteristic of registration of a component on the fly. * * @param properties * @return the same Pico instance with temporary properties */ MutablePicoContainer as(Properties... properties); /** * Name the container instance, to assist debugging or other indexing. * * @param name the name to call it. * @since 2.8 */ void setName(String name); /** * To assist ThreadLocal usage, LifecycleState can be set. No need to use this for normal usages. * @param lifecycleState the lifecyle state to use. * @since 2.8 */ void setLifecycleState(LifecycleState lifecycleState); /** * Retrieve the name set (if any). * @return Retrieve the arbitrary name of the container set by calling {@link #setName(String) setName}. * @since 2.10.2 */ String getName(); /** * Allow querying of the current lifecycle state of a MutablePicoContainer. * @return the current Lifecycle State. * @since 2.10.2 */ LifecycleState getLifecycleState(); } libpicocontainer-java-2.15/org/picocontainer/NameBinding.java000066400000000000000000000014331242247644300243570ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; public interface NameBinding { String getName(); } libpicocontainer-java-2.15/org/picocontainer/ObjectReference.java000066400000000000000000000025411242247644300252320ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer; /** * A way to refer to objects that are stored in "awkward" places (for example inside a * HttpSession or {@link ThreadLocal}). *

      * This interface is typically implemented by someone integrating Pico into an existing container. * * @author Joe Walnes */ public interface ObjectReference { /** * Retrieve an actual reference to the object. Returns null if the reference is not available * or has not been populated yet. * * @return an actual reference to the object. */ T get(); /** * Assign an object to the reference. * * @param item the object to assign to the reference. May be null. */ void set(T item); } libpicocontainer-java-2.15/org/picocontainer/Parameter.java000066400000000000000000000163231242247644300241300ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Jon Tirsen * *****************************************************************************/ package org.picocontainer; import org.picocontainer.parameters.ComponentParameter; import org.picocontainer.parameters.DefaultConstructorParameter; import java.lang.annotation.Annotation; import java.lang.reflect.Type; /** * This class provides control over the arguments that will be passed to a constructor. It can be used for finer control over * what arguments are passed to a particular constructor. * * @author Jon Tirsén * @author Aslak Hellesøy * @author Thomas Heller * @see MutablePicoContainer#addComponent(Object,Object,Parameter[]) a method on the * {@link MutablePicoContainer} interface which allows passing in of an array of {@linkplain Parameter Parameters}. * @see org.picocontainer.parameters.ComponentParameter an implementation of this interface that allows you to specify the key * used for resolving the parameter. * @see org.picocontainer.parameters.ConstantParameter an implementation of this interface that allows you to specify a constant * that will be used for resolving the parameter. */ public interface Parameter { /** * Zero parameter is used when you wish a component to be instantiated with its default constructor. Ex: *

      *
      	 * 		MutablePicoContainer mpc = new PicoBuilder().build();
      	 * 		mpc.addComponent(Map.class, HashMap.class, Parameter.ZERO);
      	 * 		mpc.addComponent(List.class, ArrayList.class, Parameter.ZERO);
      	 * 	
      *
      *

      By specifying the default constructor in this example code, you allow PicoContainer to recognize * that HashMap(Collection) should not be used and avoid a CircularDependencyException.

      */ Parameter[] ZERO = new Parameter[] {DefaultConstructorParameter.INSTANCE}; Parameter[] DEFAULT = new Parameter[]{ ComponentParameter.DEFAULT }; /** * Check if the Parameter can satisfy the expected type using the container. * * @param container the container from which dependencies are resolved. * @param forAdapter the {@link org.picocontainer.ComponentAdapter} that is asking for the instance * @param injecteeAdapter the adapter to be injected into (null for N/A) * @param expectedType the required type * @param expectedNameBinding Expected parameter name * @param useNames should use parameter names for disambiguation * @param binding @return true if the component parameter can be resolved. * @since 2.8.1 * */ Resolver resolve(PicoContainer container, ComponentAdapter forAdapter, ComponentAdapter injecteeAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding); /** * Verify that the Parameter can satisfy the expected type using the container * * @param container the container from which dependencies are resolved. * @param adapter the {@link ComponentAdapter} that is asking for the verification * @param expectedType the required type * @param expectedNameBinding Expected parameter name * * @param useNames * @param binding * @throws PicoCompositionException if parameter and its dependencies cannot be resolved */ void verify(PicoContainer container, ComponentAdapter adapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding); /** * Accepts a visitor for this Parameter. The method is normally called by visiting a {@link ComponentAdapter}, that * cascades the {@linkplain PicoVisitor visitor} also down to all its {@linkplain Parameter Parameters}. * * @param visitor the visitor. * */ void accept(PicoVisitor visitor); @Deprecated Object resolveInstance(PicoContainer container, ComponentAdapter forAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding); @Deprecated boolean isResolvable(PicoContainer container, ComponentAdapter forAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding); /** * Resolver is used transitarily during resolving of Parameters. * isResolvable() and resolveInstance() in series do not cause resolveAdapter() twice */ public static interface Resolver { /** * @return can the parameter be resolved */ public boolean isResolved(); /** * @return the instance to be used to inject as a parameter */ public Object resolveInstance(); /** * @return the ComponentAdapter for the parameter in question */ public ComponentAdapter getComponentAdapter(); } /** * The Parameter cannot (ever) be resolved */ public static class NotResolved implements Resolver { public boolean isResolved() { return false; } public Object resolveInstance() { return null; } public ComponentAdapter getComponentAdapter() { return null; } } /** * Delegate to another reolver */ public abstract static class DelegateResolver implements Resolver { private final Resolver delegate; public DelegateResolver(Resolver delegate) { this.delegate = delegate; } public boolean isResolved() { return delegate.isResolved(); } public Object resolveInstance() { return delegate.resolveInstance(); } public ComponentAdapter getComponentAdapter() { return delegate.getComponentAdapter(); } } /** * A fixed value wrapped as a Resolver */ public static class ValueResolver implements Resolver { private final boolean resolvable; private final Object value; private final ComponentAdapter adapter; public ValueResolver(boolean resolvable, Object value, ComponentAdapter adapter) { this.resolvable = resolvable; this.value = value; this.adapter = adapter; } public boolean isResolved() { return resolvable; } public Object resolveInstance() { return value; } public ComponentAdapter getComponentAdapter() { return adapter; } } } libpicocontainer-java-2.15/org/picocontainer/PicoBuilder.java000066400000000000000000000323171242247644300244120ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import org.picocontainer.behaviors.Automating; import org.picocontainer.behaviors.Locking; import org.picocontainer.behaviors.PropertyApplying; import org.picocontainer.behaviors.Synchronizing; import org.picocontainer.containers.EmptyPicoContainer; import org.picocontainer.containers.TransientPicoContainer; import org.picocontainer.injectors.CompositeInjection; import org.picocontainer.injectors.MethodInjection; import org.picocontainer.lifecycle.JavaEE5LifecycleStrategy; import org.picocontainer.lifecycle.NullLifecycleStrategy; import org.picocontainer.lifecycle.ReflectionLifecycleStrategy; import org.picocontainer.lifecycle.StartableLifecycleStrategy; import org.picocontainer.monitors.ConsoleComponentMonitor; import org.picocontainer.monitors.NullComponentMonitor; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; import java.util.Stack; import static org.picocontainer.behaviors.Behaviors.caching; import static org.picocontainer.behaviors.Behaviors.implementationHiding; import static org.picocontainer.injectors.Injectors.CDI; import static org.picocontainer.injectors.Injectors.SDI; import static org.picocontainer.injectors.Injectors.adaptiveDI; import static org.picocontainer.injectors.Injectors.annotatedFieldDI; import static org.picocontainer.injectors.Injectors.annotatedMethodDI; import static org.picocontainer.injectors.Injectors.namedField; import static org.picocontainer.injectors.Injectors.namedMethod; import static org.picocontainer.injectors.Injectors.typedFieldDI; /** * Helps assembles the myriad items available to a picocontainer. *

      Simple Example:

      *
       * MutablePicoContainer mpc = new PicoBuilder()
       *   .withCaching()
       *   .withLifecycle()
       *   .build();
       * 
      * @author Paul Hammant */ public class PicoBuilder { private PicoContainer parentContainer; private Class mpcClass = DefaultPicoContainer.class; private ComponentMonitor componentMonitor; private List containerComps = new ArrayList(); private boolean addChildToParent; private LifecycleStrategy lifecycleStrategy; private final Stack behaviors = new Stack(); private final List injectors = new ArrayList(); private Class componentMonitorClass = NullComponentMonitor.class; private Class lifecycleStrategyClass = NullLifecycleStrategy.class; public PicoBuilder(PicoContainer parentContainer, InjectionFactory injectionType) { this(parentContainer); addInjector(injectionType); } /** * Constructs a PicoBuilder using the specified PicoContainer as an argument. Note * that this only creates child -> parent references. You must use parentContainer.addChildContainer() * to the instance built here if you require child <-> parent references. * @param parentContainer */ public PicoBuilder(PicoContainer parentContainer) { if (parentContainer != null) { this.parentContainer = parentContainer; } else { this.parentContainer = new EmptyPicoContainer(); } } public PicoBuilder(InjectionFactory injectionType) { this(new EmptyPicoContainer(), injectionType); } /** * Will be used to build a PicoContainer not bound to any parent container. */ public PicoBuilder() { this(new EmptyPicoContainer()); } public PicoBuilder withLifecycle() { lifecycleStrategyClass = StartableLifecycleStrategy.class; lifecycleStrategy = null; return this; } /** * Constructed PicoContainer will use {@linkplain org.picocontainer.lifecycle.ReflectionLifecycleStrategy ReflectionLifecycle}. * @return this to allow for method chaining. */ public PicoBuilder withReflectionLifecycle() { lifecycleStrategyClass = ReflectionLifecycleStrategy.class; lifecycleStrategy = null; return this; } /** * Allows you to specify your own lifecycle strategy class. * @param specifiedLifecycleStrategyType lifecycle strategy type. * @return this to allow for method chaining. */ public PicoBuilder withLifecycle(Class specifiedLifecycleStrategyType) { this.lifecycleStrategyClass = specifiedLifecycleStrategyType; lifecycleStrategy = null; return this; } /** * Constructed PicoContainer will use {@linkplain org.picocontainer.lifecycle.JavaEE5LifecycleStrategy JavaEE5LifecycleStrategy}. * @return this to allow for method chaining. */ public PicoBuilder withJavaEE5Lifecycle() { this.lifecycleStrategyClass = JavaEE5LifecycleStrategy.class; lifecycleStrategy = null; return this; } /** * Allows you to fully specify your lifecycle strategy by passing in a built instance * @param specifiedLifecycleStrategy * @return this to allow for method chaining. */ public PicoBuilder withLifecycle(LifecycleStrategy specifiedLifecycleStrategy) { this.lifecycleStrategy = specifiedLifecycleStrategy; lifecycleStrategyClass = null; return this; } public PicoBuilder withConsoleMonitor() { componentMonitorClass = ConsoleComponentMonitor.class; return this; } public PicoBuilder withMonitor(Class cmClass) { if (cmClass == null) { throw new NullPointerException("monitor class cannot be null"); } if (!ComponentMonitor.class.isAssignableFrom(cmClass)) { throw new ClassCastException(cmClass.getName() + " is not a " + ComponentMonitor.class.getName()); } componentMonitorClass = cmClass; componentMonitor = null; return this; } public MutablePicoContainer build() { DefaultPicoContainer tempContainer = new TransientPicoContainer(); tempContainer.addComponent(PicoContainer.class, parentContainer); addContainerComponents(tempContainer); ComponentFactory componentFactory; if (injectors.size() == 1) { componentFactory = injectors.get(0); } else if (injectors.size() == 0) { componentFactory = adaptiveDI(); } else { componentFactory = new CompositeInjection(injectors.toArray(new InjectionFactory[injectors.size()])); } Stack clonedBehaviors = (Stack< Object >) behaviors.clone(); while (!clonedBehaviors.empty()) { componentFactory = buildComponentFactory(tempContainer, componentFactory, clonedBehaviors); } tempContainer.addComponent(ComponentFactory.class, componentFactory); buildComponentMonitor(tempContainer); if (lifecycleStrategy == null) { tempContainer.addComponent(LifecycleStrategy.class, lifecycleStrategyClass); } else { tempContainer.addComponent(LifecycleStrategy.class, lifecycleStrategy); } tempContainer.addComponent("mpc", mpcClass); MutablePicoContainer newContainer = (MutablePicoContainer) tempContainer.getComponent("mpc"); addChildToParent(newContainer); return newContainer; } private void buildComponentMonitor(DefaultPicoContainer tempContainer) { if (componentMonitorClass == null) { tempContainer.addComponent(ComponentMonitor.class, componentMonitor); } else { tempContainer.addComponent(ComponentMonitor.class, componentMonitorClass); } } private void addChildToParent(MutablePicoContainer newContainer) { if (addChildToParent) { if (parentContainer instanceof MutablePicoContainer) { ((MutablePicoContainer)parentContainer).addChildContainer(newContainer); } else { throw new PicoCompositionException("If using addChildContainer() the parent must be a MutablePicoContainer"); } } } private void addContainerComponents(DefaultPicoContainer temp) { for (Object containerComp : containerComps) { temp.addComponent(containerComp); } } private ComponentFactory buildComponentFactory(DefaultPicoContainer container, final ComponentFactory lastCaf, final Stack clonedBehaviors) { Object componentFactory = clonedBehaviors.pop(); DefaultPicoContainer tmpContainer = new TransientPicoContainer(container); tmpContainer.addComponent("componentFactory", componentFactory); if (lastCaf != null) { tmpContainer.addComponent(ComponentFactory.class, lastCaf); } ComponentFactory newlastCaf = (ComponentFactory) tmpContainer.getComponent("componentFactory"); if (newlastCaf instanceof BehaviorFactory) { ((BehaviorFactory) newlastCaf).wrap(lastCaf); } return newlastCaf; } public PicoBuilder withHiddenImplementations() { behaviors.push(implementationHiding()); return this; } public PicoBuilder withSetterInjection() { addInjector(SDI()); return this; } public PicoBuilder withAnnotatedMethodInjection(Class injectionAnnotation) { addInjector(annotatedMethodDI(injectionAnnotation)); return this; } public PicoBuilder withAnnotatedMethodInjection() { addInjector(annotatedMethodDI()); return this; } public PicoBuilder withAnnotatedFieldInjection(Class injectionAnnotation) { addInjector(annotatedFieldDI(injectionAnnotation)); return this; } public PicoBuilder withAnnotatedFieldInjection() { addInjector(annotatedFieldDI()); return this; } public PicoBuilder withTypedFieldInjection() { addInjector(typedFieldDI()); return this; } public PicoBuilder withConstructorInjection() { addInjector(CDI()); return this; } public PicoBuilder withNamedMethodInjection() { addInjector(namedMethod()); return this; } public PicoBuilder withNamedFieldInjection() { addInjector(namedField()); return this; } public PicoBuilder withCaching() { behaviors.push(caching()); return this; } public PicoBuilder withComponentFactory(ComponentFactory componentFactory) { if (componentFactory == null) { throw new NullPointerException("CAF cannot be null"); } behaviors.push(componentFactory); return this; } public PicoBuilder withSynchronizing() { behaviors.push(new Synchronizing()); return this; } public PicoBuilder withLocking() { behaviors.push(new Locking()); return this; } public PicoBuilder withBehaviors(BehaviorFactory... factories) { for (BehaviorFactory componentFactory : factories) { behaviors.push(componentFactory); } return this; } public PicoBuilder implementedBy(Class containerClass) { mpcClass = containerClass; return this; } /** * Allows you to specify your very own component monitor to be used by the created * picocontainer * @param specifiedComponentMonitor * @return this to allow for method chaining. */ public PicoBuilder withMonitor(ComponentMonitor specifiedComponentMonitor) { this.componentMonitor = specifiedComponentMonitor; componentMonitorClass = null; return this; } public PicoBuilder withComponentFactory(Class componentFactoryClass) { behaviors.push(componentFactoryClass); return this; } public PicoBuilder withCustomContainerComponent(Object containerDependency) { containerComps.add(containerDependency); return this; } public PicoBuilder withPropertyApplier() { behaviors.push(new PropertyApplying()); return this; } public PicoBuilder withAutomatic() { behaviors.push(new Automating()); return this; } public PicoBuilder withMethodInjection() { addInjector(new MethodInjection()); return this; } public PicoBuilder addChildToParent() { addChildToParent = true; return this; } protected void addInjector(InjectionFactory injectionType) { injectors.add(injectionType); } } libpicocontainer-java-2.15/org/picocontainer/PicoClassNotFoundException.java000066400000000000000000000017521242247644300274240ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; @SuppressWarnings("serial") public class PicoClassNotFoundException extends PicoException { public PicoClassNotFoundException(final String className, final ClassNotFoundException cnfe) { super("Class '" + className + "' not found", cnfe); } } libpicocontainer-java-2.15/org/picocontainer/PicoCompositionException.java000066400000000000000000000037551242247644300272120ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer; /** * Subclass of {@link PicoException} that is thrown when there is: * - a problem initializing the container * - a cyclic dependency between components occurs. * - problem adding a component * - a request for a component that is ambiguous. * */ @SuppressWarnings("serial") public class PicoCompositionException extends PicoException { /** * Construct a new exception with no cause and the specified detail message. Note modern JVMs may still track the * exception that caused this one. * * @param message the message detailing the exception. */ public PicoCompositionException(final String message) { super(message); } /** * Construct a new exception with the specified cause and no detail message. * * @param cause the exception that caused this one. */ public PicoCompositionException(final Throwable cause) { super(cause); } /** * Construct a new exception with the specified cause and the specified detail message. * * @param message the message detailing the exception. * @param cause the exception that caused this one. */ public PicoCompositionException(final String message, final Throwable cause) { super(message, cause); } } libpicocontainer-java-2.15/org/picocontainer/PicoContainer.java000066400000000000000000000164121242247644300247440ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import java.util.Collection; import java.util.List; import java.lang.annotation.Annotation; import java.lang.reflect.Type; /** * This is the core interface for PicoContainer. It is used to retrieve component instances from the container; it only * has accessor methods (in addition to the {@link #accept(PicoVisitor)} method). In order to register components in a * PicoContainer, use a {@link MutablePicoContainer}, such as {@link DefaultPicoContainer}. * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén * @see See package description for basic overview how to use * PicoContainer. */ public interface PicoContainer { /** * Retrieve a component instance registered with a specific key or type. If a component cannot be found in this container, * the parent container (if one exists) will be searched. * * @param componentKeyOrType the key or Type that the component was registered with. * @return an instantiated component, or null if no component has been registered for the specified * key. */ Object getComponent(Object componentKeyOrType); Object getComponent(Object componentKeyOrType, Type into); /** * Retrieve a component keyed by the component type. * @param componentType the type of the component * @return the typed resulting object instance or null if the object does not exist. */ T getComponent(Class componentType); /** * Retrieve a component keyed by the component type and binding type. * @param componentType the type of the component * @param binding the binding type of the component * @return the typed resulting object instance or null if the object does not exist. */ T getComponent(Class componentType, Class binding); /** * Retrieve all the registered component instances in the container, (not including those in the parent container). * The components are returned in their order of instantiation, which depends on the dependency order between them. * * @return all the components. * @throws PicoException if the instantiation of the component fails */ List getComponents(); /** * Retrieve the parent container of this container. * * @return a {@link PicoContainer} instance, or null if this container does not have a parent. */ PicoContainer getParent(); /** * Find a component adapter associated with the specified key. If a component adapter cannot be found in this * container, the parent container (if one exists) will be searched. * * @param componentKey the key that the component was registered with. * @return the component adapter associated with this key, or null if no component has been * registered for the specified key. */ ComponentAdapter getComponentAdapter(Object componentKey); /** * Find a component adapter associated with the specified type and binding name. If a component adapter cannot be found in this * container, the parent container (if one exists) will be searched. * * @param componentType the type of the component. * @return the component adapter associated with this class, or null if no component has been * registered for the specified key. * @param componentNameBinding the name binding to use */ ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding); /** * Find a component adapter associated with the specified type and binding type. If a component adapter cannot be found in this * container, the parent container (if one exists) will be searched. * * @param componentType the type of the component. * @return the component adapter associated with this class, or null if no component has been * registered for the specified key. * @param binding the typed binding to use */ ComponentAdapter getComponentAdapter(Class componentType, Class binding); /** * Retrieve all the component adapters inside this container. The component adapters from the parent container are * not returned. * * @return a collection containing all the {@link ComponentAdapter}s inside this container. The collection will not * be modifiable. * @see #getComponentAdapters(Class) a variant of this method which returns the component adapters inside this * container that are associated with the specified type. */ Collection> getComponentAdapters(); /** * Retrieve all component adapters inside this container that are associated with the specified type. The addComponent * adapters from the parent container are not returned. * * @param componentType the type of the components. * @return a collection containing all the {@link ComponentAdapter}s inside this container that are associated with * the specified type. Changes to this collection will not be reflected in the container itself. */ List> getComponentAdapters(Class componentType); /** * Retrieve all component adapters inside this container that are associated with the specified type and binding type. The addComponent * adapters from the parent container are not returned. * * @param componentType the type of the components. * @param binding the typed binding to use * @return a collection containing all the {@link ComponentAdapter}s inside this container that are associated with * the specified type. Changes to this collection will not be reflected in the container itself. */ List> getComponentAdapters(Class componentType, Class binding); /** * Returns a List of components of a certain componentType. The list is ordered by instantiation order, starting * with the components instantiated first at the beginning. * * @param componentType the searched type. * @return a List of components. * @throws PicoException if the instantiation of a component fails */ List getComponents(Class componentType); /** * Accepts a visitor that should visit the child containers, component adapters and component instances. * * @param visitor the visitor */ void accept(PicoVisitor visitor); } libpicocontainer-java-2.15/org/picocontainer/PicoException.java000066400000000000000000000044021242247644300247540ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; /** * Superclass for all Exceptions in PicoContainer. You can use this if you want to catch all exceptions thrown by * PicoContainer. Be aware that some parts of the PicoContainer API will also throw {@link NullPointerException} when * null values are provided for method arguments, and this is not allowed. * * @author Paul Hammant * @author Aslak Hellesøy */ public abstract class PicoException extends RuntimeException { /** * Construct a new exception with no cause and no detail message. Note modern JVMs may still track the exception * that caused this one. */ protected PicoException() { } /** * Construct a new exception with no cause and the specified detail message. Note modern JVMs may still track the * exception that caused this one. * * @param message the message detailing the exception. */ protected PicoException(final String message) { super(message); } /** * Construct a new exception with the specified cause and no detail message. * * @param cause the exception that caused this one. */ protected PicoException(final Throwable cause) { super(cause); } /** * Construct a new exception with the specified cause and the specified detail message. * * @param message the message detailing the exception. * @param cause the exception that caused this one. */ protected PicoException(final String message, final Throwable cause) { super(message,cause); } } libpicocontainer-java-2.15/org/picocontainer/PicoLifecycleException.java000066400000000000000000000024701242247644300265770ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer; import java.lang.reflect.Method; @SuppressWarnings("serial") public class PicoLifecycleException extends PicoException { private final Method method; private final Object instance; public PicoLifecycleException(final Method method, final Object instance, final Throwable cause) { super(cause); this.method = method; this.instance = instance; } public Method getMethod() { return method; } public Object getInstance() { return instance; } public String getMessage() { return "PicoLifecycleException: method '" + method + "', instance '"+ instance + ", " + super.getMessage(); } } libpicocontainer-java-2.15/org/picocontainer/PicoVerificationException.java000066400000000000000000000046221242247644300273230ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer; import java.util.ArrayList; import java.util.List; /** * Subclass of {@link PicoException} that is thrown when a {@link PicoContainer} hierarchy * cannot be verified. A failing verification is caused by ambuigities or missing dependencies * between the registered components and their parameters. This exception is designed as a * collector for all Exceptions occurring at the verification of the complete container * hierarchy. The verification is normally done with the * {@link org.picocontainer.visitors.VerifyingVisitor}, that will throw this exception. */ @SuppressWarnings("serial") public class PicoVerificationException extends PicoException { /** * The exceptions that caused this one. */ private final List nestedExceptions = new ArrayList(); /** * Construct a new exception with a list of exceptions that caused this one. * * @param nestedExceptions the exceptions that caused this one. */ public PicoVerificationException(final List nestedExceptions) { this.nestedExceptions.addAll(nestedExceptions); } /** * Retrieve the list of exceptions that caused this one. * * @return the list of exceptions that caused this one. */ public List getNestedExceptions() { return nestedExceptions; } /** * Return a string listing of all the messages associated with the exceptions that caused * this one. * * @return a string listing of all the messages associated with the exceptions that caused * this one. */ public String getMessage() { return nestedExceptions.toString(); } } libpicocontainer-java-2.15/org/picocontainer/PicoVisitor.java000066400000000000000000000052311242247644300244560ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer; /** * Interface realizing a visitor pattern for {@link PicoContainer} as described in the GoF. * The visitor should visit the container, its children, all registered {@link ComponentAdapter} * instances and all instantiated components. * * @author Aslak Hellesøy * @author Jörg Schaible */ public interface PicoVisitor { /** * Constant that indicates that the traversal should continue after the * visit*() method has been called. */ boolean CONTINUE_TRAVERSAL = true; /** * Constant that indicates that the traversal should abort after the * visit*() method has been called. */ boolean ABORT_TRAVERSAL = false; /** * Entry point for the PicoVisitor traversal. The given node is the first object, that is * asked for acceptance. Only objects of type {@link PicoContainer}, {@link ComponentAdapter}, * or {@link Parameter} are valid. * * @param node the start node of the traversal. * @return a visitor-specific value. * @throws IllegalArgumentException in case of an argument of invalid type. */ Object traverse(Object node); /** * Visit a {@link PicoContainer} that has to accept the visitor. * * @param pico the visited container. * @return CONTINUE_TRAVERSAL if the traversal should continue. * Any visitor callback that returns ABORT_TRAVERSAL indicates * the desire to abort any further traversal. */ boolean visitContainer(PicoContainer pico); /** * Visit a {@link ComponentAdapter} that has to accept the visitor. * * @param componentAdapter the visited ComponentAdapter. */ void visitComponentAdapter(ComponentAdapter componentAdapter); /** * Visit a {@link ComponentAdapter} that has to accept the visitor. * * @param componentAdapter the visited ComponentAdapter. */ void visitComponentFactory(ComponentFactory componentFactory); /** * Visit a {@link Parameter} that has to accept the visitor. * * @param parameter the visited Parameter. */ void visitParameter(Parameter parameter); } libpicocontainer-java-2.15/org/picocontainer/Startable.java000066400000000000000000000037671242247644300241410ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the license.html file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer; /** *

      An interface which is implemented by components that can be started and stopped. The {@link Startable#start()} * must be called at the begin of the component lifecycle. It can be called again only after a call to * {@link Startable#stop()}. The {@link Startable#stop()} method must be called at the end of the component lifecycle, * and can further be called after every {@link Startable#start()}. If a component implements the {@link Disposable} * interface as well, {@link Startable#stop()} should be called before {@link Disposable#dispose()}.

      *

      *

      For more advanced and pluggable lifecycle support, see the functionality offered by picocontainer-gems * subproject.

      * @see org.picocontainer.Disposable the Disposable interface if you need to dispose() semantics. * @author Paul Hammant * @author Aslak Hellesøy */ public interface Startable { /** * Start this component. Called initially at the begin of the lifecycle. It can be called again after a stop. */ void start(); /** * Stop this component. Called near the end of the lifecycle. It can be called again after a further start. Implement * {@link Disposable} if you need a single call at the definite end of the lifecycle. */ void stop(); } libpicocontainer-java-2.15/org/picocontainer/adapters/000077500000000000000000000000001242247644300231435ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/adapters/AbstractAdapter.java000066400000000000000000000132371242247644300270600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.adapters; import org.picocontainer.ComponentMonitor; import org.picocontainer.PicoVisitor; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitorStrategy; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import org.picocontainer.injectors.ProviderAdapter; import org.picocontainer.injectors.Provider; import org.picocontainer.monitors.AbstractComponentMonitor; import org.picocontainer.monitors.NullComponentMonitor; import java.io.Serializable; /** * Base class for a ComponentAdapter with general functionality. * This implementation provides basic checks for a healthy implementation of a ComponentAdapter. * It does not allow to use null for the component key or the implementation, * ensures that the implementation is a concrete class and that the key is assignable from the * implementation if the key represents a type. * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén */ public abstract class AbstractAdapter implements ComponentAdapter, ComponentMonitorStrategy, Serializable { private Object componentKey; private Class componentImplementation; private ComponentMonitor componentMonitor; /** * Constructs a new ComponentAdapter for the given key and implementation. * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation */ public AbstractAdapter(Object componentKey, Class componentImplementation) { this(componentKey, componentImplementation, new AbstractComponentMonitor()); this.componentMonitor = new NullComponentMonitor(); } /** * Constructs a new ComponentAdapter for the given key and implementation. * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param monitor the component monitor used by this ComponentAdapter */ public AbstractAdapter(Object componentKey, Class componentImplementation, ComponentMonitor monitor) { if (monitor == null) { throw new NullPointerException("ComponentMonitor==null"); } this.componentMonitor = monitor; if (componentImplementation == null) { throw new NullPointerException("componentImplementation"); } this.componentKey = componentKey; this.componentImplementation = componentImplementation; checkTypeCompatibility(); } /** * {@inheritDoc} * @see org.picocontainer.ComponentAdapter#getComponentKey() */ public Object getComponentKey() { if (componentKey == null) { throw new NullPointerException("componentKey"); } return componentKey; } /** * {@inheritDoc} * @see org.picocontainer.ComponentAdapter#getComponentImplementation() */ public Class getComponentImplementation() { return componentImplementation; } protected void checkTypeCompatibility() { if (componentKey instanceof Class) { Class componentType = (Class) componentKey; if (Provider.class.isAssignableFrom(componentImplementation)) { if (!componentType.isAssignableFrom(ProviderAdapter.getProvideMethod(componentImplementation).getReturnType())) { throw newCCE(componentType); } } else { if (!componentType.isAssignableFrom(componentImplementation)) { throw newCCE(componentType); } } } } private ClassCastException newCCE(Class componentType) { return new ClassCastException(componentImplementation.getName() + " is not a " + componentType.getName()); } public T getComponentInstance(PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, null); } /** * @return Returns the ComponentAdapter's class name and the component's key. * @see java.lang.Object#toString() */ public String toString() { return getDescriptor() + getComponentKey(); } public void accept(PicoVisitor visitor) { visitor.visitComponentAdapter(this); } public void changeMonitor(ComponentMonitor monitor) { this.componentMonitor = monitor; } /** * Returns the monitor currently used * @return The ComponentMonitor currently used */ public ComponentMonitor currentMonitor(){ return componentMonitor; } public final ComponentAdapter getDelegate() { return null; } public final U findAdapterOfType(Class adapterType) { if (adapterType.isAssignableFrom(this.getClass())) { return (U) this; } else if (getDelegate() != null) { return getDelegate().findAdapterOfType(adapterType); } return null; } } libpicocontainer-java-2.15/org/picocontainer/adapters/InstanceAdapter.java000066400000000000000000000114141242247644300270540ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.adapters; import org.picocontainer.Behavior; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentLifecycle; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.lifecycle.NullLifecycleStrategy; import org.picocontainer.monitors.NullComponentMonitor; import java.lang.reflect.Type; /** *

      * Component adapter which wraps a component instance. *

      *

      * This component adapter supports both a {@link Behavior Behavior} and a * {@link org.picocontainer.LifecycleStrategy LifecycleStrategy} to control the lifecycle of the component. * The lifecycle manager methods simply delegate to the lifecycle strategy methods * on the component instance. *

      * * @author Aslak Hellesøy * @author Paul Hammant * @author Mauro Talevi */ @SuppressWarnings("serial") public final class InstanceAdapter extends AbstractAdapter implements ComponentLifecycle, LifecycleStrategy { /** * The actual instance of the component. */ private final T componentInstance; /** * Lifecycle Strategy for the component adpater. */ private final LifecycleStrategy lifecycleStrategy; private boolean started; public InstanceAdapter(Object componentKey, T componentInstance, LifecycleStrategy lifecycleStrategy, ComponentMonitor componentMonitor) throws PicoCompositionException { super(componentKey, getInstanceClass(componentInstance), componentMonitor); this.componentInstance = componentInstance; this.lifecycleStrategy = lifecycleStrategy; } public InstanceAdapter(Object componentKey, T componentInstance) { this(componentKey, componentInstance, new NullLifecycleStrategy(), new NullComponentMonitor()); } public InstanceAdapter(Object componentKey, T componentInstance, LifecycleStrategy lifecycleStrategy) { this(componentKey, componentInstance, lifecycleStrategy, new NullComponentMonitor()); } public InstanceAdapter(Object componentKey, T componentInstance, ComponentMonitor componentMonitor) { this(componentKey, componentInstance, new NullLifecycleStrategy(), componentMonitor); } private static Class getInstanceClass(Object componentInstance) { if (componentInstance == null) { throw new NullPointerException("componentInstance cannot be null"); } return componentInstance.getClass(); } public T getComponentInstance(PicoContainer container, Type into) { return componentInstance; } public void verify(PicoContainer container) { } public String getDescriptor() { return "Instance-"; } @Override public String toString() { Object componentKey = getComponentKey(); if (componentKey instanceof Class) { componentKey = "of " + ((Class) componentKey).getName(); } return getDescriptor() + componentKey; } public void start(PicoContainer container) { start(componentInstance); } public void stop(PicoContainer container) { stop(componentInstance); } public void dispose(PicoContainer container) { dispose(componentInstance); } public boolean componentHasLifecycle() { return hasLifecycle(componentInstance.getClass()); } public boolean isStarted() { return started; } // ~~~~~~~~ LifecycleStrategy ~~~~~~~~ public void start(Object component) { lifecycleStrategy.start(componentInstance); started = true; } public void stop(Object component) { lifecycleStrategy.stop(componentInstance); started = false; } public void dispose(Object component) { lifecycleStrategy.dispose(componentInstance); } public boolean hasLifecycle(Class type) { return lifecycleStrategy.hasLifecycle(type); } public boolean isLazy(ComponentAdapter adapter) { return lifecycleStrategy.isLazy(adapter); } } libpicocontainer-java-2.15/org/picocontainer/annotations/000077500000000000000000000000001242247644300236755ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/annotations/Bind.java000066400000000000000000000005161242247644300254160ustar00rootroot00000000000000package org.picocontainer.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.ElementType; /** @author Paul Hammant */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.ANNOTATION_TYPE }) public @interface Bind { } libpicocontainer-java-2.15/org/picocontainer/annotations/Cache.java000066400000000000000000000017661242247644300255550ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.ElementType; @Retention(RetentionPolicy.RUNTIME) @Target(value={ ElementType.TYPE }) public @interface Cache { } libpicocontainer-java-2.15/org/picocontainer/annotations/Inject.java000066400000000000000000000020671242247644300257610ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.annotations; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Target(value={ElementType.METHOD, ElementType.FIELD}) public @interface Inject { //Marker annotation only, no attributes. } libpicocontainer-java-2.15/org/picocontainer/annotations/Nullable.java000066400000000000000000000017731242247644300263060ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.annotations; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Target(value={ElementType.PARAMETER}) public @interface Nullable { }libpicocontainer-java-2.15/org/picocontainer/behaviors/000077500000000000000000000000001242247644300233225ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/behaviors/AbstractBehavior.java000066400000000000000000000155561242247644300274240ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Jon Tirsen * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.ComponentMonitorStrategy; import org.picocontainer.LifecycleStrategy; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import java.io.Serializable; import java.lang.reflect.Type; /** *

      * Component adapter which decorates another adapter. *

      *

      * This adapter supports a {@link org.picocontainer.ComponentMonitorStrategy component monitor strategy} * and will propagate change of monitor to the delegate if the delegate itself * support the monitor strategy. *

      *

      * This adapter also supports a {@link Behavior lifecycle manager} and a * {@link org.picocontainer.LifecycleStrategy lifecycle strategy} if the delegate does. *

      * * @author Jon Tirsen * @author Aslak Hellesoy * @author Mauro Talevi */ public abstract class AbstractBehavior implements org.picocontainer.Behavior, ComponentMonitorStrategy, LifecycleStrategy, Serializable { protected final ComponentAdapter delegate; public AbstractBehavior(ComponentAdapter delegate) { this.delegate = delegate; } public Object getComponentKey() { return delegate.getComponentKey(); } public Class getComponentImplementation() { return delegate.getComponentImplementation(); } public T getComponentInstance(PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, NOTHING.class); } public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return (T) delegate.getComponentInstance(container, into); } public void verify(PicoContainer container) throws PicoCompositionException { delegate.verify(container); } public final ComponentAdapter getDelegate() { return delegate; } @SuppressWarnings("unchecked") public final U findAdapterOfType(Class adapterType) { if (adapterType.isAssignableFrom(this.getClass())) { return (U) this; } else { return delegate.findAdapterOfType(adapterType); } } public void accept(PicoVisitor visitor) { visitor.visitComponentAdapter(this); delegate.accept(visitor); } /** * Delegates change of monitor if the delegate supports * a component monitor strategy. * {@inheritDoc} */ public void changeMonitor(ComponentMonitor monitor) { if (delegate instanceof ComponentMonitorStrategy ) { ((ComponentMonitorStrategy)delegate).changeMonitor(monitor); } } /** * Returns delegate's current monitor if the delegate supports * a component monitor strategy. * {@inheritDoc} * @throws PicoCompositionException if no component monitor is found in delegate */ public ComponentMonitor currentMonitor() { if (delegate instanceof ComponentMonitorStrategy ) { return ((ComponentMonitorStrategy)delegate).currentMonitor(); } throw new PicoCompositionException("No component monitor found in delegate"); } /** * Invokes delegate start method if the delegate is a Behavior * {@inheritDoc} */ public void start(PicoContainer container) { if (delegate instanceof org.picocontainer.Behavior) { ((org.picocontainer.Behavior)delegate).start(container); } } /** * Invokes delegate stop method if the delegate is a Behavior * {@inheritDoc} */ public void stop(PicoContainer container) { if (delegate instanceof org.picocontainer.Behavior) { ((org.picocontainer.Behavior)delegate).stop(container); } } /** * Invokes delegate dispose method if the delegate is a Behavior * {@inheritDoc} */ public void dispose(PicoContainer container) { if (delegate instanceof org.picocontainer.Behavior) { ((org.picocontainer.Behavior)delegate).dispose(container); } } /** * Invokes delegate hasLifecycle method if the delegate is a Behavior * {@inheritDoc} */ public boolean componentHasLifecycle() { if (delegate instanceof org.picocontainer.Behavior) { return ((org.picocontainer.Behavior)delegate).componentHasLifecycle(); } return false; } public boolean isStarted() { if (delegate instanceof org.picocontainer.Behavior) { return ((org.picocontainer.Behavior)delegate).isStarted(); } return false; } // ~~~~~~~~ LifecycleStrategy ~~~~~~~~ /** * Invokes delegate start method if the delegate is a LifecycleStrategy * {@inheritDoc} */ public void start(Object component) { if (delegate instanceof LifecycleStrategy ) { ((LifecycleStrategy)delegate).start(component); } } /** * Invokes delegate stop method if the delegate is a LifecycleStrategy * {@inheritDoc} */ public void stop(Object component) { if (delegate instanceof LifecycleStrategy ) { ((LifecycleStrategy)delegate).stop(component); } } /** * Invokes delegate dispose method if the delegate is a LifecycleStrategy * {@inheritDoc} */ public void dispose(Object component) { if (delegate instanceof LifecycleStrategy ) { ((LifecycleStrategy)delegate).dispose(component); } } /** * Invokes delegate hasLifecycle(Class) method if the delegate is a LifecycleStrategy * {@inheritDoc} */ public boolean hasLifecycle(Class type) { return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).hasLifecycle(type); } public boolean isLazy(ComponentAdapter adapter) { return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).isLazy(adapter); } public String toString() { return getDescriptor() + ":" + delegate.toString(); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/AbstractBehaviorFactory.java000066400000000000000000000113741242247644300307460ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * style * license a copy of which has been included with this distribution in * the * LICENSE.txt file. * * Original code by * ******************************************************************************/ package org.picocontainer.behaviors; import java.io.Serializable; import java.util.Enumeration; import java.util.Properties; import org.picocontainer.BehaviorFactory; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentFactory; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.Characteristics; import org.picocontainer.InjectionFactory; import org.picocontainer.injectors.AdaptingInjection; @SuppressWarnings("serial") public class AbstractBehaviorFactory implements ComponentFactory, Serializable, BehaviorFactory { private ComponentFactory delegate; public ComponentFactory wrap(ComponentFactory delegate) { this.delegate = delegate; return this; } public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { if (delegate == null) { delegate = new AdaptingInjection(); } ComponentAdapter compAdapter = delegate.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); boolean enableCircular = removePropertiesIfPresent(componentProperties, Characteristics.ENABLE_CIRCULAR); if (enableCircular && delegate instanceof InjectionFactory) { return componentMonitor.newBehavior(new HiddenImplementation(compAdapter)); } else { return compAdapter; } } public void verify(PicoContainer container) { delegate.verify(container); } public void accept(PicoVisitor visitor) { visitor.visitComponentFactory(this); if (delegate != null) { delegate.accept(visitor); } } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (delegate != null && delegate instanceof BehaviorFactory) { return ((BehaviorFactory) delegate).addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } return adapter; } public static boolean arePropertiesPresent(Properties current, Properties present, boolean compareValueToo) { Enumeration keys = present.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String presentValue = present.getProperty(key); String currentValue = current.getProperty(key); if (currentValue == null) { return false; } if (!presentValue.equals(currentValue) && compareValueToo) { return false; } } return true; } public static boolean removePropertiesIfPresent(Properties current, Properties present) { if (!arePropertiesPresent(current, present, true)) { return false; } Enumeration keys = present.keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); current.remove(key); } return true; } public static String getAndRemovePropertiesIfPresentByKey(Properties current, Properties present) { if (!arePropertiesPresent(current, present, false)) { return null; } Enumeration keys = present.keys(); String value = null; while (keys.hasMoreElements()) { Object key = keys.nextElement(); value = (String) current.remove(key); } return value; } protected void mergeProperties(Properties into, Properties from) { Enumeration e = from.propertyNames(); while (e.hasMoreElements()) { String s = (String) e.nextElement(); into.setProperty(s, from.getProperty(s)); } } } libpicocontainer-java-2.15/org/picocontainer/behaviors/AdaptingBehavior.java000066400000000000000000000163361242247644300274050ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.picocontainer.BehaviorFactory; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentFactory; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.annotations.Cache; import org.picocontainer.injectors.AdaptingInjection; @SuppressWarnings("serial") public class AdaptingBehavior implements BehaviorFactory, Serializable { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { List list = new ArrayList(); ComponentFactory lastFactory = makeInjectionFactory(); processSynchronizing(componentProperties, list); processLocking(componentProperties, list); processPropertyApplying(componentProperties, list); processAutomatic(componentProperties, list); processImplementationHiding(componentProperties, list); processCaching(componentProperties, componentImplementation, list); processGuarding(componentProperties, componentImplementation, list); //Instantiate Chain of ComponentFactories for (ComponentFactory componentFactory : list) { if (lastFactory != null && componentFactory instanceof BehaviorFactory) { ((BehaviorFactory)componentFactory).wrap(lastFactory); } lastFactory = componentFactory; } return lastFactory.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { List list = new ArrayList(); processSynchronizing(componentProperties, list); processImplementationHiding(componentProperties, list); processCaching(componentProperties, adapter.getComponentImplementation(), list); processGuarding(componentProperties, adapter.getComponentImplementation(), list); //Instantiate Chain of ComponentFactories BehaviorFactory lastFactory = null; for (BehaviorFactory componentFactory : list) { if (lastFactory != null) { componentFactory.wrap(lastFactory); } lastFactory = componentFactory; } if (lastFactory == null) { return adapter; } return lastFactory.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } public void verify(PicoContainer container) { } public void accept(PicoVisitor visitor) { visitor.visitComponentFactory(this); } protected AdaptingInjection makeInjectionFactory() { return new AdaptingInjection(); } protected void processSynchronizing(Properties componentProperties, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE)) { list.add(new Synchronizing()); } } protected void processLocking(Properties componentProperties, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.LOCK)) { list.add(new Locking()); } } protected void processCaching(Properties componentProperties, Class componentImplementation, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE) || componentImplementation.getAnnotation(Cache.class) != null) { list.add(new Caching()); } AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE); } protected void processGuarding(Properties componentProperties, Class componentImplementation, List list) { if (AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.GUARD, false)) { list.add(new Guarding()); } } protected void processImplementationHiding(Properties componentProperties, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL)) { list.add(new ImplementationHiding()); } AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL); } protected void processPropertyApplying(Properties componentProperties, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING)) { list.add(new PropertyApplying()); } } protected void processAutomatic(Properties componentProperties, List list) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC)) { list.add(new Automating()); } } public ComponentFactory wrap(ComponentFactory delegate) { throw new UnsupportedOperationException(); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Automated.java000066400000000000000000000022741242247644300261150ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.Behavior; import org.picocontainer.ComponentAdapter; import java.io.Serializable; @SuppressWarnings("serial") public class Automated extends AbstractBehavior implements Behavior, Serializable { public Automated(ComponentAdapter delegate) { super(delegate); } public boolean hasLifecycle(Class type) { return true; } public String getDescriptor() { return "Automated"; } }libpicocontainer-java-2.15/org/picocontainer/behaviors/Automating.java000066400000000000000000000055271242247644300263060ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import java.io.Serializable; import java.util.Properties; @SuppressWarnings("serial") public class Automating extends AbstractBehaviorFactory implements Serializable { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC); return componentMonitor.newBehavior(new Automated(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC); return componentMonitor.newBehavior(new Automated(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Behavior.java000066400000000000000000000013651242247644300257310ustar00rootroot00000000000000package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ObjectReference; /** * static collection of factory methods for easier behavior creation * * @author Konstantin Pribluda */ public class Behavior { public static final org.picocontainer.Behavior cached(ComponentAdapter delegate) { return new Cached(delegate); } public static final org.picocontainer.Behavior cached(ComponentAdapter delegate, ObjectReference instanceReference) { return new Cached(delegate,instanceReference); } public static final org.picocontainer.Behavior decorated(ComponentAdapter delegate, Decorated.Decorator decorator) { return new Decorated(delegate,decorator); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Behaviors.java000066400000000000000000000031331242247644300261070ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.BehaviorFactory; /** * Static collection of factory methods for different BehaviourFactory implementations. * * @author Paul Hammant * @author Mauro Talevi */ public class Behaviors { /** * Prevents instantiation */ private Behaviors(){ // no-op } public static BehaviorFactory implementationHiding() { return new ImplementationHiding(); } public static BehaviorFactory caching() { return new Caching(); } public static BehaviorFactory synchronizing() { return new Synchronizing(); } public static BehaviorFactory locking() { return new Locking(); } public static BehaviorFactory propertyApplying() { return new PropertyApplying(); } public static BehaviorFactory automatic() { return new Automating(); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Cached.java000066400000000000000000000036751242247644300253470ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.Behavior; import org.picocontainer.ComponentAdapter; import org.picocontainer.ObjectReference; import org.picocontainer.references.SimpleReference; /** *

      * {@link ComponentAdapter} implementation that caches the component instance. *

      *

      * This adapter supports components with a lifecycle, as it is a * {@link Behavior lifecycle manager} which will apply the delegate's * {@link org.picocontainer.LifecycleStrategy lifecycle strategy} to the cached * component instance. The lifecycle state is maintained so that the component * instance behaves in the expected way: it can't be started if already started, * it can't be started or stopped if disposed, it can't be stopped if not * started, it can't be disposed if already disposed. *

      * * @author Mauro Talevi */ @SuppressWarnings("serial") public class Cached extends Stored { public Cached(ComponentAdapter delegate) { this(delegate, new SimpleReference>()); } public Cached(ComponentAdapter delegate, ObjectReference> instanceReference) { super(delegate, instanceReference); } public String getDescriptor() { return "Cached" + getLifecycleDescriptor(); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Caching.java000066400000000000000000000057461242247644300255350ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.ComponentMonitor; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.references.SimpleReference; import org.picocontainer.LifecycleStrategy; import java.util.Properties; /** * factory class creating cached behaviours * @author Aslak Hellesøy * @author rafal@caltha.pl * @author Konstantin Pribluda */ @SuppressWarnings("serial") public class Caching extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); return componentMonitor.newBehavior(new Cached(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters), new SimpleReference>())); } public ComponentAdapter addComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); ComponentAdapter delegate = super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); return componentMonitor.newBehavior(componentMonitor.newBehavior(new Cached(delegate, new SimpleReference>()))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Decorated.java000066400000000000000000000030431242247644300260570ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehavior; import java.lang.reflect.Type; @SuppressWarnings("serial") public class Decorated extends AbstractBehavior { private final Decorator decorator; public Decorated(ComponentAdapter delegate, Decorator decorator) { super(delegate); this.decorator = decorator; } public T getComponentInstance(final PicoContainer container, Type into) throws PicoCompositionException { T instance = super.getComponentInstance(container, into); decorator.decorate(instance); return instance; } public String getDescriptor() { return "FieldDecorated"; } interface Decorator { void decorate(Object instance); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Decorating.java000066400000000000000000000045471242247644300262560ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) NanoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Joerg Schaibe * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.Decorated; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * BehaviorFactory for Decorating. This factory will create {@link org.picocontainer.gems.behaviors.Decorated} that will * allow you to decorate what you like on the component instance that has been created * * @author Paul Hammant */ public abstract class Decorating extends AbstractBehaviorFactory implements Decorated.Decorator { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final Object componentKey, final Class componentImplementation, final Parameter... parameters) throws PicoCompositionException { return componentMonitor.newBehavior(new Decorated(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties,componentKey, componentImplementation, parameters), this)); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/FieldDecorated.java000066400000000000000000000027041242247644300270260ustar00rootroot00000000000000package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import java.lang.reflect.Field; import java.lang.reflect.Type; @SuppressWarnings("serial") public class FieldDecorated extends AbstractBehavior { private final Class fieldClass; private final Decorator decorator; public FieldDecorated(ComponentAdapter delegate, Class fieldClass, Decorator decorator) { super(delegate); this.fieldClass = fieldClass; this.decorator = decorator; } public Object getComponentInstance(final PicoContainer container, Type into) throws PicoCompositionException { Object instance = super.getComponentInstance(container, into); Field[] fields = instance.getClass().getDeclaredFields(); for (Field field : fields) { if (field.getType() == fieldClass) { Object value = decorator.decorate(instance); field.setAccessible(true); try { field.set(instance, value); } catch (IllegalAccessException e) { throw new PicoCompositionException(e); } } } return instance; } public String getDescriptor() { return "FieldDecorated"; } public interface Decorator { Object decorate(Object instance); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/FieldDecorating.java000066400000000000000000000051131242247644300272100ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) NanoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Joerg Schaibe * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * BehaviorFactory for Field Decorating. This factory will create {@link org.picocontainer.gems.behaviors.FieldDecorated} that will * allow you to decorate fields on the component instance that has been created * * @author Paul Hammant */ public abstract class FieldDecorating extends AbstractBehaviorFactory implements FieldDecorated.Decorator { private final Class fieldClass; public FieldDecorating(Class fieldClass) { this.fieldClass = fieldClass; } public ComponentAdapter createComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final Object componentKey, final Class componentImplementation, final Parameter... parameters) throws PicoCompositionException { return componentMonitor.newBehavior(new FieldDecorated( super.createComponentAdapter( componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters), fieldClass, this)); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/Guarded.java000066400000000000000000000032441242247644300255430ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; import org.picocontainer.ObjectReference; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.ComponentLifecycle; import java.lang.reflect.Type; import java.io.Serializable; /** * behaviour for allows components to be guarded by another component * * @author Paul Hammant * @param */ @SuppressWarnings("serial") public class Guarded extends AbstractBehavior { private final String guard; public Guarded(ComponentAdapter delegate, String guard) { super(delegate); this.guard = guard; } public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { container.getComponent(guard); return super.getComponentInstance(container, into); } public String getDescriptor() { return "Guarded(with " + guard + ")"; } }libpicocontainer-java-2.15/org/picocontainer/behaviors/Guarding.java000066400000000000000000000052701242247644300257310ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.ComponentMonitor; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.LifecycleStrategy; import java.util.Properties; /** * factory class creating guard behaviour * * @author Paul Hammant */ @SuppressWarnings("serial") public class Guarding extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { String guard = getAndRemovePropertiesIfPresentByKey(componentProperties, Characteristics.GUARD); ComponentAdapter delegate = super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); if (guard == null) { return delegate; } else { return componentMonitor.newBehavior(new Guarded(delegate, guard)); } } public ComponentAdapter addComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { String guard = getAndRemovePropertiesIfPresentByKey(componentProperties, Characteristics.GUARD); ComponentAdapter delegate = super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); if (guard == null) { return delegate; } else { return componentMonitor.newBehavior(componentMonitor.newBehavior(new Guarded(delegate, guard))); } } }libpicocontainer-java-2.15/org/picocontainer/behaviors/HiddenImplementation.java000066400000000000000000000114571242247644300302760ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; /** * This component adapter makes it possible to hide the implementation * of a real subject (behind a proxy) provided the key is an interface. *

      * This class exists here, because a) it has no deps on external jars, b) dynamic proxy is quite easy. * The user is prompted to look at picocontainer-gems for alternate and bigger implementations. * * @author Aslak Hellesøy * @author Paul Hammant * @see org.picocontainer.gems.adapters.HotSwappingComponentAdapter for a more feature-rich version of this class. */ @SuppressWarnings("serial") public class HiddenImplementation extends AbstractBehavior { /** * Creates an ImplementationHidingComponentAdapter with a delegate * @param delegate the component adapter to which this adapter delegates */ public HiddenImplementation(ComponentAdapter delegate) { super(delegate); } public T getComponentInstance(final PicoContainer container, Type into) throws PicoCompositionException { ComponentAdapter delegate = getDelegate(); Object componentKey = delegate.getComponentKey(); Class[] classes; if (componentKey instanceof Class && ((Class) delegate.getComponentKey()).isInterface()) { classes = new Class[]{(Class) delegate.getComponentKey()}; } else if (componentKey instanceof Class[]) { classes = (Class[]) componentKey; } else { return delegate.getComponentInstance(container, into); } verifyInterfacesOnly(classes); return createProxy(classes, container, delegate.getComponentImplementation().getClassLoader()); } public String getDescriptor() { return "Hidden"; } @SuppressWarnings("unchecked") protected T createProxy(Class[] interfaces, final PicoContainer container, final ClassLoader classLoader) { final PicoContainer container1 = container; return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() { private final PicoContainer container = container1; private volatile Object instance; public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (instance == null) { synchronized (HiddenImplementation.this) { if (instance == null) { instance = getDelegate().getComponentInstance(container, NOTHING.class); } } } return invokeMethod(instance, method, args, container); } }); } protected Object invokeMethod(Object componentInstance, Method method, Object[] args, PicoContainer container) throws Throwable { ComponentMonitor componentMonitor = currentMonitor(); try { componentMonitor.invoking(container, this, method, componentInstance, args); long startTime = System.currentTimeMillis(); Object rv = method.invoke(componentInstance, args); componentMonitor.invoked(container, this, method, componentInstance, System.currentTimeMillis() - startTime, args, rv); return rv; } catch (final InvocationTargetException ite) { componentMonitor.invocationFailed(method, componentInstance, ite); throw ite.getTargetException(); } } private void verifyInterfacesOnly(Class[] classes) { for (Class clazz : classes) { if (!clazz.isInterface()) { throw new PicoCompositionException( "Class keys must be interfaces. " + clazz + " is not an interface."); } } } } libpicocontainer-java-2.15/org/picocontainer/behaviors/ImplementationHiding.java000066400000000000000000000062201242247644300302750ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * @author Aslak Hellesøy * @see org.picocontainer.gems.adapters.HotSwappingComponentFactory for a more feature-rich version of the class */ @SuppressWarnings("serial") public class ImplementationHiding extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { removePropertiesIfPresent(componentProperties, Characteristics.ENABLE_CIRCULAR); ComponentAdapter componentAdapter = super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); if (removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL)) { return componentAdapter; } removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL); return componentMonitor.newBehavior(new HiddenImplementation(componentAdapter)); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL)) { return adapter; } removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL); return componentMonitor.newBehavior(new HiddenImplementation(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Intercepted.java000066400000000000000000000124771242247644300264460ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoContainer; import java.util.Map; import java.util.HashMap; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.Serializable; /** @author Paul Hammant */ @SuppressWarnings("serial") public class Intercepted extends HiddenImplementation { private final Map pres = new HashMap(); private final Map posts = new HashMap(); private Controller controller = new ControllerWrapper(new InterceptorThreadLocal()); public Intercepted(ComponentAdapter delegate) { super(delegate); } public void addPreInvocation(Class type, Object interceptor) { pres.put(type, interceptor); } public void addPostInvocation(Class type, Object interceptor) { posts.put(type, interceptor); } @Override protected Object invokeMethod(Object componentInstance, Method method, Object[] args, PicoContainer container) throws Throwable { try { controller.clear(); controller.instance(componentInstance); Object pre = pres.get(method.getDeclaringClass()); if (pre != null) { Object rv = method.invoke(pre, args); if (controller.isVetoed()) { return rv; } } Object result = method.invoke(componentInstance, args); controller.setOriginalRetVal(result); Object post = posts.get(method.getDeclaringClass()); if (post != null) { Object rv = method.invoke(post, args); if (controller.isOverridden()) { return rv; } } return result; } catch (final InvocationTargetException ite) { throw ite.getTargetException(); } } public Controller getController() { return controller; } public static class InterceptorThreadLocal extends ThreadLocal implements Serializable { protected Object initialValue() { return new ControllerImpl(); } } public interface Controller { void veto(); void clear(); boolean isVetoed(); void setOriginalRetVal(Object retVal); boolean isOverridden(); void instance(Object instance); Object getInstance(); Object getOriginalRetVal(); void override(); } public static class ControllerImpl implements Controller { private boolean vetoed; private Object retVal; private boolean overridden; private Object instance; public void veto() { vetoed = true; } public void clear() { vetoed = false; overridden = false; retVal = null; instance = null; } public boolean isVetoed() { return vetoed; } public void setOriginalRetVal(Object retVal) { this.retVal = retVal; } public Object getOriginalRetVal() { return retVal; } public boolean isOverridden() { return overridden; } public void instance(Object instance) { this.instance = instance; } public Object getInstance() { return instance; } public void override() { overridden = true; } } public class ControllerWrapper implements Controller { private final ThreadLocal threadLocal; public ControllerWrapper(ThreadLocal threadLocal) { this.threadLocal = threadLocal; } public void veto() { threadLocal.get().veto(); } public void clear() { threadLocal.get().clear(); } public boolean isVetoed() { return threadLocal.get().isVetoed(); } public void setOriginalRetVal(Object retVal) { threadLocal.get().setOriginalRetVal(retVal); } public Object getOriginalRetVal() { return threadLocal.get().getOriginalRetVal(); } public boolean isOverridden() { return threadLocal.get().isOverridden(); } public void instance(Object instance) { threadLocal.get().instance(instance); } public Object getInstance() { return threadLocal.get().getInstance(); } public void override() { threadLocal.get().override(); } } public String getDescriptor() { return "Intercepted"; } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Intercepting.java000066400000000000000000000036141242247644300266240ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import java.util.Properties; /** @author Paul Hammant */ @SuppressWarnings("serial") public class Intercepting extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { return componentMonitor.newBehavior(new Intercepted(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Locked.java000066400000000000000000000032031242247644300253640ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.lang.reflect.Type; /** * @author Paul Hammant */ @SuppressWarnings("serial") public class Locked extends AbstractBehavior { /** * Reentrant lock. */ private Lock lock = new ReentrantLock(); public Locked(ComponentAdapter delegate) { super(delegate); } public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { T retVal = null; lock.lock(); try { retVal = super.getComponentInstance(container, into); } finally { lock.unlock(); } return retVal; } public String getDescriptor() { return "Locked"; } }libpicocontainer-java-2.15/org/picocontainer/behaviors/Locking.java000066400000000000000000000071621242247644300255610ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * This behavior factory provides java.util.concurrent locks. It is recommended to be used instead * of {@link org.picocontainer.behaviors.Synchronizing} since it results in better performance. * @author Aslak Hellesøy * @author Paul Hammant. */ @SuppressWarnings("serial") public class Locking extends AbstractBehaviorFactory { /** {@inheritDoc} **/ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_LOCK)) { return super.createComponentAdapter( componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } removePropertiesIfPresent(componentProperties, Characteristics.LOCK); return componentMonitor.newBehavior(new Locked(super.createComponentAdapter( componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } /** {@inheritDoc} **/ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_LOCK)) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } removePropertiesIfPresent(componentProperties, Characteristics.LOCK); return componentMonitor.newBehavior(new Locked(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/OptInCaching.java000066400000000000000000000103151242247644300264730ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.ComponentMonitor; import org.picocontainer.behaviors.Cached; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.LifecycleStrategy; import java.util.Properties; /** * Behavior that turns off Caching behavior by default. *

      Example:

      *
       * 		import org.picocontainer.*;
       * 		import static org.picocontainer.Characteristics.*;
       * 
       * 		MutablePicoContainer mpc = new PicoBuilder().withBehaviors(new OptInCaching()).build();
       * 		mpc.addComponent(Map.class, HashMap.class) //Multiple Instances, no Caching.
       * 		mpc.as(CACHE).addComponent(Set.class, HashSet.class) //Single Cached Instance.		
       * 
      * @author Aslak Hellesøy * @author rafal@caltha.pl */ @SuppressWarnings("serial") public class OptInCaching extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE)) { return componentMonitor.newBehavior(new Cached(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE); return super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE)) { return componentMonitor.newBehavior(new Cached(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE); return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/PropertyApplicator.java000066400000000000000000000310601242247644300300300ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.io.File; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; import java.util.Set; import java.util.HashMap; import java.security.AccessController; import java.security.PrivilegedAction; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoClassNotFoundException; import org.picocontainer.injectors.SetterInjector; import org.picocontainer.behaviors.AbstractBehavior; import org.picocontainer.behaviors.Cached; /** * Decorating component adapter that can be used to set additional properties * on a component in a bean style. These properties must be managed manually * by the user of the API, and will not be managed by PicoContainer. This class * is therefore not the same as {@link SetterInjector}, * which is a true Setter Injection adapter. *

      * This adapter is mostly handy for setting various primitive properties via setters; * it is also able to set javabean properties by discovering an appropriate * {@link PropertyEditor} and using its setAsText method. *

      * * Note that this class doesn't cache instances. If you want caching, * use a {@link Cached} around this one. * * * @author Aslak Hellesøy * @author Mauro Talevi */ @SuppressWarnings("serial") public class PropertyApplicator extends AbstractBehavior { private Map properties; private transient Map setters = null; /** * Construct a PropertyApplicator. * * @param delegate the wrapped {@link ComponentAdapter} * @throws PicoCompositionException {@inheritDoc} */ public PropertyApplicator(ComponentAdapter delegate) throws PicoCompositionException { super(delegate); } /** * Get a component instance and set given property values. * * @return the component instance with any properties of the properties map set. * @throws PicoCompositionException {@inheritDoc} * @throws PicoCompositionException {@inheritDoc} * @throws org.picocontainer.PicoCompositionException * {@inheritDoc} * @see #setProperties(Map) */ public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { final T componentInstance = super.getComponentInstance(container, into); if (setters == null) { setters = getSetters(getComponentImplementation()); } if (properties != null) { ComponentMonitor componentMonitor = currentMonitor(); Set propertyNames = properties.keySet(); for (String propertyName : propertyNames) { final Object propertyValue = properties.get(propertyName); Method setter = setters.get(propertyName); Object valueToInvoke = this.getSetterParameter(propertyName, propertyValue, componentInstance, container); try { componentMonitor.invoking(container, PropertyApplicator.this, setter, componentInstance, new Object[] {valueToInvoke}); long startTime = System.currentTimeMillis(); setter.invoke(componentInstance, valueToInvoke); componentMonitor.invoked(container, PropertyApplicator.this, setter, componentInstance, System.currentTimeMillis() - startTime, new Object[] {valueToInvoke}, null); } catch (final Exception e) { componentMonitor.invocationFailed(setter, componentInstance, e); throw new PicoCompositionException("Failed to set property " + propertyName + " to " + propertyValue + ": " + e.getMessage(), e); } } } return componentInstance; } public String getDescriptor() { return "PropertyApplied"; } private Map getSetters(Class clazz) { Map result = new HashMap(); Method[] methods = getMethods(clazz); for (Method method : methods) { if (isSetter(method)) { result.put(getPropertyName(method), method); } } return result; } private Method[] getMethods(final Class clazz) { return (Method[]) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return clazz.getMethods(); } }); } private String getPropertyName(Method method) { final String name = method.getName(); String result = name.substring(3); if(result.length() > 1 && !Character.isUpperCase(result.charAt(1))) { result = "" + Character.toLowerCase(result.charAt(0)) + result.substring(1); } else if(result.length() == 1) { result = result.toLowerCase(); } return result; } private boolean isSetter(Method method) { final String name = method.getName(); return name.length() > 3 && name.startsWith("set") && method.getParameterTypes().length == 1; } private Object convertType(PicoContainer container, Method setter, String propertyValue) { if (propertyValue == null) { return null; } Class type = setter.getParameterTypes()[0]; String typeName = type.getName(); Object result = convert(typeName, propertyValue, Thread.currentThread().getContextClassLoader()); if (result == null) { // check if the propertyValue is a key of a component in the container // if so, the typeName of the component and the setters parameter typeName // have to be compatible // TODO: null check only because of test-case, otherwise null is impossible if (container != null) { Object component = container.getComponent(propertyValue); if (component != null && type.isAssignableFrom(component.getClass())) { return component; } } } return result; } /** * Converts a String value of a named type to an object. * Works with primitive wrappers, String, File, URL types, or any type that has * an appropriate {@link PropertyEditor}. * * @param typeName name of the type * @param value its value * @param classLoader used to load a class if typeName is "class" or "java.lang.Class" (ignored otherwise) * @return instantiated object or null if the type was unknown/unsupported */ public static Object convert(String typeName, String value, ClassLoader classLoader) { if (typeName.equals(Boolean.class.getName()) || typeName.equals(boolean.class.getName())) { return Boolean.valueOf(value); } else if (typeName.equals(Byte.class.getName()) || typeName.equals(byte.class.getName())) { return Byte.valueOf(value); } else if (typeName.equals(Short.class.getName()) || typeName.equals(short.class.getName())) { return Short.valueOf(value); } else if (typeName.equals(Integer.class.getName()) || typeName.equals(int.class.getName())) { return Integer.valueOf(value); } else if (typeName.equals(Long.class.getName()) || typeName.equals(long.class.getName())) { return Long.valueOf(value); } else if (typeName.equals(Float.class.getName()) || typeName.equals(float.class.getName())) { return Float.valueOf(value); } else if (typeName.equals(Double.class.getName()) || typeName.equals(double.class.getName())) { return Double.valueOf(value); } else if (typeName.equals(Character.class.getName()) || typeName.equals(char.class.getName())) { return value.toCharArray()[0]; } else if (typeName.equals(String.class.getName()) || typeName.equals("string")) { return value; } else if (typeName.equals(File.class.getName()) || typeName.equals("file")) { return new File(value); } else if (typeName.equals(URL.class.getName()) || typeName.equals("url")) { try { return new URL(value); } catch (MalformedURLException e) { throw new PicoCompositionException(e); } } else if (typeName.equals(Class.class.getName()) || typeName.equals("class")) { return loadClass(classLoader, value); } else { final Class clazz = loadClass(classLoader, typeName); final PropertyEditor editor = PropertyEditorManager.findEditor(clazz); if (editor != null) { editor.setAsText(value); return editor.getValue(); } } return null; } private static Class loadClass(ClassLoader classLoader, String typeName) { try { return classLoader.loadClass(typeName); } catch (ClassNotFoundException e) { throw new PicoClassNotFoundException(typeName, e); } } /** * Sets the bean property values that should be set upon creation. * * @param properties bean properties */ public void setProperties(Map properties) { this.properties = properties; } /** * Converts and validates the given property value to an appropriate object * for calling the bean's setter. * @param propertyName String the property name on the component that * we will be setting the value to. * @param propertyValue Object the property value that we've been given. It * may need conversion to be formed into the value we need for the * component instance setter. * @param componentInstance the component that we're looking to provide * the setter to. * @return Object: the final converted object that can * be used in the setter. * @param container */ private Object getSetterParameter(final String propertyName, final Object propertyValue, final Object componentInstance, PicoContainer container) { if (propertyValue == null) { return null; } Method setter = setters.get(propertyName); //We can assume that there is only one object (as per typical setters) //because the Setter introspector does that job for us earlier. Class setterParameter = setter.getParameterTypes()[0]; Object convertedValue; Class givenParameterClass = propertyValue.getClass(); // //If property value is a string or a true primative then convert it to whatever //we need. (String will convert to string). // convertedValue = convertType(container, setter, propertyValue.toString()); //Otherwise, check the parameter type to make sure we can //assign it properly. if (convertedValue == null) { if (setterParameter.isAssignableFrom(givenParameterClass)) { convertedValue = propertyValue; } else { throw new ClassCastException("Setter: " + setter.getName() + " for addComponent: " + componentInstance.toString() + " can only take objects of: " + setterParameter.getName() + " instead got: " + givenParameterClass.getName()); } } return convertedValue; } public void setProperty(String name, String value) { if (properties == null) { properties = new HashMap(); } properties.put(name, value); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/PropertyApplying.java000066400000000000000000000050111242247644300275120ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.behaviors.PropertyApplicator; import java.util.Properties; /** * A {@link org.picocontainer.ComponentFactory} that creates * {@link PropertyApplicator} instances. * * @author Aslak Hellesøy */ @SuppressWarnings("serial") public final class PropertyApplying extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { ComponentAdapter decoratedAdapter = super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING); return componentMonitor.newBehavior(new PropertyApplicator(decoratedAdapter)); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING); return componentMonitor.newBehavior(new PropertyApplicator(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Stored.java000066400000000000000000000156721242247644300254400ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; import org.picocontainer.ObjectReference; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.ComponentLifecycle; import java.lang.reflect.Type; import java.io.Serializable; /* * behaviour for all behaviours wishing to store * their component in "awkward places" ( object references ) * * @author Konstantin Pribluda */ @SuppressWarnings("serial") public class Stored extends AbstractBehavior { private final ObjectReference> instanceReference; private final ComponentLifecycle lifecycleDelegate; public Stored(ComponentAdapter delegate, ObjectReference> reference) { super(delegate); instanceReference = reference; this.lifecycleDelegate = hasLifecycle(delegate) ? new RealComponentLifecycle() : new NoComponentLifecycle(); } private void guardInstRef() { if (instanceReference.get() == null) { instanceReference.set(new Instance()); } } public boolean componentHasLifecycle() { return lifecycleDelegate.componentHasLifecycle(); } /** * Disposes the cached component instance * {@inheritDoc} */ public void dispose(PicoContainer container) { lifecycleDelegate.dispose(container); } /** * Retrieves the stored reference. May be null if it has * never been set, or possibly if the reference has been * flushed. * * @return the stored object or null. */ public T getStoredObject() { guardInstRef(); return instanceReference.get().instance; } /** * Flushes the cache. * If the component instance is started is will stop and dispose it before * flushing the cache. */ public void flush() { Instance inst = instanceReference.get(); if (inst != null) { Object instance = inst.instance; if (instance != null && instanceReference.get().started) { stop(instance); dispose(instance); } instanceReference.set(null); } } public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { guardInstRef(); T instance = instanceReference.get().instance; if (instance == null) { instance = super.getComponentInstance(container, into); instanceReference.get().instance = instance; } return instance; } public String getDescriptor() { return "Stored" + getLifecycleDescriptor(); } protected String getLifecycleDescriptor() { return (lifecycleDelegate.componentHasLifecycle() ? "+Lifecycle" : ""); } /** * Starts the cached component instance * {@inheritDoc} */ public void start(PicoContainer container) { lifecycleDelegate.start(container); } /** * Stops the cached component instance * {@inheritDoc} */ public void stop(PicoContainer container) { lifecycleDelegate.stop(container); } public boolean isStarted() { return lifecycleDelegate.isStarted(); } private class RealComponentLifecycle implements ComponentLifecycle, Serializable { public void start(PicoContainer container) { guardInstRef(); guardAlreadyDisposed(); guardStartState(true, "already started"); // Lazily make the component if applicable Stored.this.start(getComponentInstance(container, NOTHING.class)); instanceReference.get().started = true; } public void stop(PicoContainer container) { guardInstRef(); guardAlreadyDisposed(); guardNotInstantiated(); guardStartState(false, "not started"); Stored.this.stop(instanceReference.get().instance); instanceReference.get().started = false; } public void dispose(PicoContainer container) { guardInstRef(); Instance instance = instanceReference.get(); if (instance.instance != null) { guardAlreadyDisposed(); Stored.this.dispose(instance.instance); instance.disposed = true; } } private void guardNotInstantiated() { if (instanceReference.get().instance == null) throw new IllegalStateException("'" + getComponentKey() + "' not instantiated"); } private void guardStartState(boolean unexpectedStartState, String message) { if (instanceReference.get().started == unexpectedStartState) throw new IllegalStateException("'" + getComponentKey() + "' " + message); } private void guardAlreadyDisposed() { if (instanceReference.get().disposed) throw new IllegalStateException("'" + getComponentKey() + "' already disposed"); } public boolean componentHasLifecycle() { return true; } public boolean isStarted() { guardInstRef(); return instanceReference.get().started; } } private static class NoComponentLifecycle implements ComponentLifecycle, Serializable { public void start(PicoContainer container) { } public void stop(PicoContainer container) { } public void dispose(PicoContainer container) { } public boolean componentHasLifecycle() { return false; } public boolean isStarted() { return false; } } private static boolean hasLifecycle(ComponentAdapter delegate) { return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).hasLifecycle(delegate.getComponentImplementation()); } public static class Instance implements Serializable { private T instance; protected boolean started; protected boolean disposed; } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Storing.java000066400000000000000000000114041242247644300256120ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.references.ThreadLocalMapObjectReference; import java.io.Serializable; import java.util.Properties; import java.util.HashMap; import java.util.Map; import java.util.Collections; //import java.util.concurrent.ConcurrentHashMap; /** * @author Paul Hammant */ @SuppressWarnings("serial") public class Storing extends AbstractBehaviorFactory { private final StoreThreadLocal mapThreadLocalObjectReference = new StoreThreadLocal(); public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); return componentMonitor.newBehavior(new Stored(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters), new ThreadLocalMapObjectReference(mapThreadLocalObjectReference, componentKey))); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); return componentMonitor.newBehavior(new Stored(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter), new ThreadLocalMapObjectReference(mapThreadLocalObjectReference, adapter.getComponentKey()))); } public StoreWrapper getCacheForThread() { StoreWrapper wrappedMap = new StoreWrapper(); wrappedMap.wrapped = (Map)mapThreadLocalObjectReference.get(); return wrappedMap; } public void putCacheForThread(StoreWrapper wrappedMap) { mapThreadLocalObjectReference.set(wrappedMap.wrapped); } public StoreWrapper resetCacheForThread() { Map map = new HashMap(); mapThreadLocalObjectReference.set(map); StoreWrapper storeWrapper = new StoreWrapper(); storeWrapper.wrapped = map; return storeWrapper; } public void invalidateCacheForThread() { mapThreadLocalObjectReference.set(Collections.unmodifiableMap(Collections.emptyMap())); } public int getCacheSize() { return ((Map)mapThreadLocalObjectReference.get()).size(); } public static class StoreThreadLocal extends ThreadLocal implements Serializable { protected Map initialValue() { return new HashMap(); } } public static class StoreWrapper implements Serializable { private Map wrapped; } }libpicocontainer-java-2.15/org/picocontainer/behaviors/Synchronized.java000066400000000000000000000030161242247644300266440ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehavior; import java.lang.reflect.Type; /** * Component Adapter that uses java synchronized around getComponentInstance(). * @author Aslak Hellesøy * @author Manish Shah */ @SuppressWarnings("serial") public class Synchronized extends AbstractBehavior { public Synchronized(ComponentAdapter delegate) { super(delegate); } public synchronized T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return super.getComponentInstance(container, into); } public String getDescriptor() { return "Synchronized"; } } libpicocontainer-java-2.15/org/picocontainer/behaviors/Synchronizing.java000066400000000000000000000066111242247644300270350ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * This behavior factory provides synchronized wrappers to control access to a particular component. * It is recommended that you use {@link org.picocontainer.behaviors.Locking} instead since it results in better performance * and does the same job. * @author Aslak Hellesøy */ @SuppressWarnings("serial") public class Synchronizing extends AbstractBehaviorFactory { /** {@inheritDoc} **/ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_SYNCHRONIZE)) { return super.createComponentAdapter( componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE); return componentMonitor.newBehavior(new Synchronized(super.createComponentAdapter( componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } /** {@inheritDoc} **/ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_SYNCHRONIZE)) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE); return componentMonitor.newBehavior(new Synchronized(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } } libpicocontainer-java-2.15/org/picocontainer/behaviors/ThreadCached.java000066400000000000000000000023641242247644300264710ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.ComponentAdapter; import org.picocontainer.references.ThreadLocalReference; /** *

      * This behavior supports caches values per thread. *

      * * @author Paul Hammant */ @SuppressWarnings("serial") public final class ThreadCached extends Stored{ public ThreadCached(ComponentAdapter delegate) { super(delegate, new ThreadLocalReference>()); } public String getDescriptor() { return "ThreadCached" + getLifecycleDescriptor(); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/ThreadCaching.java000066400000000000000000000074001242247644300266520ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.behaviors; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import java.util.Properties; /** @author Paul Hammant */ @SuppressWarnings("serial") public class ThreadCaching extends AbstractBehaviorFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); return componentMonitor.newBehavior(new ThreadCached(super.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters))); } public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter adapter) { if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) { return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter); } removePropertiesIfPresent(componentProperties, Characteristics.CACHE); return componentMonitor.newBehavior(new ThreadCached(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter))); } }libpicocontainer-java-2.15/org/picocontainer/behaviors/package.html000066400000000000000000000007071242247644300256070ustar00rootroot00000000000000 Insert title here

      BehaviorFactories make Behaviors which change aspects of component implementations and instances

      libpicocontainer-java-2.15/org/picocontainer/classname/000077500000000000000000000000001242247644300233065ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/classname/ClassLoadingPicoContainer.java000066400000000000000000000034401242247644300311730ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.classname; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.classname.ClassPathElement; import java.net.URL; /** * A ClassLoadingPicoContainer extends PicoContainer with classloader juggling capability * * @author Paul Hammant * @author Aslak Hellesøy */ public interface ClassLoadingPicoContainer extends MutablePicoContainer { /** * Adds a new URL that will be used in classloading * * @param url url of the jar to find components in. * @return ClassPathElement to add permissions to (subject to security * policy) */ ClassPathElement addClassLoaderURL(URL url); /** * Returns class loader that is the aggregate of the URLs added. * * @return A ClassLoader */ ClassLoader getComponentClassLoader(); /** * Make a child container with a given name * * @param name the container name * @return The ScriptedPicoContainer */ ClassLoadingPicoContainer makeChildContainer(String name); /** * Addes a child container with a given name * * @param name the container name * @param child the child PicoContainer */ ClassLoadingPicoContainer addChildContainer(String name, PicoContainer child); } libpicocontainer-java-2.15/org/picocontainer/classname/ClassName.java000066400000000000000000000024741242247644300260260ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.classname; /** * ClassName is a simple wrapper for a class name which is used as a key in * the registration of components in PicoContainer. * * @author Paul Hammant */ public class ClassName implements CharSequence { private final String className; public ClassName(String className) { this.className = className; } public int length() { return className.length(); } public char charAt(int ix) { return className.charAt(ix); } public CharSequence subSequence(int from, int to) { return className.subSequence(from, to); } public String toString() { return className.toString(); } public int hashCode() { return className.hashCode(); } public boolean equals(Object o) { return className.equals(o); } } libpicocontainer-java-2.15/org/picocontainer/classname/ClassPathElement.java000066400000000000000000000035061242247644300273510ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.classname; import java.io.Serializable; import java.net.URL; import java.security.Permission; import java.security.Permissions; import java.util.ArrayList; import java.util.List; /** * ClassPathElement denotes an element in a classpath allowing to grant permissions. * * @author Paul Hammant */ @SuppressWarnings("serial") public class ClassPathElement implements Serializable { private final URL url; private Permissions permissionCollection; private final List permissions = new ArrayList(); public ClassPathElement(URL url) { this.url = url; } public Permission grantPermission(Permission permission) { if (permission == null) { throw new NullPointerException(); } permissions.add(permission); return permission; } public URL getUrl() { return url; } public Permissions getPermissionCollection() { if (permissionCollection == null) { permissionCollection = new Permissions(); for (Permission permission : permissions) { permissionCollection.add(permission); } } return permissionCollection; } public String toString() { return "[" + System.identityHashCode(this) + " " + url + " " + permissions.size() +"]"; } } libpicocontainer-java-2.15/org/picocontainer/classname/DefaultClassLoadingPicoContainer.java000066400000000000000000000615071242247644300325100ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.classname; import org.picocontainer.ComponentAdapter; import org.picocontainer.*; import org.picocontainer.security.CustomPermissionsURLClassLoader; import org.picocontainer.lifecycle.LifecycleState; import org.picocontainer.behaviors.Caching; import org.picocontainer.containers.AbstractDelegatingMutablePicoContainer; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.net.URL; import java.security.AccessController; import java.security.CodeSource; import java.security.PrivilegedAction; import java.security.Permissions; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * Default implementation of ClassLoadingPicoContainer. * * @author Paul Hammant * @author Mauro Talevi * @author Michael Rimov */ @SuppressWarnings("serial") public class DefaultClassLoadingPicoContainer extends AbstractDelegatingMutablePicoContainer implements ClassLoadingPicoContainer, ComponentMonitorStrategy { /** * Converting Map to allow for primitives to be boxed to Object types. */ private static final transient Map primitiveNameToBoxedName = new HashMap(); static { primitiveNameToBoxedName.put("int", Integer.class.getName()); primitiveNameToBoxedName.put("byte", Byte.class.getName()); primitiveNameToBoxedName.put("short", Short.class.getName()); primitiveNameToBoxedName.put("long", Long.class.getName()); primitiveNameToBoxedName.put("float", Float.class.getName()); primitiveNameToBoxedName.put("double", Double.class.getName()); primitiveNameToBoxedName.put("boolean", Boolean.class.getName()); } private final transient List classPathElements = new ArrayList(); private final transient ClassLoader parentClassLoader; private transient ClassLoader componentClassLoader; private transient boolean componentClassLoaderLocked; protected final Map namedChildContainers = new HashMap(); public DefaultClassLoadingPicoContainer(ClassLoader classLoader, ComponentFactory componentFactory, PicoContainer parent) { super(new DefaultPicoContainer(componentFactory, parent)); parentClassLoader = classLoader; } public DefaultClassLoadingPicoContainer(ClassLoader classLoader, MutablePicoContainer delegate) { super(delegate); parentClassLoader = classLoader; } public DefaultClassLoadingPicoContainer(ClassLoader classLoader, PicoContainer parent, ComponentMonitor componentMonitor) { super(new DefaultPicoContainer(new Caching(), parent)); parentClassLoader = classLoader; ((ComponentMonitorStrategy) getDelegate()).changeMonitor(componentMonitor); } public DefaultClassLoadingPicoContainer(ComponentFactory componentFactory) { super(new DefaultPicoContainer(componentFactory, null)); parentClassLoader = DefaultClassLoadingPicoContainer.class.getClassLoader(); } public DefaultClassLoadingPicoContainer(PicoContainer parent) { super(new DefaultPicoContainer(parent)); parentClassLoader = DefaultClassLoadingPicoContainer.class.getClassLoader(); } public DefaultClassLoadingPicoContainer(MutablePicoContainer delegate) { super(delegate); parentClassLoader = DefaultClassLoadingPicoContainer.class.getClassLoader(); } public DefaultClassLoadingPicoContainer(ClassLoader classLoader) { super(new DefaultPicoContainer()); parentClassLoader = classLoader; } public DefaultClassLoadingPicoContainer() { super(new DefaultPicoContainer()); parentClassLoader = DefaultClassLoadingPicoContainer.class.getClassLoader(); } public DefaultClassLoadingPicoContainer(ComponentFactory componentFactory, LifecycleStrategy lifecycleStrategy, PicoContainer parent, ClassLoader cl, ComponentMonitor componentMonitor) { super(new DefaultPicoContainer(componentFactory, lifecycleStrategy, parent, componentMonitor)); parentClassLoader = (cl != null) ? cl : DefaultClassLoadingPicoContainer.class.getClassLoader(); } protected DefaultClassLoadingPicoContainer createChildContainer() { MutablePicoContainer child = getDelegate().makeChildContainer(); DefaultClassLoadingPicoContainer container = new DefaultClassLoadingPicoContainer(getComponentClassLoader(), child); container.changeMonitor(currentMonitor()); return container; } /** * Propagates the monitor change down the delegate chain if a delegate that implements ComponentMonitorStrategy * exists. Because of the ComponentMonitorStrategy API, not all delegates can have their API changed. If * a delegate implementing ComponentMonitorStrategy cannot be found, an exception is thrown. * @throws IllegalStateException if no delegate can be found that implements ComponentMonitorStrategy. * @param monitor the monitor to swap. */ public void changeMonitor(ComponentMonitor monitor) { MutablePicoContainer picoDelegate = getDelegate(); while (picoDelegate != null) { if (picoDelegate instanceof ComponentMonitorStrategy) { ((ComponentMonitorStrategy)picoDelegate).changeMonitor(monitor); return; } if (picoDelegate instanceof AbstractDelegatingMutablePicoContainer) { picoDelegate = ((AbstractDelegatingMutablePicoContainer)picoDelegate).getDelegate(); } else { break; } } throw new IllegalStateException("Could not find delegate picocontainer that implemented ComponentMonitorStrategy"); } public ComponentMonitor currentMonitor() { MutablePicoContainer picoDelegate = getDelegate(); while (picoDelegate != null) { if (picoDelegate instanceof ComponentMonitorStrategy) { return ((ComponentMonitorStrategy)picoDelegate).currentMonitor(); } if (picoDelegate instanceof AbstractDelegatingMutablePicoContainer) { picoDelegate = ((AbstractDelegatingMutablePicoContainer)picoDelegate).getDelegate(); } else { break; } } throw new IllegalStateException("Could not find delegate picocontainer that implemented ComponentMonitorStrategy"); } public final Object getComponent(Object componentKeyOrType) throws PicoException { if (componentKeyOrType instanceof ClassName) { componentKeyOrType = loadClass((ClassName) componentKeyOrType); } Object instance = getDelegate().getComponent(componentKeyOrType); if (instance != null) { return instance; } ComponentAdapter componentAdapter = null; if (componentKeyOrType.toString().startsWith("*")) { String candidateClassName = componentKeyOrType.toString().substring(1); Collection> cas = getComponentAdapters(); for (ComponentAdapter ca : cas) { Object key = ca.getComponentKey(); if (key instanceof Class && candidateClassName.equals(((Class) key).getName())) { componentAdapter = ca; break; } } } if (componentAdapter != null) { return componentAdapter.getComponentInstance(this, ComponentAdapter.NOTHING.class); } else { return getComponentInstanceFromChildren(componentKeyOrType); } } private Object getComponentInstanceFromChildren(Object componentKey) { String componentKeyPath = componentKey.toString(); int ix = componentKeyPath.indexOf('/'); if (ix != -1) { String firstElement = componentKeyPath.substring(0, ix); String remainder = componentKeyPath.substring(ix + 1, componentKeyPath.length()); Object o = getNamedContainers().get(firstElement); if (o != null) { MutablePicoContainer child = (MutablePicoContainer) o; return child.getComponent(remainder); } } return null; } public final MutablePicoContainer makeChildContainer() { return makeChildContainer("containers" + namedChildContainers.size()); } /** * Makes a child container with the same basic characteristics of * this object (ComponentFactory, PicoContainer type, Behavior, * etc) * * @param name the name of the child container * @return The child MutablePicoContainer */ public ClassLoadingPicoContainer makeChildContainer(String name) { DefaultClassLoadingPicoContainer child = createChildContainer(); MutablePicoContainer parentDelegate = getDelegate(); parentDelegate.removeChildContainer(child.getDelegate()); parentDelegate.addChildContainer(child); namedChildContainers.put(name, child); return child; } public boolean removeChildContainer(PicoContainer child) { boolean result = getDelegate().removeChildContainer(child); Iterator> children = namedChildContainers.entrySet().iterator(); while (children.hasNext()) { Map.Entry e = children.next(); PicoContainer pc = e.getValue(); if (pc == child) { children.remove(); } } return result; } protected final Map getNamedContainers() { return namedChildContainers; } public ClassPathElement addClassLoaderURL(URL url) { if (componentClassLoaderLocked) { throw new IllegalStateException("ClassLoader URLs cannot be added once this instance is locked"); } ClassPathElement classPathElement = new ClassPathElement(url); classPathElements.add(classPathElement); return classPathElement; } public MutablePicoContainer addComponent(Object implOrInstance) { if (implOrInstance instanceof ClassName) { super.addComponent(loadClass((ClassName) implOrInstance)); } else { super.addComponent(implOrInstance); } return this; } public MutablePicoContainer addComponent(Object key, Object componentImplementationOrInstance, Parameter... parameters) { super.addComponent(classNameToClassIfApplicable(key), classNameToClassIfApplicable(componentImplementationOrInstance), parameters); return this; } private Object classNameToClassIfApplicable(Object key) { if (key instanceof ClassName) { key = loadClass((ClassName) key); } return key; } public MutablePicoContainer addAdapter(ComponentAdapter componentAdapter) throws PicoCompositionException { super.addAdapter(componentAdapter); return this; } public ClassLoader getComponentClassLoader() { if (componentClassLoader == null) { componentClassLoaderLocked = true; componentClassLoader = AccessController.doPrivileged(new PrivilegedAction() { public ClassLoader run() { return new CustomPermissionsURLClassLoader(getURLs(classPathElements), makePermissions(), parentClassLoader); } }); } return componentClassLoader; } public MutablePicoContainer addChildContainer(PicoContainer child) { getDelegate().addChildContainer(child); namedChildContainers.put("containers" + namedChildContainers.size(), child); return this; } public ClassLoadingPicoContainer addChildContainer(String name, PicoContainer child) { super.addChildContainer(child); namedChildContainers.put(name, child); return this; } private Class loadClass(final ClassName className) { ClassLoader classLoader = getComponentClassLoader(); // this is deliberately not a doPrivileged operation. String cn = getClassName(className.toString()); try { return classLoader.loadClass(cn); } catch (ClassNotFoundException e) { throw new PicoClassNotFoundException(cn, e); } } private Map makePermissions() { Map permissionsMap = new HashMap(); for (ClassPathElement cpe : classPathElements) { Permissions permissionCollection = cpe.getPermissionCollection(); permissionsMap.put(cpe.getUrl(), permissionCollection); } return permissionsMap; } private URL[] getURLs(List classPathElemelements) { final URL[] urls = new URL[classPathElemelements.size()]; for (int i = 0; i < urls.length; i++) { urls[i] = (classPathElemelements.get(i)).getUrl(); } return urls; } private static String getClassName(String primitiveOrClass) { String fromMap = primitiveNameToBoxedName.get(primitiveOrClass); return fromMap != null ? fromMap : primitiveOrClass; } public ComponentAdapter getComponentAdapter(Object componentKey) { Object componentKey2 = componentKey; if (componentKey instanceof ClassName) { componentKey2 = loadClass((ClassName) componentKey); } return super.getComponentAdapter(componentKey2); } public MutablePicoContainer change(Properties... properties) { super.change(properties); return this; } public MutablePicoContainer as(Properties... properties) { return new AsPropertiesPicoContainer(properties); } private class AsPropertiesPicoContainer implements ClassLoadingPicoContainer { private MutablePicoContainer delegate; public AsPropertiesPicoContainer(Properties... props) { delegate = DefaultClassLoadingPicoContainer.this.getDelegate().as(props); } public ClassPathElement addClassLoaderURL(URL url) { return DefaultClassLoadingPicoContainer.this.addClassLoaderURL(url); } public ClassLoader getComponentClassLoader() { return DefaultClassLoadingPicoContainer.this.getComponentClassLoader(); } public ClassLoadingPicoContainer makeChildContainer(String name) { return DefaultClassLoadingPicoContainer.this.makeChildContainer(name); } public ClassLoadingPicoContainer addChildContainer(String name, PicoContainer child) { return (ClassLoadingPicoContainer) DefaultClassLoadingPicoContainer.this.addChildContainer(child); } public MutablePicoContainer addComponent(Object componentKey, Object componentImplementationOrInstance, Parameter... parameters) { delegate.addComponent(classNameToClassIfApplicable(componentKey), classNameToClassIfApplicable(componentImplementationOrInstance), parameters); return DefaultClassLoadingPicoContainer.this; } public MutablePicoContainer addComponent(Object implOrInstance) { delegate.addComponent(classNameToClassIfApplicable(implOrInstance)); return DefaultClassLoadingPicoContainer.this; } public MutablePicoContainer addConfig(String name, Object val) { delegate.addConfig(name, val); return DefaultClassLoadingPicoContainer.this; } public MutablePicoContainer addAdapter(ComponentAdapter componentAdapter) { delegate.addAdapter(componentAdapter); return DefaultClassLoadingPicoContainer.this; } public ComponentAdapter removeComponent(Object componentKey) { return delegate.removeComponent(componentKey); } public ComponentAdapter removeComponentByInstance(Object componentInstance) { return delegate.removeComponentByInstance(componentInstance); } public MutablePicoContainer makeChildContainer() { return DefaultClassLoadingPicoContainer.this.makeChildContainer(); } public MutablePicoContainer addChildContainer(PicoContainer child) { return DefaultClassLoadingPicoContainer.this.addChildContainer(child); } public boolean removeChildContainer(PicoContainer child) { return DefaultClassLoadingPicoContainer.this.removeChildContainer(child); } public MutablePicoContainer change(Properties... properties) { return DefaultClassLoadingPicoContainer.this.change(properties); } public MutablePicoContainer as(Properties... properties) { return new AsPropertiesPicoContainer(properties); } public Object getComponent(Object componentKeyOrType) { return DefaultClassLoadingPicoContainer.this.getComponent(componentKeyOrType); } public Object getComponent(Object componentKeyOrType, Type into) { return DefaultClassLoadingPicoContainer.this.getComponent(componentKeyOrType, into); } public T getComponent(Class componentType) { return DefaultClassLoadingPicoContainer.this.getComponent(componentType); } public T getComponent(Class componentType, Class binding) { return DefaultClassLoadingPicoContainer.this.getComponent(componentType, binding); } public List getComponents() { return DefaultClassLoadingPicoContainer.this.getComponents(); } public PicoContainer getParent() { return DefaultClassLoadingPicoContainer.this.getParent(); } public ComponentAdapter getComponentAdapter(Object componentKey) { return DefaultClassLoadingPicoContainer.this.getComponentAdapter(componentKey); } public ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding) { return DefaultClassLoadingPicoContainer.this.getComponentAdapter(componentType, componentNameBinding); } public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { return DefaultClassLoadingPicoContainer.this.getComponentAdapter(componentType, binding); } public Collection> getComponentAdapters() { return DefaultClassLoadingPicoContainer.this.getComponentAdapters(); } public List> getComponentAdapters(Class componentType) { return DefaultClassLoadingPicoContainer.this.getComponentAdapters(componentType); } public List> getComponentAdapters(Class componentType, Class binding) { return DefaultClassLoadingPicoContainer.this.getComponentAdapters(componentType, binding); } public List getComponents(Class componentType) { return DefaultClassLoadingPicoContainer.this.getComponents(componentType); } public void accept(PicoVisitor visitor) { DefaultClassLoadingPicoContainer.this.accept(visitor); } public void start() { //This implementation does nothing on lifecycle triggers. } public void stop() { //This implementation does nothing on lifecycle triggers. } public void dispose() { //This implementation does nothing on lifecycle triggers. } public void setName(String name) { DefaultClassLoadingPicoContainer.this.setName(name); } public void setLifecycleState(LifecycleState lifecycleState) { DefaultClassLoadingPicoContainer.this.setLifecycleState(lifecycleState); } public Converters getConverter() { return DefaultClassLoadingPicoContainer.this.getConverters(); } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getLifecycleState() */ public LifecycleState getLifecycleState() { return DefaultClassLoadingPicoContainer.this.getLifecycleState(); } /** * {@inheritDoc} * @see org.picocontainer.MutablePicoContainer#getName() */ public String getName() { return DefaultClassLoadingPicoContainer.this.getName(); } } public int visit(ClassName thisClassesPackage, String regex, boolean recursive, ClassVisitor classNameVisitor) { Class clazz = loadClass(thisClassesPackage); /* File Seperator of '\\' can cause bogus results in Windows -- So we keep it to forward slash since Windows * can handle it. * -MR */ String pkgName = clazz.getPackage().getName().replace(".", "/"); CodeSource codeSource = clazz.getProtectionDomain().getCodeSource(); if(codeSource == null) { throw new PicoCompositionException("no codesource for " + thisClassesPackage); } String codeSourceRoot = codeSource.getLocation().getFile(); String fileName = codeSourceRoot + File.separator + pkgName; File file = new File(fileName); Pattern compiledPattern = Pattern.compile(regex); if (file.exists()) { if (file.isFile()) { file = file.getParentFile(); } return visit(file, pkgName, compiledPattern, recursive, classNameVisitor); } else { return visit(pkgName, codeSourceRoot, compiledPattern, recursive, classNameVisitor); } } public int visit(String pkgName, String codeSourceRoot, Pattern compiledPattern, boolean recursive, ClassVisitor classNameVisitor) { int found = 0; try { ZipFile zip = new ZipFile(new File(codeSourceRoot)); for (Enumeration e = zip.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); String entryName = entry.getName(); if (entryName.startsWith(pkgName) && entryName.endsWith(".class")) { String name = entryName.substring(pkgName.length()+1); if (name.endsWith("XStream.class")) { System.out.println(); } int length = name.split("/").length; if (length == 1 || recursive) { found = visit(pkgName, compiledPattern, classNameVisitor, found, entryName.replace("/","."), null); } } } } catch (IOException e) { e.printStackTrace(); } return found; } public int visit(File pkgDir, String pkgName, Pattern pattern, boolean recursive, ClassVisitor classNameVisitor) { int found = 0; File files[] = pkgDir.listFiles(); if(files != null) { for (File file : files) { if (file.isDirectory()) { if (recursive) { found = found + visit(file, pkgName, pattern, recursive, classNameVisitor); } } else { found = visit(pkgName, pattern, classNameVisitor, found, file.getName(), file.getAbsolutePath().replace(File.separatorChar, '/') ); } } } return found; } private int visit(String pkgName, Pattern pattern, ClassVisitor classNameVisitor, int foundSoFar, String fileName, String absolutePath) { boolean matches = pattern.matcher(fileName).matches(); if (matches) { if (absolutePath != null) { String fqn = absolutePath.substring(absolutePath.indexOf(pkgName)); fileName = fqn.substring(0, fqn.indexOf(".class")).replace('/', '.');; } else { fileName = fileName.substring(0, fileName.indexOf(".class")); } classNameVisitor.classFound(loadClass(new ClassName(fileName))); foundSoFar++; } return foundSoFar; } public interface ClassVisitor { void classFound(Class clazz); } }libpicocontainer-java-2.15/org/picocontainer/composers/000077500000000000000000000000001242247644300233525ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/composers/RegexComposer.java000066400000000000000000000046241242247644300270050ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.composers; import org.picocontainer.ComponentAdapter; import org.picocontainer.PicoContainer; import org.picocontainer.monitors.ComposingMonitor; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Subsets components in a container, the keys for which match a regular expression. */ public class RegexComposer implements ComposingMonitor.Composer { private final Pattern pattern; private final String forNamedComponent; public RegexComposer(String pattern, String forNamedComponent) { this.pattern = Pattern.compile(pattern); this.forNamedComponent = forNamedComponent; } public RegexComposer() { pattern = null; forNamedComponent = null; } public Object compose(PicoContainer container, Object componentKey) { if (componentKey instanceof String && (forNamedComponent == null || forNamedComponent.equals(componentKey))) { Pattern pat = null; if (pattern == null) { pat = Pattern.compile((String) componentKey); } else { pat = pattern; } Collection> cas = container.getComponentAdapters(); List retVal = new ArrayList(); for (ComponentAdapter componentAdapter : cas) { Object key = componentAdapter.getComponentKey(); if (key instanceof String) { Matcher matcher = pat.matcher((String) key); if (matcher != null && matcher.find()) { retVal.add(componentAdapter.getComponentInstance(container, ComponentAdapter.NOTHING.class)); } } } return retVal; } return null; } } libpicocontainer-java-2.15/org/picocontainer/composers/package.html000066400000000000000000000010461242247644300256340ustar00rootroot00000000000000 Insert title here

      Composers collaborate with ComposingMonitor to collect subsets of components for injection according to an scheme like:

      • Regular expression match of component keys
      libpicocontainer-java-2.15/org/picocontainer/containers/000077500000000000000000000000001242247644300235055ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/containers/AbstractDelegatingMutablePicoContainer.java000066400000000000000000000073361242247644300341000ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by the committers * *****************************************************************************/ package org.picocontainer.containers; import java.util.Properties; import org.picocontainer.ComponentAdapter; import org.picocontainer.MutablePicoContainer; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.lifecycle.LifecycleState; /** * abstract base class for delegating to mutable containers * @author Paul Hammant */ public abstract class AbstractDelegatingMutablePicoContainer extends AbstractDelegatingPicoContainer implements MutablePicoContainer { public AbstractDelegatingMutablePicoContainer(MutablePicoContainer delegate) { super(delegate); } public MutablePicoContainer addComponent(Object componentKey, Object componentImplementationOrInstance, Parameter... parameters) throws PicoCompositionException { return getDelegate().addComponent(componentKey, componentImplementationOrInstance, parameters); } public MutablePicoContainer addComponent(Object implOrInstance) throws PicoCompositionException { return getDelegate().addComponent(implOrInstance); } public MutablePicoContainer addConfig(String name, Object val) { return getDelegate().addConfig(name, val); } public MutablePicoContainer addAdapter(ComponentAdapter componentAdapter) throws PicoCompositionException { return getDelegate().addAdapter(componentAdapter); } public ComponentAdapter removeComponent(Object componentKey) { return getDelegate().removeComponent(componentKey); } public ComponentAdapter removeComponentByInstance(T componentInstance) { return getDelegate().removeComponentByInstance(componentInstance); } public MutablePicoContainer addChildContainer(PicoContainer child) { return getDelegate().addChildContainer(child); } public boolean removeChildContainer(PicoContainer child) { return getDelegate().removeChildContainer(child); } public MutablePicoContainer change(Properties... properties) { return getDelegate().change(properties); } public MutablePicoContainer as(Properties... properties) { return getDelegate().as(properties); } public void dispose() { getDelegate().dispose(); } public MutablePicoContainer makeChildContainer() { return null; } public void start() { getDelegate().start(); } public void stop() { getDelegate().stop(); } public MutablePicoContainer getDelegate() { return (MutablePicoContainer) super.getDelegate(); } public void setName(String name) { getDelegate().setName(name); } public void setLifecycleState(LifecycleState lifecycleState) { getDelegate().setLifecycleState(lifecycleState); } /** {@inheritDoc} **/ public LifecycleState getLifecycleState() { return getDelegate().getLifecycleState(); } /** {@inheritDoc} **/ public String getName() { return getDelegate().getName(); } } libpicocontainer-java-2.15/org/picocontainer/containers/AbstractDelegatingPicoContainer.java000066400000000000000000000070761242247644300325670ustar00rootroot00000000000000package org.picocontainer.containers; import org.picocontainer.ComponentAdapter; import org.picocontainer.Converters; import org.picocontainer.Converting; import org.picocontainer.NameBinding; import org.picocontainer.PicoContainer; import org.picocontainer.PicoException; import org.picocontainer.PicoVisitor; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import java.util.List; /** * Abstract base class for immutable delegation to a PicoContainer * * @author Konstantin Pribluda * */ @SuppressWarnings("serial") public abstract class AbstractDelegatingPicoContainer implements PicoContainer, Converting, Serializable{ private PicoContainer delegate; public AbstractDelegatingPicoContainer(PicoContainer delegate) { if (delegate == null) { throw new NullPointerException( "PicoContainer delegate must not be null"); } this.delegate = delegate; } public final void accept(PicoVisitor visitor) { visitor.visitContainer(this); delegate.accept(visitor); } @Override public boolean equals(Object obj) { // required to make it pass on both jdk 1.3 and jdk 1.4. Btw, what about // overriding hashCode()? (AH) return delegate.equals(obj) || this == obj; } public T getComponent(Class componentType) { return componentType.cast(getComponent((Object) componentType)); } public T getComponent(Class componentType, Class binding) { return delegate.getComponent(componentType, binding); } public Object getComponent(Object componentKeyOrType) { return delegate.getComponent(componentKeyOrType); } public Object getComponent(Object componentKeyOrType, Type into) { return delegate.getComponent(componentKeyOrType, into); } public ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding) { return delegate.getComponentAdapter(componentType, componentNameBinding); } public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { return delegate.getComponentAdapter(componentType, binding); } public ComponentAdapter getComponentAdapter(Object componentKey) { return delegate.getComponentAdapter(componentKey); } public Collection> getComponentAdapters() { return delegate.getComponentAdapters(); } public List> getComponentAdapters( Class componentType) { return delegate.getComponentAdapters(componentType); } public List> getComponentAdapters(Class componentType, Class binding) { return delegate.getComponentAdapters(componentType, binding); } public List getComponents() { return delegate.getComponents(); } public List getComponents(Class type) throws PicoException { return delegate.getComponents(type); } public PicoContainer getDelegate() { return delegate; } public PicoContainer getParent() { return delegate.getParent(); } @Override public String toString() { return "[Delegate]:" + delegate.toString(); } public Converters getConverters() { if (delegate instanceof Converting) { return ((Converting) delegate).getConverters(); } else { return null; } } } libpicocontainer-java-2.15/org/picocontainer/containers/CommandLineArgumentsPicoContainer.java000066400000000000000000000055461242247644300331140ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.containers; import java.io.IOException; import java.io.StringReader; import org.picocontainer.PicoContainer; /** * Compatibility stub. This class was renamed to CommandLinePicoContainer for * PicoContainer version 2.4. * * @author Michael Rimov * @deprecated Use {@link org.picocontainer.containers.CommandLinePicoContainer} * instead. */ @Deprecated @SuppressWarnings("serial") public final class CommandLineArgumentsPicoContainer extends CommandLinePicoContainer { /** * @param separator * @param arguments */ public CommandLineArgumentsPicoContainer(final String separator, final String[] arguments) { super(separator, arguments); } /** * @param separator * @param arguments * @param parent */ public CommandLineArgumentsPicoContainer(final String separator, final String[] arguments, final PicoContainer parent) { super(separator, arguments, parent); } /** * @param separator * @param argumentsProps * @throws IOException */ public CommandLineArgumentsPicoContainer(final String separator, final StringReader argumentsProps) throws IOException { super(separator, argumentsProps); } /** * @param separator * @param argumentProperties * @param arguments * @throws IOException */ public CommandLineArgumentsPicoContainer(final String separator, final StringReader argumentProperties, final String[] arguments) throws IOException { super(separator, argumentProperties, arguments); } /** * @param separator * @param argumentProperties * @param arguments * @param parent * @throws IOException */ public CommandLineArgumentsPicoContainer(final String separator, final StringReader argumentProperties, final String[] arguments, final PicoContainer parent) throws IOException { super(separator, argumentProperties, arguments, parent); } /** * @param arguments */ public CommandLineArgumentsPicoContainer(final String[] arguments) { super(arguments); } /** * @param arguments * @param parent */ public CommandLineArgumentsPicoContainer(final String[] arguments, final PicoContainer parent) { super(arguments, parent); } } libpicocontainer-java-2.15/org/picocontainer/containers/CommandLinePicoContainer.java000066400000000000000000000101351242247644300312140ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.containers; import java.io.IOException; import java.io.LineNumberReader; import java.io.StringReader; import java.util.List; import org.picocontainer.ComponentAdapter; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; /** * CommandLineArgumentsPicoContainer configured itself from array of strings * which are most likely coming in as command line arguments * */ @SuppressWarnings("serial") public class CommandLinePicoContainer extends AbstractDelegatingPicoContainer { public CommandLinePicoContainer(String separator, String[] arguments) { this(separator,arguments,null); } public CommandLinePicoContainer(String separator, String[] arguments, PicoContainer parent ) { super(new DefaultPicoContainer(parent)); for (String argument : arguments) { processArgument(argument, separator); } } public CommandLinePicoContainer(String separator, StringReader argumentsProps) throws IOException { this(separator, argumentsProps, new String[0]); } public CommandLinePicoContainer(String separator, StringReader argumentProperties, String[] arguments) throws IOException{ this(separator,argumentProperties,arguments,null); } public CommandLinePicoContainer(String separator, StringReader argumentProperties, String[] arguments, PicoContainer parent) throws IOException { super(new DefaultPicoContainer(parent)); LineNumberReader lnr = new LineNumberReader(argumentProperties); String line = lnr.readLine(); while (line != null) { processArgument(line, separator); line = lnr.readLine(); } for (String argument : arguments) { processArgument(argument, separator); } } public CommandLinePicoContainer(String[] arguments) { this("=", arguments); } public CommandLinePicoContainer(String[] arguments, PicoContainer parent) { this("=", arguments,parent); } private void addConfig(String key, Object val) { if (getDelegate().getComponent(key) != null) { getDelegate().removeComponent(key); } getDelegate().addConfig(key, val); } public T getComponent(Class componentType) { return null; } public List> getComponentAdapters(Class componentType) { return null; } public PicoContainer getParent() { return new EmptyPicoContainer(); } private void processArgument(String argument, String separator) { String[] kvs = argument.split(separator); if (kvs.length == 2) { addConfig(kvs[0], kvs[1]); } else if (kvs.length == 1) { addConfig(kvs[0], "true"); } else if (kvs.length > 2) { throw new PicoCompositionException( "Argument name'"+separator+"'value pair '" + argument + "' has too many '"+separator+"' characters"); } } public MutablePicoContainer getDelegate() { return (MutablePicoContainer) super.getDelegate(); } public void setName(String s) { ((MutablePicoContainer)getDelegate()).setName(s); } @Override public String toString() { return "[CommandLine]:" + super.getDelegate().toString(); } } libpicocontainer-java-2.15/org/picocontainer/containers/CompositePicoContainer.java000066400000000000000000000122251242247644300307720ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by various * *****************************************************************************/ package org.picocontainer.containers; import org.picocontainer.*; import java.lang.reflect.Type; import java.lang.annotation.Annotation; import java.io.Serializable; import java.util.List; import java.util.Collection; import java.util.Collections; /** * CompositePicoContainer takes a var-args list of containers and will query them * in turn for getComponent(*) and getComponentAdapter(*) requests. Methods returning * lists and getParent/accept will not function. */ public class CompositePicoContainer implements PicoContainer, Converting, Serializable { private final PicoContainer[] containers; private Converters compositeConverter = new CompositeConverters(); public class CompositeConverters implements Converters { public boolean canConvert(Type type) { for (PicoContainer container : containers) { if (container instanceof Converting && ((Converting) container).getConverters().canConvert(type)) { return true; } } return false; } public Object convert(String paramValue, Type type) { for (PicoContainer container : containers) { if (container instanceof Converting) { Converters converter = ((Converting) container).getConverters(); if (converter.canConvert(type)) { return converter.convert(paramValue, type); } } } return null; } } public CompositePicoContainer(PicoContainer... containers) { this.containers = containers; } public T getComponent(Class componentType) { for (PicoContainer container : containers) { T inst = container.getComponent(componentType); if (inst != null) { return inst; } } return null; } public Object getComponent(Object componentKeyOrType, Type into) { for (PicoContainer container : containers) { Object inst = container.getComponent(componentKeyOrType, into); if (inst != null) { return inst; } } return null; } public Object getComponent(Object componentKeyOrType) { for (PicoContainer container : containers) { Object inst = container.getComponent(componentKeyOrType); if (inst != null) { return inst; } } return null; } public ComponentAdapter getComponentAdapter(Object componentKey) { for (PicoContainer container : containers) { ComponentAdapter inst = container.getComponentAdapter(componentKey); if (inst != null) { return inst; } } return null; } public ComponentAdapter getComponentAdapter(Class componentType, NameBinding nameBinding) { for (PicoContainer container : containers) { ComponentAdapter inst = container.getComponentAdapter(componentType, nameBinding); if (inst != null) { return inst; } } return null; } public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { for (PicoContainer container : containers) { ComponentAdapter inst = container.getComponentAdapter(componentType, binding); if (inst != null) { return inst; } } return null; } public T getComponent(Class componentType, Class binding) { return null; } public List getComponents() { return Collections.emptyList(); } public PicoContainer getParent() { return null; } public Collection> getComponentAdapters() { return Collections.emptyList(); } public List> getComponentAdapters(Class componentType) { return Collections.emptyList(); } public List> getComponentAdapters(Class componentType, Class binding) { return Collections.emptyList(); } public List getComponents(Class componentType) { return Collections.emptyList(); } public void accept(PicoVisitor visitor) { } public Converters getConverters() { return compositeConverter; } } libpicocontainer-java-2.15/org/picocontainer/containers/EmptyPicoContainer.java000066400000000000000000000066341242247644300301350ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammant * *****************************************************************************/ package org.picocontainer.containers; import org.picocontainer.*; import org.picocontainer.converters.ConvertsNothing; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.List; import java.lang.annotation.Annotation; import java.lang.reflect.Type; /** * Empty pico container serving as recoil damper in situations where you * do not like to check whether container reference supplied to you * is null or not * * @author Konstantin Pribluda */ @SuppressWarnings("serial") public class EmptyPicoContainer implements PicoContainer, Converting, Serializable { @SuppressWarnings("unused") public Object getComponent(Object componentKeyOrType) { return null; } @SuppressWarnings("unused") public Object getComponent(Object componentKeyOrType, Type into) { return null; } @SuppressWarnings("unused") public T getComponent(Class componentType) { return null; } @SuppressWarnings("unused") public T getComponent(Class componentType, Class binding) { return null; } public List getComponents() { return Collections.EMPTY_LIST; } public PicoContainer getParent() { return null; } @SuppressWarnings("unused") public ComponentAdapter getComponentAdapter(Object componentKey) { return null; } @SuppressWarnings("unused") public ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding) { return null; } @SuppressWarnings("unused") public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { return null; } public Collection> getComponentAdapters() { return Collections.emptyList(); } @SuppressWarnings("unused") public List> getComponentAdapters(Class componentType) { return Collections.emptyList(); } @SuppressWarnings("unused") public List> getComponentAdapters(Class componentType, Class binding) { return Collections.emptyList(); } /** * we do not have anything to do here. */ @SuppressWarnings("unused") public void accept(PicoVisitor visitor) { //Does nothing. } /** {@inheritDoc} **/ @SuppressWarnings("unused") public List getComponents(Class componentType) { return Collections.emptyList(); } @Override public String toString() { return "(empty)"; } public Converters getConverters() { return new ConvertsNothing(); } } libpicocontainer-java-2.15/org/picocontainer/containers/ImmutablePicoContainer.java000066400000000000000000000077671242247644300307660ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.containers; import org.picocontainer.*; import org.picocontainer.converters.ConvertsNothing; import java.util.List; import java.util.Collection; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Type; /** * wrap pico container to achieve immutability * Typically its used to mock a parent container. * * @author Konstantin Pribluda */ @SuppressWarnings("serial") public final class ImmutablePicoContainer implements PicoContainer, Converting, Serializable { private final PicoContainer delegate; public ImmutablePicoContainer(PicoContainer delegate) { if (delegate == null) { throw new NullPointerException(); } this.delegate = delegate; } public Object getComponent(Object componentKeyOrType) { return delegate.getComponent(componentKeyOrType); } public Object getComponent(Object componentKeyOrType, Type into) { return delegate.getComponent(componentKeyOrType, into); } public T getComponent(Class componentType) { return delegate.getComponent(componentType); } public T getComponent(Class componentType, Class binding) { return delegate.getComponent(componentType, binding); } public List getComponents() { return delegate.getComponents(); } public PicoContainer getParent() { return delegate.getParent(); } public ComponentAdapter getComponentAdapter(Object componentKey) { return delegate.getComponentAdapter(componentKey); } public ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding) { return delegate.getComponentAdapter(componentType, componentNameBinding); } public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { return delegate.getComponentAdapter(componentType, binding); } public Collection> getComponentAdapters() { return delegate.getComponentAdapters(); } public List> getComponentAdapters(Class componentType) { return delegate.getComponentAdapters(componentType); } public List> getComponentAdapters(Class componentType, Class binding) { return delegate.getComponentAdapters(componentType, binding); } public List getComponents(Class componentType) { return delegate.getComponents(componentType); } public final void accept(PicoVisitor visitor) { // don't visit "this" its pointless. delegate.accept(visitor); } public boolean equals(Object obj) { return obj == this || (obj != null && obj == delegate) || (obj instanceof ImmutablePicoContainer && ((ImmutablePicoContainer) obj).delegate == delegate) ; } public int hashCode() { return delegate.hashCode(); } public String toString() { return "[Immutable]:" + delegate.toString(); } public Converters getConverters() { if (delegate instanceof Converting) { return ((Converting) delegate).getConverters(); } return new ConvertsNothing(); } } libpicocontainer-java-2.15/org/picocontainer/containers/PropertiesPicoContainer.java000066400000000000000000000036111242247644300311630ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.containers; import java.util.Properties; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; /** * immutable pico container constructed from properties. * intendet to be used with config parameter * * @author Konstantin Pribluda * */ @SuppressWarnings("serial") public class PropertiesPicoContainer extends AbstractDelegatingPicoContainer { /** * create with parent container and populate from properties * @param properties * @param parent */ public PropertiesPicoContainer(Properties properties, PicoContainer parent) { super(new DefaultPicoContainer(parent)); // populate container from properties for(Object key: properties.keySet()) { ((MutablePicoContainer)getDelegate()).addComponent(key,properties.get(key)); } } /** * construct without a parent * @param properties */ public PropertiesPicoContainer(Properties properties) { this(properties,null); } public void setName(String s) { ((DefaultPicoContainer)getDelegate()).setName(s); } @Override public String toString() { return "[Properties]:" + super.getDelegate().toString(); } } libpicocontainer-java-2.15/org/picocontainer/containers/SystemPropertiesPicoContainer.java000066400000000000000000000023401242247644300323660ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.containers; import org.picocontainer.PicoContainer; /** * A container backed by system properties (is a PropertiesPicoContainer) * @author Konstantin Pribluda */ @SuppressWarnings("serial") public class SystemPropertiesPicoContainer extends PropertiesPicoContainer { public SystemPropertiesPicoContainer() { this(null); } public SystemPropertiesPicoContainer(PicoContainer parent) { super(System.getProperties(),parent); } @Override public String toString() { return "[SysProps]:" + super.getDelegate().toString(); } } libpicocontainer-java-2.15/org/picocontainer/containers/TieringPicoContainer.java000066400000000000000000000163561242247644300304420ustar00rootroot00000000000000package org.picocontainer.containers; import java.lang.annotation.Annotation; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentFactory; import org.picocontainer.ComponentMonitor; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.LifecycleStrategy; import org.picocontainer.MutablePicoContainer; import org.picocontainer.NameBinding; import org.picocontainer.PicoContainer; import org.picocontainer.behaviors.AdaptingBehavior; import org.picocontainer.injectors.AdaptingInjection; @SuppressWarnings("serial") public class TieringPicoContainer extends DefaultPicoContainer { /** * Creates a new container with a custom ComponentFactory, LifecycleStrategy for instance registration, * and a parent container. * * Important note about caching: If you intend the components to be cached, you should pass * in a factory that creates {@link org.picocontainer.behaviors.Cached} instances, such as for example * {@link org.picocontainer.behaviors.Caching}. Caching can delegate to other ComponentAdapterFactories. * * * @param componentFactory the factory to use for creation of ComponentAdapters. * @param lifecycleStrategy * the lifecycle strategy chosen for registered * instance (not implementations!) * @param parent the parent container (used for component dependency lookups). */ public TieringPicoContainer(final ComponentFactory componentFactory, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { super(componentFactory, lifecycleStrategy, parent); } public TieringPicoContainer(final ComponentFactory componentFactory, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent, final ComponentMonitor componentMonitor) { super(componentFactory, lifecycleStrategy, parent, componentMonitor); } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor * * @param monitor the ComponentMonitor to use * @param parent the parent container (used for component dependency lookups). */ public TieringPicoContainer(final ComponentMonitor monitor, final PicoContainer parent) { super(monitor, parent); } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor and lifecycle strategy * * @param monitor the ComponentMonitor to use * @param lifecycleStrategy the lifecycle strategy to use. * @param parent the parent container (used for component dependency lookups). */ public TieringPicoContainer(final ComponentMonitor monitor, final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { super(monitor, lifecycleStrategy, parent); } /** * Creates a new container with the AdaptingInjection using a * custom lifecycle strategy * * @param lifecycleStrategy the lifecycle strategy to use. * @param parent the parent container (used for component dependency lookups). */ public TieringPicoContainer(final LifecycleStrategy lifecycleStrategy, final PicoContainer parent) { super(lifecycleStrategy, parent); } /** * Creates a new container with a custom ComponentFactory and no parent container. * * @param componentFactory the ComponentFactory to use. */ public TieringPicoContainer(final ComponentFactory componentFactory) { super(componentFactory); } /** * Creates a new container with the AdaptingInjection using a * custom ComponentMonitor * * @param monitor the ComponentMonitor to use */ public TieringPicoContainer(final ComponentMonitor monitor) { super(monitor); } /** * Creates a new container with a (caching) {@link AdaptingInjection} * and a parent container. * * @param parent the parent container (used for component dependency lookups). */ public TieringPicoContainer(final PicoContainer parent) { super(parent); } /** Creates a new container with a {@link AdaptingBehavior} and no parent container. */ public TieringPicoContainer() { super(); } public PicoContainer getParent() { return new TieringGuard(super.getParent()); } public MutablePicoContainer makeChildContainer() { return new TieringPicoContainer(super.componentFactory, super.lifecycleStrategy, this, super.componentMonitor); } private static class TieringGuard extends AbstractDelegatingPicoContainer { private static final AskingParentForComponent askingParentForComponent = new AskingParentForComponent(); public TieringGuard(PicoContainer parent) { super(parent); } public ComponentAdapter getComponentAdapter(Class componentType, NameBinding componentNameBinding) { boolean iDidIt = false; try { if (notYetAskingParentForComponent()) { nowAskingParentForComponent(); iDidIt = true; return super.getComponentAdapter(componentType, componentNameBinding); } else { return null; } } finally { if (iDidIt) { doneAskingParentForComponent(); } } } private void nowAskingParentForComponent() { askingParentForComponent.set(Boolean.TRUE); } public ComponentAdapter getComponentAdapter(Class componentType, Class binding) { boolean iDidIt = false; try { if (notYetAskingParentForComponent()) { nowAskingParentForComponent(); iDidIt = true; return super.getComponentAdapter(componentType, binding); } else { return null; } } finally { if (iDidIt) { doneAskingParentForComponent(); } } } private void doneAskingParentForComponent() { askingParentForComponent.set(Boolean.FALSE); } private boolean notYetAskingParentForComponent() { return askingParentForComponent.get() == Boolean.FALSE; } public ComponentAdapter getComponentAdapter(Object componentKey) { boolean iDidIt = false; try { if (notYetAskingParentForComponent()) { nowAskingParentForComponent(); iDidIt = true; return super.getComponentAdapter(componentKey); } else { return null; } } finally { if (iDidIt) { doneAskingParentForComponent(); } } } } private static class AskingParentForComponent extends ThreadLocal { protected Object initialValue() { return Boolean.FALSE; } } }libpicocontainer-java-2.15/org/picocontainer/containers/TransientPicoContainer.java000066400000000000000000000033401242247644300307750ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.containers; import org.picocontainer.ComponentFactory; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.behaviors.Caching; import org.picocontainer.injectors.ConstructorInjection; import org.picocontainer.lifecycle.NullLifecycleStrategy; import org.picocontainer.monitors.NullComponentMonitor; @SuppressWarnings("serial") public class TransientPicoContainer extends DefaultPicoContainer { public TransientPicoContainer() { super(new Caching().wrap(new ConstructorInjection()), new NullLifecycleStrategy(), null, new NullComponentMonitor()); } public TransientPicoContainer(PicoContainer parent) { super(new Caching().wrap(new ConstructorInjection()), new NullLifecycleStrategy(), parent, new NullComponentMonitor()); } public TransientPicoContainer(ComponentFactory componentFactory, PicoContainer parent) { super(componentFactory, new NullLifecycleStrategy(), parent, new NullComponentMonitor()); } } libpicocontainer-java-2.15/org/picocontainer/containers/package.html000066400000000000000000000007671242247644300260000ustar00rootroot00000000000000 Insert title here

      Containers are the main user entry point for PicoContainer. Implementations with behaviors not used in DefaultPicoContainer are in this package

      libpicocontainer-java-2.15/org/picocontainer/converters/000077500000000000000000000000001242247644300235325ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/converters/BooleanConverter.java000066400000000000000000000005431242247644300276460ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'boolean' data type objects * * @author Paul Hammant * @author Michael Rimov */ class BooleanConverter implements Converter { public Boolean convert(String paramValue) { return Boolean.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/BuiltInConverters.java000066400000000000000000000043111242247644300300150ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.Converters; import java.io.File; import java.io.Serializable; import java.lang.reflect.Type; import java.net.URL; import java.util.HashMap; import java.util.Map; /** * Provides some built-in converters used by {@link DefaultPicoContainer}. It * supports by default primitive types (and boxed equivalents) and for * {@link File} and {@link URL} types. Built-in converters can be changed by * extending the class and overriding the method {@link #addBuiltInConverters()}. */ @SuppressWarnings("serial") public class BuiltInConverters implements Converters, Serializable { private final Map, Converter> converters = new HashMap, Converter>(); public BuiltInConverters() { addBuiltInConverters(); } protected void addBuiltInConverters() { addMultiTypeConverter(new IntegerConverter(), Integer.class, Integer.TYPE); addMultiTypeConverter(new DoubleConverter(), Double.class, Double.TYPE); addMultiTypeConverter(new BooleanConverter(), Boolean.class, Boolean.TYPE); addMultiTypeConverter(new LongConverter(), Long.class, Long.TYPE); addMultiTypeConverter(new FloatConverter(), Float.class, Float.TYPE); addMultiTypeConverter(new CharacterConverter(), Character.class, Character.TYPE); addMultiTypeConverter(new ByteConverter(), Byte.class, Byte.TYPE); addMultiTypeConverter(new ShortConverter(), Short.class, Short.TYPE); addConverter(new FileConverter(), File.class); addConverter(new UrlConverter(), URL.class); } private void addMultiTypeConverter(Converter converter, Class... types) { for (Class type : types) { addConverter(converter, type); } } protected void addConverter(Converter converter, Class key) { converters.put(key, converter); } public boolean canConvert(Type type) { return converters.containsKey(type); } public Object convert(String paramValue, Type type) { Converter converter = converters.get(type); if (converter == null) { return null; } return converter.convert(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/ByteConverter.java000066400000000000000000000005301242247644300271660ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'byte' data type objects * * @author Paul Hammant * @author Michael Rimov */ class ByteConverter implements Converter { public Byte convert(String paramValue) { return Byte.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/CharacterConverter.java000066400000000000000000000006341242247644300301640ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts string to single-character. It does so by only grabbing * the first character in the string. * * @author Paul Hammant * @author Michael Rimov */ class CharacterConverter implements Converter { public Character convert(String paramValue) { return paramValue.charAt(0); } } libpicocontainer-java-2.15/org/picocontainer/converters/Converter.java000066400000000000000000000017331242247644300263500ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.converters; /** * Interface for type converters. * * @author Paul Hammant * @author Michael Rimov */ public interface Converter { /** * Performs a conversion between the given parameter value and the target type. * @param parameterValue the string value to convert. * @return the resulting object. */ T convert(String parameterValue); } libpicocontainer-java-2.15/org/picocontainer/converters/ConvertsNothing.java000066400000000000000000000005651242247644300275350ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.Converters; import java.lang.reflect.Type; /** * Null-object implementation of Converters */ public class ConvertsNothing implements Converters { public boolean canConvert(Type type) { return false; } public Object convert(String paramValue, Type type) { return null; } } libpicocontainer-java-2.15/org/picocontainer/converters/DoubleConverter.java000066400000000000000000000005361242247644300275030ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'double' data type objects * * @author Paul Hammant * @author Michael Rimov */ class DoubleConverter implements Converter { public Double convert(String paramValue) { return Double.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/FileConverter.java000066400000000000000000000005431242247644300271460ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; import java.io.File; /** * Converts values to File data type objects * * @author Paul Hammant * @author Michael Rimov */ class FileConverter implements Converter { public File convert(String paramValue) { return new File(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/FloatConverter.java000066400000000000000000000005311242247644300273310ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'float' data type objects * * @author Paul Hammant * @author Michael Rimov */ class FloatConverter implements Converter { public Float convert(String paramValue) { return Float.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/IntegerConverter.java000066400000000000000000000005371242247644300276670ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'int' data type objects * * @author Paul Hammant * @author Michael Rimov */ class IntegerConverter implements Converter { public Integer convert(String paramValue) { return Integer.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/LongConverter.java000066400000000000000000000005241242247644300271650ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'long' data type objects * * @author Paul Hammant * @author Michael Rimov */ class LongConverter implements Converter { public Long convert(String paramValue) { return Long.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/NewInstanceConverter.java000066400000000000000000000015471242247644300305120ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * Converts a value to an object via its single-String constructor. */ public class NewInstanceConverter implements Converter { private Constructor c; public NewInstanceConverter(Class clazz) { try { c = clazz.getConstructor(String.class); } catch (NoSuchMethodException e) { } } public Object convert(String paramValue) { if ( c == null ){ return null; } try { return c.newInstance(paramValue); } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (InstantiationException e) { } return null; } } libpicocontainer-java-2.15/org/picocontainer/converters/ShortConverter.java000066400000000000000000000005301242247644300273620ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.converters.Converter; /** * Converts values to 'short' data type objects * * @author Paul Hammant * @author Michael Rimov */ class ShortConverter implements Converter { public Short convert(String paramValue) { return Short.valueOf(paramValue); } } libpicocontainer-java-2.15/org/picocontainer/converters/UrlConverter.java000066400000000000000000000010131242247644300270220ustar00rootroot00000000000000package org.picocontainer.converters; import org.picocontainer.PicoCompositionException; import java.net.MalformedURLException; import java.net.URL; /** * Converts values to URL data type objects * * @author Paul Hammant * @author Michael Rimov */ public class UrlConverter implements Converter { public URL convert(String paramValue) { try { return new URL(paramValue); } catch (MalformedURLException e) { throw new PicoCompositionException(e); } } } libpicocontainer-java-2.15/org/picocontainer/converters/package.html000066400000000000000000000013441242247644300260150ustar00rootroot00000000000000 Insert title here

      Individual String to Type converters, that PicoContainer may use to convert types where required. Of Note:

      • Primitive and boxed equivalent converters
      • java.io.File and java.net.URL converters
      • Your own implementations of Converter
      • An aggregate 'Converters' implementation that's built-in to PicoContainer (but extensible)
      libpicocontainer-java-2.15/org/picocontainer/injectors/000077500000000000000000000000001242247644300233405ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/injectors/AbstractFieldInjector.java000066400000000000000000000027571242247644300304230ustar00rootroot00000000000000package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.List; import java.util.Set; public abstract class AbstractFieldInjector extends IterativeInjector { public AbstractFieldInjector(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); } @Override final protected void unsatisfiedDependencies(PicoContainer container, Set unsatisfiableDependencyTypes, List unsatisfiableDependencyMembers) { StringBuilder sb = new StringBuilder(this.getComponentImplementation().getName()).append(" has unsatisfied dependency for fields ["); for (int i = 0; i < unsatisfiableDependencyMembers.size(); i++) { AccessibleObject accessibleObject = unsatisfiableDependencyMembers.get(i); Field m = (Field) accessibleObject; sb.append(m.getType().getName()).append(".").append(m.getName()); } String container1 = container.toString(); throw new UnsatisfiableDependenciesException(sb.toString() + "] from " + container1); } } libpicocontainer-java-2.15/org/picocontainer/injectors/AbstractInjectionFactory.java000066400000000000000000000076621242247644300311540ustar00rootroot00000000000000package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.ComponentMonitorStrategy; import org.picocontainer.InjectionFactory; import org.picocontainer.Injector; import org.picocontainer.LifecycleStrategy; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.lifecycle.NullLifecycleStrategy; import java.io.Serializable; import java.lang.reflect.Type; public abstract class AbstractInjectionFactory implements InjectionFactory, Serializable { public void verify(PicoContainer container) { } public final void accept(PicoVisitor visitor) { visitor.visitComponentFactory(this); } protected ComponentAdapter wrapLifeCycle(final Injector injector, LifecycleStrategy lifecycleStrategy) { if (lifecycleStrategy instanceof NullLifecycleStrategy) { return injector; } else { return new LifecycleAdapter(injector, lifecycleStrategy); } } private static class LifecycleAdapter implements Injector, LifecycleStrategy, ComponentMonitorStrategy, Serializable { private final Injector delegate; private final LifecycleStrategy lifecycleStrategy; public LifecycleAdapter(Injector delegate, LifecycleStrategy lifecycleStrategy) { this.delegate = delegate; this.lifecycleStrategy = lifecycleStrategy; } public Object getComponentKey() { return delegate.getComponentKey(); } public Class getComponentImplementation() { return delegate.getComponentImplementation(); } public Object getComponentInstance(PicoContainer container) throws PicoCompositionException { return delegate.getComponentInstance(container); } public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return delegate.getComponentInstance(container, into); } public void verify(PicoContainer container) throws PicoCompositionException { delegate.verify(container); } public void accept(PicoVisitor visitor) { delegate.accept(visitor); } public ComponentAdapter getDelegate() { return delegate; } public ComponentAdapter findAdapterOfType(Class adapterType) { return delegate.findAdapterOfType(adapterType); } public String getDescriptor() { return "LifecycleAdapter"; } public String toString() { return getDescriptor() + ":" + delegate.toString(); } public void start(Object component) { lifecycleStrategy.start(component); } public void stop(Object component) { lifecycleStrategy.stop(component); } public void dispose(Object component) { lifecycleStrategy.dispose(component); } public boolean hasLifecycle(Class type) { return lifecycleStrategy.hasLifecycle(type); } public boolean isLazy(ComponentAdapter adapter) { return lifecycleStrategy.isLazy(adapter); } public void changeMonitor(ComponentMonitor monitor) { if (delegate instanceof ComponentMonitorStrategy) { ((ComponentMonitorStrategy) delegate).changeMonitor(monitor); } } public ComponentMonitor currentMonitor() { if (delegate instanceof ComponentMonitorStrategy) { return ((ComponentMonitorStrategy) delegate).currentMonitor(); } return null; } public Object decorateComponentInstance(PicoContainer container, Type into, Object instance) { return delegate.decorateComponentInstance(container, into, instance); } } } libpicocontainer-java-2.15/org/picocontainer/injectors/AbstractInjector.java000066400000000000000000000370631242247644300274550ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.ObjectReference; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.adapters.AbstractAdapter; import org.picocontainer.parameters.ComponentParameter; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * This ComponentAdapter will instantiate a new object for each call to * {@link org.picocontainer.ComponentAdapter#getComponentInstance(PicoContainer, Type)}. * That means that when used with a PicoContainer, getComponent will * return a new object each time. * * @author Aslak Hellesøy * @author Paul Hammant * @author Jörg Schaible * @author Mauro Talevi */ @SuppressWarnings("serial") public abstract class AbstractInjector extends AbstractAdapter implements org.picocontainer.Injector { /** The cycle guard for the verification. */ protected transient ThreadLocalCyclicDependencyGuard verifyingGuard; /** The parameters to use for initialization. */ protected transient Parameter[] parameters; /** The strategy used to control the lifecycle */ private final boolean useNames; /** * Constructs a new ComponentAdapter for the given key and implementation. * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this ComponentAdapter * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException if the implementation is not a concrete class * @throws NullPointerException if one of the parameters is null */ protected AbstractInjector(final Object componentKey, final Class componentImplementation, final Parameter[] parameters, final ComponentMonitor monitor, final boolean useNames) { super(componentKey, componentImplementation, monitor); this.useNames = useNames; checkConcrete(); if (parameters != null) { for (int i = 0; i < parameters.length; i++) { if(parameters[i] == null) { throw new NullPointerException("Parameter " + i + " is null"); } } } this.parameters = parameters; } public boolean useNames() { return useNames; } private void checkConcrete() throws NotConcreteRegistrationException { // Assert that the component class is concrete. boolean isAbstract = (getComponentImplementation().getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT; if (getComponentImplementation().isInterface() || isAbstract) { throw new NotConcreteRegistrationException(getComponentImplementation()); } } /** * Create default parameters for the given types. * * @param length parameter list length * @return the array with the default parameters. */ protected Parameter[] createDefaultParameters(int length) { Parameter[] componentParameters = new Parameter[length]; for (int i = 0; i < length; i++) { componentParameters[i] = ComponentParameter.DEFAULT; } return componentParameters; } @SuppressWarnings("unused") public void verify(PicoContainer container) throws PicoCompositionException { } @Override public T getComponentInstance(PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, NOTHING.class); } public abstract T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException; @SuppressWarnings("unused") public Object decorateComponentInstance(PicoContainer container, Type into, T instance) { return null; } @Override public void accept(final PicoVisitor visitor) { super.accept(visitor); if (parameters != null) { for (Parameter parameter : parameters) { parameter.accept(visitor); } } } public String getDescriptor() { return "Asbtract Injector"; } /** * Instantiate an object with given parameters and respect the accessible flag. * * @param constructor the constructor to use * @param parameters the parameters for the constructor * @return the new object. * @throws InstantiationException * @throws IllegalAccessException * @throws InvocationTargetException */ protected T newInstance(final Constructor constructor, final Object[] parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException { return constructor.newInstance(parameters); } /** * inform monitor about component instantiation failure * @param componentMonitor * @param constructor * @param e * @param container * @return */ protected T caughtInstantiationException(final ComponentMonitor componentMonitor, final Constructor constructor, final InstantiationException e, final PicoContainer container) { // can't get here because checkConcrete() will catch it earlier, but see PICO-191 componentMonitor.instantiationFailed(container, this, constructor, e); throw new PicoCompositionException("Should never get here"); } /** * inform monitor about access exception. * @param componentMonitor * @param constructor * @param e * @param container * @return */ protected T caughtIllegalAccessException(final ComponentMonitor componentMonitor, final Constructor constructor, final IllegalAccessException e, final PicoContainer container) { // can't get here because either filtered or access mode set componentMonitor.instantiationFailed(container, this, constructor, e); throw new PicoCompositionException(e); } /** * inform monitor about exception while instantiating component * @param componentMonitor * @param member * @param componentInstance * @param e * @return */ protected T caughtInvocationTargetException(final ComponentMonitor componentMonitor, final Member member, final Object componentInstance, final InvocationTargetException e) { componentMonitor.invocationFailed(member, componentInstance, e); if (e.getTargetException() instanceof RuntimeException) { throw (RuntimeException) e.getTargetException(); } else if (e.getTargetException() instanceof Error) { throw (Error) e.getTargetException(); } throw new PicoCompositionException(e.getTargetException()); } protected Object caughtIllegalAccessException(final ComponentMonitor componentMonitor, final Member member, final Object componentInstance, final IllegalAccessException e) { componentMonitor.invocationFailed(member, componentInstance, e); throw new PicoCompositionException(e); } protected Type box(Type parameterType) { if (parameterType instanceof Class && ((Class) parameterType).isPrimitive()) { String parameterTypeName = ((Class) parameterType).getName(); if (parameterTypeName == "int") { return Integer.class; } else if (parameterTypeName == "boolean") { return Boolean.class; } else if (parameterTypeName == "long") { return Long.class; } else if (parameterTypeName == "float") { return Float.class; } else if (parameterTypeName == "double") { return Double.class; } else if (parameterTypeName == "char") { return Character.class; } else if (parameterTypeName == "byte") { return Byte.class; } else if (parameterTypeName == "short") { return Short.class; } } return parameterType; } /** * Abstract utility class to detect recursion cycles. * Derive from this class and implement {@link ThreadLocalCyclicDependencyGuard#run}. * The method will be called by {@link ThreadLocalCyclicDependencyGuard#observe}. Select * an appropriate guard for your scope. Any {@link ObjectReference} can be * used as long as it is initialized with Boolean.FALSE. * * @author Jörg Schaible */ static abstract class ThreadLocalCyclicDependencyGuard extends ThreadLocal { protected PicoContainer guardedContainer; /** * Derive from this class and implement this function with the functionality * to observe for a dependency cycle. * * @return a value, if the functionality result in an expression, * otherwise just return null * @param instance */ public abstract T run(Object instance); /** * Call the observing function. The provided guard will hold the {@link Boolean} value. * If the guard is already Boolean.TRUE a {@link CyclicDependencyException} * will be thrown. * * * @param stackFrame the current stack frame * @param instance * @return the result of the run method */ public final T observe(final Class stackFrame, final Object instance) { if (Boolean.TRUE.equals(get())) { throw new CyclicDependencyException(stackFrame); } T result = null; try { set(Boolean.TRUE); result = run(instance); } catch (final CyclicDependencyException e) { e.push(stackFrame); throw e; } finally { set(null); } return result; } public void setGuardedContainer(final PicoContainer container) { this.guardedContainer = container; } } public static class CyclicDependencyException extends PicoCompositionException { private final List stack; /** * @param element */ public CyclicDependencyException(final Class element) { super((Throwable)null); this.stack = new LinkedList(); push(element); } /** * @param element */ public void push(final Class element) { stack.add(element); } public Class[] getDependencies() { return stack.toArray(new Class[stack.size()]); } @Override public String getMessage() { return "Cyclic dependency: " + stack.toString(); } } /** * Exception that is thrown as part of the introspection. Raised if a PicoContainer cannot resolve a * type dependency because the registered {@link org.picocontainer.ComponentAdapter}s are not * distinct. * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén */ public static final class AmbiguousComponentResolutionException extends PicoCompositionException { private String component; private final Class ambiguousDependency; private final String[] ambiguousComponentKeys; private AccessibleObject accessibleObject; /** * Construct a new exception with the ambiguous class type and the ambiguous component keys. * * @param ambiguousDependency the unresolved dependency type * @param componentKeys the ambiguous keys. */ public AmbiguousComponentResolutionException(final Class ambiguousDependency, final String[] componentKeys) { super(""); this.ambiguousDependency = ambiguousDependency; this.ambiguousComponentKeys = componentKeys; } /** * @return Returns a string containing the unresolved class type and the ambiguous keys. */ @Override public String getMessage() { StringBuffer msg = new StringBuffer(); msg.append(component != null ? component : ""); msg.append(" needs a '"); msg.append(ambiguousDependency.getName()); msg.append("' injected via '"); msg.append(accessibleObject != null ? accessibleObject : ""); msg.append("', but there are too many choices to inject. These:"); msg.append(Arrays.asList(getAmbiguousComponentKeys())); msg.append(", refer http://picocontainer.org/ambiguous-injectable-help.html"); return msg.toString(); } /** * @return Returns the ambiguous component keys as array. */ public String[] getAmbiguousComponentKeys() { return ambiguousComponentKeys; } public void setComponent(final String component) { if (this.component == null) { this.component = component; } } public void setMember(AccessibleObject accessibleObject) { if (this.accessibleObject == null) { this.accessibleObject = accessibleObject; } } } /** * Exception thrown when some of the component's dependencies are not satisfiable. * * @author Aslak Hellesøy * @author Mauro Talevi */ public static class UnsatisfiableDependenciesException extends PicoCompositionException { public UnsatisfiableDependenciesException(String message) { super(message); } } /** * @author Aslak Hellesoy */ public static class NotConcreteRegistrationException extends PicoCompositionException { private final Class componentImplementation; public NotConcreteRegistrationException(final Class componentImplementation) { super("Bad Access: '" + componentImplementation.getName() + "' is not instantiable"); this.componentImplementation = componentImplementation; } public Class getComponentImplementation() { return componentImplementation; } } } libpicocontainer-java-2.15/org/picocontainer/injectors/AdaptingInjection.java000066400000000000000000000314251242247644300276020ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import java.lang.reflect.AccessibleObject; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Properties; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.annotations.Inject; import org.picocontainer.behaviors.AbstractBehaviorFactory; /** * Creates injector instances, depending on the injection characteristics of the component class. * It will attempt to create a component adapter with - in order of priority: *
        *
      1. Annotated field injection: if annotation {@link org.picocontainer.annotations.Inject} is found for field
      2. *
      3. Annotated method injection: if annotation {@link org.picocontainer.annotations.Inject} is found for method
      4. *
      5. Setter injection: if {@link Characteristics.SDI} is found
      6. *
      7. Method injection: if {@link Characteristics.METHOD_INJECTION} if found
      8. *
      9. Constructor injection (the default, must find {@link Characteristics.CDI})
      10. *
      * * @author Paul Hammant * @author Mauro Talevi * @see AnnotatedFieldInjection * @see AnnotatedMethodInjection * @see SetterInjection * @see MethodInjection * @see ConstructorInjection */ @SuppressWarnings("serial") public class AdaptingInjection extends AbstractInjectionFactory { public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { ComponentAdapter componentAdapter = null; componentAdapter = fieldAnnotatedInjectionAdapter(componentImplementation, componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentAdapter, parameters); if (componentAdapter != null) { return componentAdapter; } componentAdapter = methodAnnotatedInjectionAdapter(componentImplementation, componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentAdapter, parameters); if (componentAdapter != null) { return componentAdapter; } componentAdapter = setterInjectionAdapter(componentProperties, componentMonitor, lifecycleStrategy, componentKey, componentImplementation, componentAdapter, parameters); if (componentAdapter != null) { return componentAdapter; } componentAdapter = methodInjectionAdapter(componentProperties, componentMonitor, lifecycleStrategy, componentKey, componentImplementation, componentAdapter, parameters); if (componentAdapter != null) { return componentAdapter; } return defaultInjectionAdapter(componentProperties, componentMonitor, lifecycleStrategy, componentKey, componentImplementation, parameters); } private ComponentAdapter defaultInjectionAdapter(Properties componentProperties, ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Object componentKey, Class componentImplementation, Parameter... parameters) { AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CDI); return new ConstructorInjection().createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } private ComponentAdapter setterInjectionAdapter(Properties componentProperties, ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Object componentKey, Class componentImplementation, ComponentAdapter componentAdapter, Parameter... parameters) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SDI)) { componentAdapter = new SetterInjection().createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } return componentAdapter; } private ComponentAdapter methodInjectionAdapter(Properties componentProperties, ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Object componentKey, Class componentImplementation, ComponentAdapter componentAdapter, Parameter... parameters) { if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.METHOD_INJECTION)) { componentAdapter = new MethodInjection().createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } return componentAdapter; } private ComponentAdapter methodAnnotatedInjectionAdapter(Class componentImplementation, ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, ComponentAdapter componentAdapter, Parameter... parameters) { if (injectionMethodAnnotated(componentImplementation)) { componentAdapter = new AnnotatedMethodInjection().createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } return componentAdapter; } private ComponentAdapter fieldAnnotatedInjectionAdapter(Class componentImplementation, ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, ComponentAdapter componentAdapter, Parameter... parameters) { if (injectionFieldAnnotated(componentImplementation)) { componentAdapter = new AnnotatedFieldInjection().createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } return componentAdapter; } private boolean injectionMethodAnnotated(final Class componentImplementation) { return (Boolean) AccessController.doPrivileged(new PrivilegedAction() { @SuppressWarnings("synthetic-access") public Object run() { return injectionAnnotated(componentImplementation.getDeclaredMethods()); } }); } private boolean injectionFieldAnnotated(final Class componentImplementation) { return (Boolean) AccessController.doPrivileged(new PrivilegedAction() { @SuppressWarnings("synthetic-access") public Object run() { if (componentImplementation.isInterface()) { return false; } Class impl = componentImplementation; while (impl != Object.class) { boolean injAnnotated = injectionAnnotated(impl.getDeclaredFields()); if (injAnnotated) { return true; } impl = impl.getSuperclass(); } return false; } }); } private boolean injectionAnnotated(AccessibleObject[] objects) { for (AccessibleObject object : objects) { if (object.getAnnotation(Inject.class) != null) { return true; } } return false; } } libpicocontainer-java-2.15/org/picocontainer/injectors/AnnotatedFieldInjection.java000066400000000000000000000051121242247644300307260ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import org.picocontainer.annotations.Inject; import java.util.Properties; import java.lang.annotation.Annotation; /** * A {@link org.picocontainer.InjectionFactory} for Guice-style annotated fields. * The factory creates {@link AnnotatedFieldInjector}. * * @author Paul Hammant */ @SuppressWarnings("serial") public class AnnotatedFieldInjection extends AbstractInjectionFactory { private final Class injectionAnnotation; public AnnotatedFieldInjection(Class injectionAnnotation) { this.injectionAnnotation = injectionAnnotation; } public AnnotatedFieldInjection() { this(Inject.class); } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return wrapLifeCycle(monitor.newInjector(new AnnotatedFieldInjector(componentKey, componentImplementation, parameters, monitor, injectionAnnotation, useNames)), lifecycleStrategy); } } libpicocontainer-java-2.15/org/picocontainer/injectors/AnnotatedFieldInjector.java000066400000000000000000000107071242247644300305670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Bind; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Injection happens after instantiation, and through fields marked as injection points via an Annotation. * The default annotation of org.picocontainer.annotations.@Inject can be overridden. */ @SuppressWarnings("serial") public class AnnotatedFieldInjector extends AbstractFieldInjector { private final Class injectionAnnotation; public AnnotatedFieldInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, Class injectionAnnotation, boolean useNames) { super(key, impl, parameters, componentMonitor, useNames); this.injectionAnnotation = injectionAnnotation; } @Override protected void initializeInjectionMembersAndTypeLists() { injectionMembers = new ArrayList(); List bindingIds = new ArrayList(); final List typeList = new ArrayList(); Class drillInto = getComponentImplementation(); while (drillInto != Object.class) { final Field[] fields = getFields(drillInto); for (final Field field : fields) { if (isAnnotatedForInjection(field)) { injectionMembers.add(field); typeList.add(box(field.getType())); bindingIds.add(getBinding(field)); } } drillInto = drillInto.getSuperclass(); } injectionTypes = typeList.toArray(new Type[0]); bindings = bindingIds.toArray(new Annotation[0]); } private Annotation getBinding(Field field) { Annotation[] annotations = field.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(Bind.class)) { return annotation; } } return null; } protected boolean isAnnotatedForInjection(Field field) { return field.getAnnotation(injectionAnnotation) != null; } private Field[] getFields(final Class clazz) { return AccessController.doPrivileged(new PrivilegedAction() { public Field[] run() { return clazz.getDeclaredFields(); } }); } protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException { Field field = (Field) member; field.setAccessible(true); field.set(componentInstance, toInject); return null; } @Override public String getDescriptor() { return "AnnotatedFieldInjector-"; } @Override protected NameBinding makeParameterNameImpl(final AccessibleObject member) { return new NameBinding() { public String getName() { return ((Field) member).getName(); } }; } protected Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance) { return instance; } } libpicocontainer-java-2.15/org/picocontainer/injectors/AnnotatedMethodInjection.java000066400000000000000000000057051242247644300311330ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.annotations.Inject; import java.lang.annotation.Annotation; import java.util.Properties; /** * A {@link org.picocontainer.InjectionFactory} for Guice-style annotated methods. * The factory creates {@link AnnotatedMethodInjector}. * * @author Paul Hammant */ @SuppressWarnings("serial") public class AnnotatedMethodInjection extends AbstractInjectionFactory { private final Class injectionAnnotation; private final boolean useNames; public AnnotatedMethodInjection(Class injectionAnnotation, boolean useNames) { this.injectionAnnotation = injectionAnnotation; this.useNames = useNames; } public AnnotatedMethodInjection() { this(Inject.class, false); } /** * Create a {@link SetterInjector}. * * @param monitor * @param lifecycleStrategy * @param componentProperties * @param componentKey The component's key * @param componentImplementation The class of the bean. * @param parameters Any parameters for the setters. If null the adapter * solves the dependencies for all setters internally. Otherwise * the number parameters must match the number of the setter. * @return Returns a new {@link SetterInjector}. * @throws org.picocontainer.PicoCompositionException if dependencies cannot * be solved or if the implementation is an interface or an * abstract class. */ public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { return wrapLifeCycle(monitor.newInjector(new AnnotatedMethodInjector(componentKey, componentImplementation, parameters, monitor, injectionAnnotation, useNames)), lifecycleStrategy); } }libpicocontainer-java-2.15/org/picocontainer/injectors/AnnotatedMethodInjector.java000066400000000000000000000041501242247644300307570ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @SuppressWarnings("serial") public class AnnotatedMethodInjector extends SetterInjector { private final Class injectionAnnotation; public AnnotatedMethodInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor, Class injectionAnnotation, boolean useNames) { super(key, impl, parameters, monitor, "", "", false, useNames); this.injectionAnnotation = injectionAnnotation; } @Override protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException { return ((Method)member).invoke(componentInstance, toInject); } @Override protected final boolean isInjectorMethod(Method method) { return method.getAnnotation(injectionAnnotation) != null; } @Override public String getDescriptor() { return "MethodInjection"; } } libpicocontainer-java-2.15/org/picocontainer/injectors/CompositeInjection.java000066400000000000000000000054611242247644300300160ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.InjectionFactory; import org.picocontainer.Injector; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * A Composite of other types on InjectionFactories - pass them into the varargs constructor. * * @author Paul Hammant */ @SuppressWarnings("serial") public class CompositeInjection extends AbstractInjectionFactory { private final InjectionFactory[] injectionFactories; public CompositeInjection(InjectionFactory... injectionFactories) { this.injectionFactories = injectionFactories; } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { Injector[] injectors = new Injector[injectionFactories.length]; for (int i = 0; i < injectionFactories.length; i++) { InjectionFactory injectionFactory = injectionFactories[i]; ComponentAdapter adapter = injectionFactory.createComponentAdapter(monitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); injectors[i] = (Injector) adapter; } boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return wrapLifeCycle(monitor.newInjector(new CompositeInjector(componentKey, componentImplementation, parameters, monitor, useNames, injectors)), lifecycleStrategy); } }libpicocontainer-java-2.15/org/picocontainer/injectors/CompositeInjector.java000066400000000000000000000062611242247644300276500ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.Injector; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import java.lang.reflect.Type; @SuppressWarnings("serial") public class CompositeInjector extends AbstractInjector { private final Injector[] injectors; public CompositeInjector(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames, Injector... injectors) { super(componentKey, componentImplementation, parameters, monitor, useNames); this.injectors = injectors; } @Override public T getComponentInstance(PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, NOTHING.class); } @Override public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { T instance = null; for (Injector injector : injectors) { if (instance == null) { instance = injector.getComponentInstance(container, NOTHING.class); } else { injector.decorateComponentInstance(container, into, instance); } } return (T) instance; } /** * @return the object returned is the result of the last of the injectors delegated to */ @Override public Object decorateComponentInstance(PicoContainer container, Type into, T instance) { Object result = null; for (Injector injector : injectors) { result = injector.decorateComponentInstance(container, into, instance); } return result; } @Override public void verify(PicoContainer container) throws PicoCompositionException { for (Injector injector : injectors) { injector.verify(container); } } @Override public final void accept(PicoVisitor visitor) { super.accept(visitor); for (Injector injector : injectors) { injector.accept(visitor); } } @Override public String getDescriptor() { StringBuilder sb = new StringBuilder("CompositeInjector("); for (Injector injector : injectors) { sb.append(injector.getDescriptor()); } sb.deleteCharAt(sb.length()-1); // remove last dash return sb.toString().replace("-", "+") + ")-"; } } libpicocontainer-java-2.15/org/picocontainer/injectors/ConstructorInjection.java000066400000000000000000000056741242247644300304070ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import java.util.Properties; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehaviorFactory; /** * A {@link org.picocontainer.InjectionFactory} for constructor injection. * The factory creates {@link ConstructorInjector}. * * If there is more than one constructor for the component, the one with the * most satisfiable parameters will be used. By default, the choice of * constructor for the component in question will be remembered between usages. * * @author Paul Hammant * @author Jon Tirsén */ @SuppressWarnings("serial") public class ConstructorInjection extends AbstractInjectionFactory { private final boolean rememberChosenConstructor; /** * * @param rememberChosenConstructor whether 'which constructor?' should be remembered * from use to use for the associated injector. */ public ConstructorInjection(boolean rememberChosenConstructor) { this.rememberChosenConstructor = rememberChosenConstructor; } /** * Will remember which constructor to use between usages on the associated * Injector. */ public ConstructorInjection() { this(true); } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties properties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(properties, Characteristics.USE_NAMES, true); ConstructorInjector injector = new ConstructorInjector(componentKey, componentImplementation, parameters, monitor, useNames, rememberChosenConstructor); injector.enableEmjection(AbstractBehaviorFactory.removePropertiesIfPresent(properties, Characteristics.EMJECTION_ENABLED)); return wrapLifeCycle(monitor.newInjector(injector), lifecycleStrategy); } } libpicocontainer-java-2.15/org/picocontainer/injectors/ConstructorInjector.java000066400000000000000000000530451242247644300302350ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.Emjection; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.monitors.NullComponentMonitor; import java.lang.annotation.Annotation; 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.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * Injection will happen through a constructor for the component. * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén * @author Zohar Melamed * @author Jörg Schaible * @author Mauro Talevi */ @SuppressWarnings("serial") public class ConstructorInjector extends SingleMemberInjector { private transient List> sortedMatchingConstructors; private transient ThreadLocalCyclicDependencyGuard instantiationGuard; private boolean rememberChosenConstructor = true; private transient CtorAndAdapters chosenConstructor; private boolean enableEmjection = false; private boolean allowNonPublicClasses = false; /** * Constructor injector that uses no monitor and no lifecycle adapter. This is a more * convenient constructor for use when instantiating a constructor injector directly. * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters used for initialization */ public ConstructorInjector(final Object componentKey, final Class componentImplementation, Parameter... parameters) { this(componentKey, componentImplementation, parameters, new NullComponentMonitor(), false); } /** * Creates a ConstructorInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public ConstructorInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); } /** * Creates a ConstructorInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param rememberChosenCtor remember the chosen constructor (to speed up second/subsequent calls) * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public ConstructorInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames, boolean rememberChosenCtor) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); this.rememberChosenConstructor = rememberChosenCtor; } private CtorAndAdapters getGreediestSatisfiableConstructor(PicoContainer guardedContainer, @SuppressWarnings("unused") Class componentImplementation) { CtorAndAdapters ctor = null; if (chosenConstructor == null) { ctor = getGreediestSatisfiableConstructor(guardedContainer); } if (rememberChosenConstructor) { if (chosenConstructor == null) { chosenConstructor = ctor; } else { ctor = chosenConstructor; } } return ctor; } @SuppressWarnings("synthetic-access") protected CtorAndAdapters getGreediestSatisfiableConstructor(PicoContainer container) throws PicoCompositionException { final Set conflicts = new HashSet(); final Set unsatisfiableDependencyTypes = new HashSet(); final Map resolvers = new HashMap(); if (sortedMatchingConstructors == null) { sortedMatchingConstructors = getSortedMatchingConstructors(); } Constructor greediestConstructor = null; Parameter[] greediestConstructorsParameters = null; ComponentAdapter[] greediestConstructorsParametersComponentAdapters = null; int lastSatisfiableConstructorSize = -1; Type unsatisfiedDependency = null; Constructor unsatisfiedConstructor = null; for (final Constructor sortedMatchingConstructor : sortedMatchingConstructors) { try { boolean failedDependency = false; Type[] parameterTypes = sortedMatchingConstructor.getGenericParameterTypes(); fixGenericParameterTypes(sortedMatchingConstructor, parameterTypes); Annotation[] bindings = getBindings(sortedMatchingConstructor.getParameterAnnotations()); final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes.length); final ComponentAdapter[] currentAdapters = new ComponentAdapter[currentParameters.length]; // remember: all constructors with less arguments than the given parameters are filtered out already for (int j = 0; j < currentParameters.length; j++) { // check whether this constructor is satisfiable Type expectedType = box(parameterTypes[j]); NameBinding expectedNameBinding = new ParameterNameBinding(getParanamer(), sortedMatchingConstructor, j); ResolverKey resolverKey = new ResolverKey(expectedType, useNames() ? expectedNameBinding.getName() : null, useNames(), bindings[j], currentParameters[j]); Parameter.Resolver resolver = resolvers.get(resolverKey); if (resolver == null) { resolver = currentParameters[j].resolve(container, this, null, expectedType, expectedNameBinding, useNames(), bindings[j]); resolvers.put(resolverKey, resolver); } if (resolver.isResolved()) { currentAdapters[j] = resolver.getComponentAdapter(); continue; } unsatisfiableDependencyTypes.add(expectedType); unsatisfiedDependency = box(parameterTypes[j]); unsatisfiedConstructor = sortedMatchingConstructor; failedDependency = true; } if (greediestConstructor != null && parameterTypes.length != lastSatisfiableConstructorSize) { if (conflicts.isEmpty()) { // we found our match [aka. greedy and satisfied] return new CtorAndAdapters(greediestConstructor, greediestConstructorsParameters, greediestConstructorsParametersComponentAdapters); } // fits although not greedy conflicts.add(sortedMatchingConstructor); } else if (!failedDependency && lastSatisfiableConstructorSize == parameterTypes.length) { // satisfied and same size as previous one? conflicts.add(sortedMatchingConstructor); conflicts.add(greediestConstructor); } else if (!failedDependency) { greediestConstructor = sortedMatchingConstructor; greediestConstructorsParameters = currentParameters; greediestConstructorsParametersComponentAdapters = currentAdapters; lastSatisfiableConstructorSize = parameterTypes.length; } } catch (AmbiguousComponentResolutionException e) { // embellish with the constructor being injected into. e.setMember(sortedMatchingConstructor); throw e; } } if (!conflicts.isEmpty()) { throw new PicoCompositionException(conflicts.size() + " satisfiable constructors is too many for '"+getComponentImplementation()+"'. Constructor List:" + conflicts.toString().replace(getComponentImplementation().getName(),"").replace("public nonMatching = new HashSet(); for (Constructor constructor : getConstructors()) { nonMatching.add(constructor); } throw new PicoCompositionException("Either the specified parameters do not match any of the following constructors: " + nonMatching.toString() + "; OR the constructors were not accessible for '" + getComponentImplementation().getName() + "'"); } return new CtorAndAdapters(greediestConstructor, greediestConstructorsParameters, greediestConstructorsParametersComponentAdapters); } private String toList(Set unsatisfiableDependencyTypes) { StringBuilder sb = new StringBuilder(); Iterator it = unsatisfiableDependencyTypes.iterator(); while (it.hasNext()) { Type next = it.next(); sb.append(next.toString().replace("class ", "")); sb.append(", "); } String s = sb.toString(); return s.substring(0, s.lastIndexOf(", ")); } public void enableEmjection(boolean enableEmjection) { this.enableEmjection = enableEmjection; } public ConstructorInjector withNonPublicConstructors() { allowNonPublicClasses = true; return this; } private static final class ResolverKey { private final Type expectedType; private final String pName; private final boolean useNames; private final Annotation binding; private final Parameter currentParameter; private ResolverKey(Type expectedType, String pName, boolean useNames, Annotation binding, Parameter currentParameter) { this.expectedType = expectedType; this.pName = pName; this.useNames = useNames; this.binding = binding; this.currentParameter = currentParameter; } // Generated by IDEA @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ResolverKey that = (ResolverKey) o; if (useNames != that.useNames) return false; if (binding != null ? !binding.equals(that.binding) : that.binding != null) return false; if (!currentParameter.equals(that.currentParameter)) return false; if (!expectedType.equals(that.expectedType)) return false; if (pName != null ? !pName.equals(that.pName) : that.pName != null) return false; return true; } @Override public int hashCode() { int result; result = expectedType.hashCode(); result = 31 * result + (pName != null ? pName.hashCode() : 0); result = 31 * result + (useNames ? 1 : 0); result = 31 * result + (binding != null ? binding.hashCode() : 0); result = 31 * result + currentParameter.hashCode(); return result; } } private void fixGenericParameterTypes(Constructor ctor, Type[] parameterTypes) { for (int i = 0; i < parameterTypes.length; i++) { Type parameterType = parameterTypes[i]; if (parameterType instanceof TypeVariable) { parameterTypes[i] = ctor.getParameterTypes()[i]; } } } protected class CtorAndAdapters { private final Constructor ctor; private final Parameter[] constructorParameters; private final ComponentAdapter[] injecteeAdapters; public CtorAndAdapters(Constructor ctor, Parameter[] parameters, ComponentAdapter[] injecteeAdapters) { this.ctor = ctor; this.constructorParameters = parameters; this.injecteeAdapters = injecteeAdapters; } public Constructor getConstructor() { return ctor; } public Object[] getParameterArguments(PicoContainer container) { Type[] parameterTypes = ctor.getGenericParameterTypes(); // as per fixParameterType() for (int i = 0; i < parameterTypes.length; i++) { Type parameterType = parameterTypes[i]; if (parameterType instanceof TypeVariable) { parameterTypes[i] = ctor.getParameterTypes()[i]; } } boxParameters(parameterTypes); Object[] result = new Object[constructorParameters.length]; Annotation[] bindings = getBindings(ctor.getParameterAnnotations()); for (int i = 0; i < constructorParameters.length; i++) { result[i] = getParameter(container, ctor, i, parameterTypes[i], bindings[i], constructorParameters[i], injecteeAdapters[i]); } return result; } public ComponentAdapter[] getInjecteeAdapters() { return injecteeAdapters; } public Parameter[] getParameters() { return constructorParameters; } } @Override public T getComponentInstance(final PicoContainer container, @SuppressWarnings("unused") Type into) throws PicoCompositionException { if (instantiationGuard == null) { instantiationGuard = new ThreadLocalCyclicDependencyGuard() { @Override @SuppressWarnings("synthetic-access") public T run(Object instance) { CtorAndAdapters ctorAndAdapters = getGreediestSatisfiableConstructor(guardedContainer, getComponentImplementation()); ComponentMonitor componentMonitor = currentMonitor(); Constructor ctor = ctorAndAdapters.getConstructor(); try { Object[] ctorParameters = ctorAndAdapters.getParameterArguments(guardedContainer); ctor = componentMonitor.instantiating(container, ConstructorInjector.this, ctor); if(ctorAndAdapters == null) { throw new NullPointerException("Component Monitor " + componentMonitor + " returned a null constructor from method 'instantiating' after passing in " + ctorAndAdapters); } long startTime = System.currentTimeMillis(); T inst = newInstance(ctor, ctorParameters); componentMonitor.instantiated(container, ConstructorInjector.this, ctor, inst, ctorParameters, System.currentTimeMillis() - startTime); return inst; } catch (InvocationTargetException e) { componentMonitor.instantiationFailed(container, ConstructorInjector.this, ctor, e); if (e.getTargetException() instanceof RuntimeException) { throw (RuntimeException) e.getTargetException(); } else if (e.getTargetException() instanceof Error) { throw (Error) e.getTargetException(); } throw new PicoCompositionException(e.getTargetException()); } catch (InstantiationException e) { return caughtInstantiationException(componentMonitor, ctor, e, container); } catch (IllegalAccessException e) { return caughtIllegalAccessException(componentMonitor, ctor, e, container); } } }; } instantiationGuard.setGuardedContainer(container); T inst = instantiationGuard.observe(getComponentImplementation(), null); decorate(inst, container); return inst; } private void decorate(T inst, PicoContainer container) { if (enableEmjection) { Emjection.setupEmjection(inst, container); } } private List> getSortedMatchingConstructors() { List> matchingConstructors = new ArrayList>(); Constructor[] allConstructors = getConstructors(); // filter out all constructors that will definately not match for (Constructor constructor : allConstructors) { int modifiers = constructor.getModifiers(); if ((parameters == null || constructor.getParameterTypes().length == parameters.length) && (allowNonPublicClasses || (modifiers & Modifier.PUBLIC) != 0)) { if ((modifiers & Modifier.PUBLIC) == 0) { constructor.setAccessible(true); } matchingConstructors.add(constructor); } } // optimize list of constructors moving the longest at the beginning if (parameters == null) { Collections.sort(matchingConstructors, new Comparator() { public int compare(Constructor arg0, Constructor arg1) { return arg1.getParameterTypes().length - arg0.getParameterTypes().length; } }); } return matchingConstructors; } private Constructor[] getConstructors() { return AccessController.doPrivileged(new PrivilegedAction[]>() { public Constructor[] run() { return (Constructor[]) getComponentImplementation().getDeclaredConstructors(); } }); } @Override public void verify(final PicoContainer container) throws PicoCompositionException { if (verifyingGuard == null) { verifyingGuard = new ThreadLocalCyclicDependencyGuard() { @Override public Object run(Object instance) { final Constructor constructor = getGreediestSatisfiableConstructor(guardedContainer).getConstructor(); final Class[] parameterTypes = constructor.getParameterTypes(); final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes.length); for (int i = 0; i < currentParameters.length; i++) { currentParameters[i].verify(container, ConstructorInjector.this, box(parameterTypes[i]), new ParameterNameBinding(getParanamer(), constructor, i), useNames(), getBindings(constructor.getParameterAnnotations())[i]); } return null; } }; } verifyingGuard.setGuardedContainer(container); verifyingGuard.observe(getComponentImplementation(), null); } @Override public String getDescriptor() { return "ConstructorInjector-"; } } libpicocontainer-java-2.15/org/picocontainer/injectors/FactoryInjector.java000066400000000000000000000131371242247644300273150ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Injector; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** *

      * An Injector which provides an custom instance in a factory style *

      * * @author Paul Hammant */ public abstract class FactoryInjector implements Injector { private Class key; public FactoryInjector() throws PicoCompositionException { key = getTypeArguments(FactoryInjector.class, getClass()).get(0); if (key == null) { key = CantWorkItOut.class; } } public FactoryInjector(Class key) { this.key = key; } // from http://www.artima.com/weblogs/viewpost.jsp?thread=208860 public static Class getClass(Type type) { if (type instanceof Class) { return (Class) type; } else if (type instanceof ParameterizedType) { return getClass(((ParameterizedType) type).getRawType()); } else if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType) type).getGenericComponentType(); Class componentClass = getClass(componentType); if (componentClass != null) { return Array.newInstance(componentClass, 0).getClass(); } else { return null; } } else { return null; } } /** * Get the actual type arguments a child class has used to extend a generic base class. * * @param class1 the base class * @param class2 the child class * @return a list of the raw classes for the actual type arguments. */ public static List> getTypeArguments( Class class1, Class class2) { Map resolvedTypes = new HashMap(); Type type = class2; // start walking up the inheritance hierarchy until we hit baseClass while (! getClass(type).equals(class1)) { if (type instanceof Class) { // there is no useful information for us in raw types, so just keep going. type = ((Class) type).getGenericSuperclass(); } else { ParameterizedType parameterizedType = (ParameterizedType) type; Class rawType = (Class) parameterizedType.getRawType(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); TypeVariable[] typeParameters = rawType.getTypeParameters(); for (int i = 0; i < actualTypeArguments.length; i++) { resolvedTypes.put(typeParameters[i], actualTypeArguments[i]); } if (!rawType.equals(class1)) { type = rawType.getGenericSuperclass(); } } } // finally, for each actual type argument provided to baseClass, determine (if possible) // the raw class for that type argument. Type[] actualTypeArguments; if (type instanceof Class) { actualTypeArguments = ((Class) type).getTypeParameters(); } else { actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); } List> typeArgumentsAsClasses = new ArrayList>(); // resolve types by chasing down type variables. for (Type baseType: actualTypeArguments) { while (resolvedTypes.containsKey(baseType)) { baseType = resolvedTypes.get(baseType); } typeArgumentsAsClasses.add(getClass(baseType)); } return typeArgumentsAsClasses; } public Object getComponentKey() { return key; } public Class getComponentImplementation() { return key; } public void accept(PicoVisitor visitor) { visitor.visitComponentAdapter(this); } public ComponentAdapter getDelegate() { return null; } public U findAdapterOfType(Class adapterType) { return null; } public T getComponentInstance(PicoContainer container) { throw new UnsupportedOperationException(); } public abstract T getComponentInstance(PicoContainer container, Type into); public Object decorateComponentInstance(PicoContainer container, Type into, T instance) { return null; } public void verify(PicoContainer container) { } public String getDescriptor() { return "FactoryInjector-"; } public void start(PicoContainer container) { } public void stop(PicoContainer container) { } public void dispose(PicoContainer container) { } public boolean componentHasLifecycle() { return false; } public static class CantWorkItOut { private CantWorkItOut() { } } }libpicocontainer-java-2.15/org/picocontainer/injectors/ForgetfulConstructorInjection.java000066400000000000000000000017321242247644300322540ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; /** * Constructor Injection where 'which constructor?' is re-calculated each time an * instance is asked to construct a component. */ @SuppressWarnings("serial") public class ForgetfulConstructorInjection extends ConstructorInjection { public ForgetfulConstructorInjection() { super(false); } } libpicocontainer-java-2.15/org/picocontainer/injectors/InjectInto.java000066400000000000000000000022361242247644300262540ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import java.lang.reflect.Type; public class InjectInto implements Type { private Type intoType; private Object intoKey; public InjectInto(Type intoType, Object intoKey) { this.intoType = intoType; this.intoKey = intoKey; } public Type getIntoType() { return intoType; } // at FactoryInjector implementor's risk public Class getIntoClass() { return (Class) getIntoType(); } public Object getIntoKey() { return intoKey; } } libpicocontainer-java-2.15/org/picocontainer/injectors/Injector.java000066400000000000000000000242371242247644300257700ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; /** * convenience class providing static methods to conveniently create injectors * ( like org.junit.Assert ) * * @author Konstantin Pribluda */ public class Injector { /** * Constructor injector that uses no monitor and no lifecycle adapter. This is a more * convenient constructor for use when instantiating a constructor injector directly. * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters used for initialization */ public static ComponentAdapter constructor(final Object componentKey, final Class componentImplementation, Parameter... parameters) { return new ConstructorInjector(componentKey, componentImplementation, parameters); } /** * Creates a ConstructorInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public static ComponentAdapter constructor(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException { return new ConstructorInjector(componentKey, componentImplementation, parameters, monitor, useNames); } /** * Creates a ConstructorInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param rememberChosenCtor remember the chosen constructor (to speed up second/subsequent calls) * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public static ComponentAdapter constructor(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames, boolean rememberChosenCtor) throws AbstractInjector.NotConcreteRegistrationException { return new ConstructorInjector(componentKey, componentImplementation, parameters, monitor, useNames, rememberChosenCtor); } /** * Convenience method to create annotated field injector * * @param key * @param impl * @param parameters * @param componentMonitor * @param injectionAnnotation * @param useNames * @return annotated field injector instance. */ public static ComponentAdapter annotatedField(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, Class injectionAnnotation, boolean useNames) { return componentMonitor.newInjector(new AnnotatedFieldInjector(key, impl, parameters, componentMonitor, injectionAnnotation, useNames)); } /** * convenience method to create annotated method injector * * @param key * @param impl * @param parameters * @param monitor * @param injectionAnnotation * @param useNames * @return method injector instance. */ public static ComponentAdapter annotatedMethod(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor, Class injectionAnnotation, boolean useNames) { return monitor.newInjector(new AnnotatedMethodInjector(key, impl, parameters, monitor, injectionAnnotation, useNames)); } /** * creates composite injector * * @param componentKey * @param componentImplementation * @param parameters * @param monitor * @param useNames * @param injectors * @return composite injector instance. */ public static ComponentAdapter composite(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames, org.picocontainer.Injector... injectors) { return monitor.newInjector(new CompositeInjector(componentKey, componentImplementation, parameters, monitor, useNames, injectors)); } /** * convenience method to create method injector * * @param componentKey * @param componentImplementation * @param parameters * @param monitor * @param methodName * @param useNames * @return method injector instance. * @throws AbstractInjector.NotConcreteRegistrationException * */ public static ComponentAdapter method(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, String methodName, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException { return monitor.newInjector(new MethodInjector.ByMethodName(componentKey, componentImplementation, parameters, monitor, new HashSet(Arrays.asList(methodName)), useNames)); } /** * convenience method to create multi component adapter * * @param componentKey * @param componentImplementation * @param parameters * @param componentMonitor * @param setterPrefix * @param useNames * @return MultiInjector component adapter instance. */ public static ComponentAdapter multi(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor componentMonitor, String setterPrefix, boolean useNames) { return componentMonitor.newInjector(new MultiInjector(componentKey, componentImplementation, parameters, componentMonitor, setterPrefix, useNames)); } /** * convenience method to create named field injector * * @param key * @param impl * @param parameters * @param componentMonitor * @param fieldNames * @return named field component injector instance. */ public static ComponentAdapter namedField(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, String fieldNames) { return componentMonitor.newInjector(new NamedFieldInjector(key, impl, parameters, componentMonitor, fieldNames)); } /** * convenience method to create setter injector * * @param componentKey * @param componentImplementation * @param parameters * @param monitor * @param prefix * @param useNames * @return setter injector instance. * @throws AbstractInjector.NotConcreteRegistrationException * */ public static ComponentAdapter setter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, String prefix, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException { return monitor.newInjector(new SetterInjector(componentKey, componentImplementation, parameters, monitor, prefix, "", false, useNames)); } /** * conveniently create typed field injector * * @param key * @param impl * @param parameters * @param componentMonitor * @param classNames * @return typed field injector instance. */ public static ComponentAdapter typedField(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, String classNames) { return componentMonitor.newInjector(new TypedFieldInjector(key, impl, parameters, componentMonitor, classNames)); } } libpicocontainer-java-2.15/org/picocontainer/injectors/Injectors.java000066400000000000000000000037451242247644300261540ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.InjectionFactory; import java.lang.annotation.Annotation; public class Injectors { public static InjectionFactory adaptiveDI() { return new AdaptingInjection(); } public static InjectionFactory SDI() { return new SetterInjection(); } public static InjectionFactory CDI() { return new ConstructorInjection(); } public static InjectionFactory namedMethod() { return new NamedMethodInjection(); } public static InjectionFactory namedField() { return new NamedFieldInjection(); } public static InjectionFactory annotatedMethodDI(Class injectionAnnotation) { return new AnnotatedMethodInjection(injectionAnnotation, false); } public static InjectionFactory annotatedMethodDI() { return new AnnotatedMethodInjection(); } public static InjectionFactory annotatedFieldDI(Class injectionAnnotation) { return new AnnotatedFieldInjection(injectionAnnotation); } public static InjectionFactory annotatedFieldDI() { return new AnnotatedFieldInjection(); } public static InjectionFactory typedFieldDI() { return new TypedFieldInjection(); } } libpicocontainer-java-2.15/org/picocontainer/injectors/IterativeInjector.java000066400000000000000000000401721242247644300276410ustar00rootroot00000000000000package org.picocontainer.injectors; import com.thoughtworks.paranamer.AdaptiveParanamer; import com.thoughtworks.paranamer.AnnotationParanamer; import com.thoughtworks.paranamer.CachingParanamer; import com.thoughtworks.paranamer.Paranamer; import org.picocontainer.ComponentMonitor; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Bind; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Injection will happen iteratively after component instantiation */ public abstract class IterativeInjector extends AbstractInjector { private static final Object[] NONE = new Object[0]; private transient ThreadLocalCyclicDependencyGuard instantiationGuard; protected transient List injectionMembers; protected transient Type[] injectionTypes; protected transient Annotation[] bindings; private transient Paranamer paranamer; private transient volatile boolean initialized; /** * Constructs a IterativeInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public IterativeInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); } protected Constructor getConstructor() { Object retVal = AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { return getComponentImplementation().getConstructor((Class[])null); } catch (NoSuchMethodException e) { return new PicoCompositionException(e); } catch (SecurityException e) { return new PicoCompositionException(e); } } }); if (retVal instanceof Constructor) { return (Constructor) retVal; } else { throw (PicoCompositionException) retVal; } } private Parameter[] getMatchingParameterListForSetters(PicoContainer container) throws PicoCompositionException { if (initialized == false) { synchronized (this) { if (initialized == false) { initializeInjectionMembersAndTypeLists(); } } } final List matchingParameterList = new ArrayList(Collections.nCopies(injectionMembers.size(), null)); final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(injectionTypes.length); final Set nonMatchingParameterPositions = matchParameters(container, matchingParameterList, currentParameters); final Set unsatisfiableDependencyTypes = new HashSet(); final List unsatisfiableDependencyMembers = new ArrayList(); for (int i = 0; i < matchingParameterList.size(); i++) { if (matchingParameterList.get(i) == null) { unsatisfiableDependencyTypes.add(injectionTypes[i]); unsatisfiableDependencyMembers.add(injectionMembers.get(i)); } } if (unsatisfiableDependencyTypes.size() > 0) { unsatisfiedDependencies(container, unsatisfiableDependencyTypes, unsatisfiableDependencyMembers); } else if (nonMatchingParameterPositions.size() > 0) { throw new PicoCompositionException("Following parameters do not match any of the injectionMembers for " + getComponentImplementation() + ": " + nonMatchingParameterPositions.toString()); } return matchingParameterList.toArray(new Parameter[matchingParameterList.size()]); } private Set matchParameters(PicoContainer container, List matchingParameterList, Parameter[] currentParameters) { Set unmatchedParameters = new HashSet(); for (int i = 0; i < currentParameters.length; i++) { if (!matchParameter(container, matchingParameterList, currentParameters[i])) { unmatchedParameters.add(i); } } return unmatchedParameters; } private boolean matchParameter(PicoContainer container, List matchingParameterList, Parameter parameter) { for (int j = 0; j < injectionTypes.length; j++) { Object o = matchingParameterList.get(j); try { if (o == null && parameter.resolve(container, this, null, injectionTypes[j], makeParameterNameImpl(injectionMembers.get(j)), useNames(), bindings[j]).isResolved()) { matchingParameterList.set(j, parameter); return true; } } catch (AmbiguousComponentResolutionException e) { e.setMember(injectionMembers.get(j)); throw e; } } return false; } protected NameBinding makeParameterNameImpl(AccessibleObject member) { if (paranamer == null) { paranamer = new CachingParanamer(new AnnotationParanamer(new AdaptiveParanamer())); } return new ParameterNameBinding(paranamer, member, 0); } protected abstract void unsatisfiedDependencies(PicoContainer container, Set unsatisfiableDependencyTypes, List unsatisfiableDependencyMembers); public T getComponentInstance(final PicoContainer container, Type into) throws PicoCompositionException { final Constructor constructor = getConstructor(); if (instantiationGuard == null) { instantiationGuard = new ThreadLocalCyclicDependencyGuard() { public Object run(Object instance) { final Parameter[] matchingParameters = getMatchingParameterListForSetters(guardedContainer); Object componentInstance = makeInstance(container, constructor, currentMonitor()); return decorateComponentInstance(matchingParameters, currentMonitor(), componentInstance, container, guardedContainer); } }; } instantiationGuard.setGuardedContainer(container); return (T) instantiationGuard.observe(getComponentImplementation(), null); } private Object decorateComponentInstance(Parameter[] matchingParameters, ComponentMonitor componentMonitor, Object componentInstance, PicoContainer container, PicoContainer guardedContainer) { AccessibleObject member = null; Object injected[] = new Object[injectionMembers.size()]; Object lastReturn = null; try { for (int i = 0; i < injectionMembers.size(); i++) { member = injectionMembers.get(i); if (matchingParameters[i] != null) { Object toInject = matchingParameters[i].resolve(guardedContainer, this, null, injectionTypes[i], makeParameterNameImpl(injectionMembers.get(i)), useNames(), bindings[i]).resolveInstance(); Object rv = componentMonitor.invoking(container, this, (Member) member, componentInstance, new Object[] {toInject}); if (rv == ComponentMonitor.KEEP) { long str = System.currentTimeMillis(); lastReturn = injectIntoMember(member, componentInstance, toInject); componentMonitor.invoked(container, this, (Member) member, componentInstance, System.currentTimeMillis() - str, new Object[] {toInject}, lastReturn); } else { lastReturn = rv; } injected[i] = toInject; } } return memberInvocationReturn(lastReturn, member, componentInstance); } catch (InvocationTargetException e) { return caughtInvocationTargetException(componentMonitor, (Member) member, componentInstance, e); } catch (IllegalAccessException e) { return caughtIllegalAccessException(componentMonitor, (Member) member, componentInstance, e); } } protected abstract Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance); private Object makeInstance(PicoContainer container, Constructor constructor, ComponentMonitor componentMonitor) { long startTime = System.currentTimeMillis(); Constructor constructorToUse = componentMonitor.instantiating(container, IterativeInjector.this, constructor); Object componentInstance; try { componentInstance = newInstance(constructorToUse, null); } catch (InvocationTargetException e) { componentMonitor.instantiationFailed(container, IterativeInjector.this, constructorToUse, e); if (e.getTargetException() instanceof RuntimeException) { throw (RuntimeException)e.getTargetException(); } else if (e.getTargetException() instanceof Error) { throw (Error)e.getTargetException(); } throw new PicoCompositionException(e.getTargetException()); } catch (InstantiationException e) { return caughtInstantiationException(componentMonitor, constructor, e, container); } catch (IllegalAccessException e) { return caughtIllegalAccessException(componentMonitor, constructor, e, container); } componentMonitor.instantiated(container, IterativeInjector.this, constructorToUse, componentInstance, NONE, System.currentTimeMillis() - startTime); return componentInstance; } @Override public Object decorateComponentInstance(final PicoContainer container, Type into, final T instance) { if (instantiationGuard == null) { instantiationGuard = new ThreadLocalCyclicDependencyGuard() { public Object run(Object inst) { final Parameter[] matchingParameters = getMatchingParameterListForSetters(guardedContainer); return decorateComponentInstance(matchingParameters, currentMonitor(), inst, container, guardedContainer); } }; } instantiationGuard.setGuardedContainer(container); return instantiationGuard.observe(getComponentImplementation(), instance); } protected abstract Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException; @Override public void verify(final PicoContainer container) throws PicoCompositionException { if (verifyingGuard == null) { verifyingGuard = new ThreadLocalCyclicDependencyGuard() { public Object run(Object instance) { final Parameter[] currentParameters = getMatchingParameterListForSetters(guardedContainer); for (int i = 0; i < currentParameters.length; i++) { currentParameters[i].verify(container, IterativeInjector.this, injectionTypes[i], makeParameterNameImpl(injectionMembers.get(i)), useNames(), bindings[i]); } return null; } }; } verifyingGuard.setGuardedContainer(container); verifyingGuard.observe(getComponentImplementation(), null); } protected void initializeInjectionMembersAndTypeLists() { injectionMembers = new ArrayList(); Set injectionMemberNames = new HashSet(); List bingingIds = new ArrayList(); final List nameList = new ArrayList(); final List typeList = new ArrayList(); final Method[] methods = getMethods(); for (final Method method : methods) { final Type[] parameterTypes = method.getGenericParameterTypes(); fixGenericParameterTypes(method, parameterTypes); String methodSignature = crudeMethodSignature(method); // We're only interested if there is only one parameter ... if (parameterTypes.length == 1) { boolean isInjector = isInjectorMethod(method); // ... and the method name is bean-style. // We're also not interested in dupes from parent classes (not all JDK impls) if (isInjector && !injectionMemberNames.contains(methodSignature)) { injectionMembers.add(method); injectionMemberNames.add(methodSignature); nameList.add(getName(method)); typeList.add(box(parameterTypes[0])); bingingIds.add(getBindings(method, 0)); } } } injectionTypes = typeList.toArray(new Type[0]); bindings = bingingIds.toArray(new Annotation[0]); initialized = true; } public static String crudeMethodSignature(Method method) { StringBuilder sb = new StringBuilder(); sb.append(method.getReturnType().getName()); sb.append(method.getName()); for (Class pType : method.getParameterTypes()) { sb.append(pType.getName()); } return sb.toString(); } protected String getName(Method method) { return null; } private void fixGenericParameterTypes(Method method, Type[] parameterTypes) { for (int i = 0; i < parameterTypes.length; i++) { Type parameterType = parameterTypes[i]; if (parameterType instanceof TypeVariable) { parameterTypes[i] = method.getParameterTypes()[i]; } } } private Annotation getBindings(Method method, int i) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); if (parameterAnnotations.length >= i +1 ) { Annotation[] o = parameterAnnotations[i]; for (Annotation annotation : o) { if (annotation.annotationType().getAnnotation(Bind.class) != null) { return annotation; } } return null; } //TODO - what's this ? if (parameterAnnotations != null) { //return ((Bind) method.getAnnotation(Bind.class)).id(); } return null; } protected boolean isInjectorMethod(Method method) { return false; } private Method[] getMethods() { return (Method[]) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return getComponentImplementation().getMethods(); } }); } } libpicocontainer-java-2.15/org/picocontainer/injectors/MethodInjection.java000066400000000000000000000111621242247644300272670ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Properties; import java.util.Set; /** * A {@link org.picocontainer.InjectionFactory} for methods. * The factory creates {@link MethodInjector}. * * @author Paul Hammant */ @SuppressWarnings("serial") public class MethodInjection extends AbstractInjectionFactory { private final AbstractInjectionFactory delegate; public MethodInjection(String injectionMethodName) { delegate = new MethodInjectionByName(injectionMethodName); } public MethodInjection(String... injectionMethodNames) { delegate = new MethodInjectionByName(injectionMethodNames); } public MethodInjection() { this("inject"); } public MethodInjection(Method injectionMethod) { delegate = new MethodInjectionByReflectionMethod(injectionMethod); } public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { return delegate.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); } public class MethodInjectionByName extends AbstractInjectionFactory { private final Set injectionMethodNames = new HashSet(); public MethodInjectionByName(String... injectionMethodNames) { for (String injectionMethodName : injectionMethodNames) { this.injectionMethodNames.add(injectionMethodName); } } public MethodInjectionByName(String injectionMethodName) { this.injectionMethodNames.add(injectionMethodName); } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return wrapLifeCycle(new MethodInjector.ByMethodName(componentKey, componentImplementation, parameters, monitor, injectionMethodNames, useNames), lifecycleStrategy); } } public class MethodInjectionByReflectionMethod extends AbstractInjectionFactory { private final Method injectionMethod; public MethodInjectionByReflectionMethod(Method injectionMethod) { this.injectionMethod = injectionMethod; } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); if (injectionMethod.getDeclaringClass().isAssignableFrom(componentImplementation)) { return wrapLifeCycle(monitor.newInjector(new MethodInjector.ByReflectionMethod(componentKey, componentImplementation, parameters, monitor, injectionMethod, useNames)), lifecycleStrategy); } else { throw new PicoCompositionException("method [" + injectionMethod + "] not on impl " + componentImplementation.getName()); } } } } libpicocontainer-java-2.15/org/picocontainer/injectors/MethodInjector.java000066400000000000000000000244751242247644300271350ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Nullable; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Set; /** * Injection will happen through a single method for the component. * * Most likely it is a method called 'inject', though that can be overridden. * * @author Paul Hammant * @author Aslak Hellesøy * @author Jon Tirsén * @author Zohar Melamed * @author Jörg Schaible * @author Mauro Talevi */ @SuppressWarnings("serial") public abstract class MethodInjector extends SingleMemberInjector { private transient ThreadLocalCyclicDependencyGuard instantiationGuard; private final String methodName; /** * Creates a MethodInjector * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param methodName the method name * @param useNames use argument names when looking up dependencies * @throws AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public MethodInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, String methodName, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); this.methodName = methodName; } protected abstract Method getInjectorMethod(); @Override public T getComponentInstance(final PicoContainer container, @SuppressWarnings("unused") Type into) throws PicoCompositionException { if (instantiationGuard == null) { instantiationGuard = new ThreadLocalCyclicDependencyGuard() { @Override @SuppressWarnings("synthetic-access") public Object run(Object instance) { Method method = getInjectorMethod(); T inst = null; ComponentMonitor componentMonitor = currentMonitor(); try { // TODO .. instantiating() ??? componentMonitor.instantiating(container, MethodInjector.this, null); long startTime = System.currentTimeMillis(); Object[] methodParameters = null; inst = getComponentImplementation().newInstance(); if (method != null) { methodParameters = getMemberArguments(guardedContainer, method); invokeMethod(method, methodParameters, inst, container); } componentMonitor.instantiated(container, MethodInjector.this, null, inst, methodParameters, System.currentTimeMillis() - startTime); return inst; } catch (InstantiationException e) { return caughtInstantiationException(componentMonitor, null, e, container); } catch (IllegalAccessException e) { return caughtIllegalAccessException(componentMonitor, method, inst, e); } } }; } instantiationGuard.setGuardedContainer(container); return (T) instantiationGuard.observe(getComponentImplementation(), null); } protected Object[] getMemberArguments(PicoContainer container, final Method method) { return super.getMemberArguments(container, method, method.getParameterTypes(), getBindings(method.getParameterAnnotations())); } @Override public Object decorateComponentInstance(final PicoContainer container, @SuppressWarnings("unused") final Type into, final T instance) { if (instantiationGuard == null) { instantiationGuard = new ThreadLocalCyclicDependencyGuard() { @Override @SuppressWarnings("synthetic-access") public Object run(Object inst) { Method method = getInjectorMethod(); if (method != null && method.getDeclaringClass().isAssignableFrom(inst.getClass())) { Object[] methodParameters = getMemberArguments(guardedContainer, method); return invokeMethod(method, methodParameters, (T) inst, container); } return null; } }; } instantiationGuard.setGuardedContainer(container); Object o = instantiationGuard.observe(getComponentImplementation(), instance); return o; } private Object invokeMethod(Method method, Object[] methodParameters, T instance, PicoContainer container) { try { Object rv = currentMonitor().invoking(container, MethodInjector.this, (Member) method, instance, methodParameters); if (rv == ComponentMonitor.KEEP) { long str = System.currentTimeMillis(); rv = method.invoke(instance, methodParameters); currentMonitor().invoked(container, MethodInjector.this, method, instance, System.currentTimeMillis() - str, methodParameters, rv); } return rv; } catch (IllegalAccessException e) { return caughtIllegalAccessException(currentMonitor(), method, instance, e); } catch (InvocationTargetException e) { currentMonitor().invocationFailed(method, instance, e); if (e.getTargetException() instanceof RuntimeException) { throw (RuntimeException) e.getTargetException(); } else if (e.getTargetException() instanceof Error) { throw (Error) e.getTargetException(); } throw new PicoCompositionException(e); } } @Override public void verify(final PicoContainer container) throws PicoCompositionException { if (verifyingGuard == null) { verifyingGuard = new ThreadLocalCyclicDependencyGuard() { @Override public Object run(Object instance) { final Method method = getInjectorMethod(); final Class[] parameterTypes = method.getParameterTypes(); final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes.length); for (int i = 0; i < currentParameters.length; i++) { currentParameters[i].verify(container, MethodInjector.this, parameterTypes[i], new ParameterNameBinding(getParanamer(), method, i), useNames(), getBindings(method.getParameterAnnotations())[i]); } return null; } }; } verifyingGuard.setGuardedContainer(container); verifyingGuard.observe(getComponentImplementation(), null); } @Override protected boolean isNullParamAllowed(AccessibleObject member, int i) { Annotation[] annotations = ((Method) member).getParameterAnnotations()[i]; for (Annotation annotation : annotations) { if (annotation instanceof Nullable) { return true; } } return false; } public static class ByReflectionMethod extends MethodInjector { private final Method injectionMethod; public ByReflectionMethod(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, Method injectionMethod, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, null, useNames); this.injectionMethod = injectionMethod; } @Override protected Method getInjectorMethod() { return injectionMethod; } @Override public String getDescriptor() { return "MethodInjector.ByReflectionMethod[" + injectionMethod + "]-"; } } public static class ByMethodName extends MethodInjector { private Set injectionMethodNames; public ByMethodName(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, Set injectionMethodNames, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, null, useNames); ByMethodName.this.injectionMethodNames = injectionMethodNames; } @Override protected Method getInjectorMethod() { for (Method method : super.getComponentImplementation().getMethods()) { if (injectionMethodNames.contains(method.getName())) { return method; } } return null; } @Override public String getDescriptor() { return "MethodInjector.ByMethodName" + injectionMethodNames + "-"; } } }libpicocontainer-java-2.15/org/picocontainer/injectors/MultiInjection.java000066400000000000000000000042041242247644300271400ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** @author Paul Hammant */ @SuppressWarnings("serial") public class MultiInjection extends AbstractInjectionFactory { private final String setterPrefix; public MultiInjection(String setterPrefix) { this.setterPrefix = setterPrefix; } public MultiInjection() { this("set"); } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return wrapLifeCycle(new MultiInjector(componentKey, componentImplementation, parameters, monitor, setterPrefix, useNames), lifecycleStrategy); } } libpicocontainer-java-2.15/org/picocontainer/injectors/MultiInjector.java000066400000000000000000000037111242247644300267750ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.Parameter; import org.picocontainer.ComponentMonitor; import org.picocontainer.annotations.Inject; /** @author Paul Hammant */ @SuppressWarnings("serial") public class MultiInjector extends CompositeInjector { public MultiInjector(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor componentMonitor, String setterPrefix, boolean useNames) { super(componentKey, componentImplementation, parameters, componentMonitor, useNames, componentMonitor.newInjector(new ConstructorInjector(componentKey, componentImplementation, parameters, componentMonitor, useNames)), componentMonitor.newInjector(new SetterInjector(componentKey, componentImplementation, parameters, componentMonitor, setterPrefix, "", false, useNames)), componentMonitor.newInjector(new AnnotatedMethodInjector(componentKey, componentImplementation, parameters, componentMonitor, Inject.class, useNames)), componentMonitor.newInjector(new AnnotatedFieldInjector(componentKey, componentImplementation, parameters, componentMonitor, Inject.class, useNames))); } public String getDescriptor() { return "MultiInjector"; } } libpicocontainer-java-2.15/org/picocontainer/injectors/NamedFieldInjection.java000066400000000000000000000052601242247644300300410ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import static org.picocontainer.Characteristics.immutable; import java.util.Properties; /** * A {@link org.picocontainer.InjectionFactory} for named fields. * * Use like so: pico.as(injectionFieldNames("field1", "field2")).addComponent(...) * * The factory creates {@link org.picocontainer.injectors.NamedFieldInjector}. * * @author Paul Hammant */ @SuppressWarnings("serial") public class NamedFieldInjection extends AbstractInjectionFactory { private static final String INJECTION_FIELD_NAMES = "injectionFieldNames"; public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { String fieldNames = (String) componentProperties.remove(INJECTION_FIELD_NAMES); if (fieldNames == null) { fieldNames = ""; } return wrapLifeCycle(monitor.newInjector(new NamedFieldInjector(componentKey, componentImplementation, parameters, monitor, fieldNames)), lifecycleStrategy); } public static Properties injectionFieldNames(String... fieldNames) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fieldNames.length; i++) { sb.append(" ").append(fieldNames[i]); } Properties retVal = new Properties(); return immutable(INJECTION_FIELD_NAMES, sb.toString().trim()); } }libpicocontainer-java-2.15/org/picocontainer/injectors/NamedFieldInjector.java000066400000000000000000000103561242247644300276760ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Bind; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; /** * Injection happens after instantiation, and fields are marked as * injection points via a named field. */ @SuppressWarnings("serial") public class NamedFieldInjector extends AbstractFieldInjector { private final List fieldNames; public NamedFieldInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, String fieldNames) { super(key, impl, parameters, componentMonitor, true); this.fieldNames = Arrays.asList(fieldNames.trim().split(" ")); } @Override protected void initializeInjectionMembersAndTypeLists() { injectionMembers = new ArrayList(); List bindingIds = new ArrayList(); final List typeList = new ArrayList(); final Field[] fields = getFields(); for (final Field field : fields) { if (isNamedForInjection(field)) { injectionMembers.add(field); typeList.add(box(field.getType())); bindingIds.add(getBinding(field)); } } injectionTypes = typeList.toArray(new Type[0]); bindings = bindingIds.toArray(new Annotation[0]); } private Annotation getBinding(Field field) { Annotation[] annotations = field.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(Bind.class)) { return annotation; } } return null; } protected boolean isNamedForInjection(Field field) { return fieldNames.contains(field.getName()); } private Field[] getFields() { return AccessController.doPrivileged(new PrivilegedAction() { public Field[] run() { return getComponentImplementation().getDeclaredFields(); } }); } protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException { Field field = (Field) member; field.setAccessible(true); field.set(componentInstance, toInject); return null; } @Override public String getDescriptor() { return "NamedFieldInjector-"; } @Override protected NameBinding makeParameterNameImpl(final AccessibleObject member) { return new NameBinding() { public String getName() { return ((Field) member).getName(); } }; } protected Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance) { return instance; } List getInjectionFieldNames() { return Collections.unmodifiableList(fieldNames); } } libpicocontainer-java-2.15/org/picocontainer/injectors/NamedMethodInjection.java000066400000000000000000000023421242247644300302340ustar00rootroot00000000000000package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import java.util.Properties; public class NamedMethodInjection extends AbstractInjectionFactory { private final String prefix; private final boolean optional; public NamedMethodInjection(String prefix) { this(prefix, true); } public NamedMethodInjection() { this("set"); } public NamedMethodInjection(boolean optional) { this("set", optional); } public NamedMethodInjection(String prefix, boolean optional) { this.prefix = prefix; this.optional = optional; } public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { return wrapLifeCycle(monitor.newInjector(new NamedMethodInjector(componentKey, componentImplementation, parameters, monitor, prefix, optional)), lifecycleStrategy); } } libpicocontainer-java-2.15/org/picocontainer/injectors/NamedMethodInjector.java000066400000000000000000000055121242247644300300710ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Method; @SuppressWarnings("serial") public class NamedMethodInjector extends SetterInjector { public NamedMethodInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor, boolean optional) { this(key, impl, parameters, monitor, "set", optional); } public NamedMethodInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor) { this(key, impl, parameters, monitor, "set", true); } public NamedMethodInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor, String prefix) { this(key, impl, parameters, monitor, prefix, true); } public NamedMethodInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor monitor, String prefix, boolean optional) { super(key, impl, parameters, monitor, prefix, "", optional, true); } @Override protected NameBinding makeParameterNameImpl(final AccessibleObject member) { return new NameBinding() { public String getName() { String name = ((Method)member).getName().substring(prefix.length()); // string off 'set' or chosen prefix return name.substring(0,1).toLowerCase() + name.substring(1); // change "SomeThing" to "someThing" } }; } @Override public String getDescriptor() { return "NamedMethodInjection:"; } }libpicocontainer-java-2.15/org/picocontainer/injectors/ParameterNameBinding.java000066400000000000000000000031001242247644300302110ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.NameBinding; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Member; import com.thoughtworks.paranamer.CachingParanamer; import com.thoughtworks.paranamer.Paranamer; public class ParameterNameBinding implements NameBinding { private final AccessibleObject member; private final int index; private final Paranamer paranamer; private String name; public ParameterNameBinding(Paranamer paranamer, AccessibleObject member, int index) { this.member = member; this.paranamer = paranamer; this.index = index; } public String getName() { if (name != null) { return name; } String[] strings = paranamer.lookupParameterNames(member, false); name = strings.length == 0 ? "" : strings[index]; return name; } } libpicocontainer-java-2.15/org/picocontainer/injectors/PrimitiveMemberChecker.java000066400000000000000000000050101242247644300305640ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * Original Code By: Centerline Computers, Inc. * *****************************************************************************/ package org.picocontainer.injectors; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * * @author Michael Rimov */ public class PrimitiveMemberChecker { /** * Checks if the target argument is primative. * @param member target member instance, may be constructor, field, or method. * @param i parameter index. * @return true if the target object's "i"th parameter is a primitive (ie, int, float, etc) * @throws UnsupportedOperationException if for some reason the member parameter * is not a Constructor, Method, or Field. * @throws ArrayIndexOutOfBoundsException if 'i' is an inappropriate index for the * given parameters. For example, i should never be anything but zero for a field. */ public static boolean isPrimitiveArgument(AccessibleObject member, int i) throws ArrayIndexOutOfBoundsException, UnsupportedOperationException { Class[] types; if (member instanceof Constructor) { types = ((Constructor)member).getParameterTypes(); } else if (member instanceof Method) { types = ((Method)member).getParameterTypes(); } else if (member instanceof Field) { types = new Class[1]; types[0] = ((Field)member).getType(); } else { //Should be field/constructor/method only. throw new UnsupportedOperationException("Unsupported member type: " + member.getClass()); } if (i >= types.length) { throw new ArrayIndexOutOfBoundsException("Index i > types array length " + types.length + " for member " + member); } if (types[i].isPrimitive()) { return true; } return false; } } libpicocontainer-java-2.15/org/picocontainer/injectors/Provider.java000066400000000000000000000020031242247644300257700ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; /** * Providers are a type of Injector that can participate in Injection via a custom method. * * Implementers of this class must implement a single method called provide. That method must return * the component type intended to be provided. The method can accept parameters that PicoContainer * will satisfy. */ public interface Provider { } libpicocontainer-java-2.15/org/picocontainer/injectors/ProviderAdapter.java000066400000000000000000000125461242247644300273060ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.lifecycle.NullLifecycleStrategy; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Properties; /** * Providers are a type of Injector that can participate in Injection via a custom method. * * Implementers of this class must implement a single method called provide. That method must return * the component type intended to be provided. The method can accept parameters that PicoContainer * will satisfy. */ public class ProviderAdapter implements org.picocontainer.Injector, Provider, LifecycleStrategy { private final Provider provider; private final Method provideMethod; private final Class key; private Properties properties; private LifecycleStrategy lifecycleStrategy; protected ProviderAdapter() { provider = this; provideMethod = getProvideMethod(this.getClass()); key = provideMethod.getReturnType(); setUseNames(useNames()); this.lifecycleStrategy = new NullLifecycleStrategy(); } public ProviderAdapter(LifecycleStrategy lifecycleStrategy, Provider provider) { this(lifecycleStrategy, provider, false); } public ProviderAdapter(Provider provider) { this(new NullLifecycleStrategy(), provider, false); } public ProviderAdapter(Provider provider, boolean useNames) { this(new NullLifecycleStrategy(), provider, useNames); } public ProviderAdapter(LifecycleStrategy lifecycleStrategy, Provider provider, boolean useNames) { this.lifecycleStrategy = lifecycleStrategy; this.provider = provider; provideMethod = getProvideMethod(provider.getClass()); key = provideMethod.getReturnType(); setUseNames(useNames); } private void setUseNames(boolean useNames) { if (useNames) { properties = Characteristics.USE_NAMES; } else { properties = Characteristics.NONE; } } protected boolean useNames() { return false; } public Object decorateComponentInstance(PicoContainer container, Type into, Object instance) { return null; } public Object getComponentKey() { return key; } public Class getComponentImplementation() { return key; } @Deprecated public Object getComponentInstance(PicoContainer container) throws PicoCompositionException { return getComponentInstance(container, NOTHING.class); } public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return new Reinjector(container).reinject(key, provider.getClass(), provider, properties, new MethodInjection(provideMethod)); } public static Method getProvideMethod(Class clazz) { Method provideMethod = null; // TODO doPrivileged for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("provide")) { if (provideMethod != null) { throw newProviderMethodException("only one"); } provideMethod = method; } } if (provideMethod == null) { throw newProviderMethodException("a"); } if (provideMethod.getReturnType() == void.class) { throw newProviderMethodException("a non void returning"); } return provideMethod; } private static PicoCompositionException newProviderMethodException(String str) { return new PicoCompositionException("There must be "+ str +" method named 'provide' in the AbstractProvider implementation"); } public void verify(PicoContainer container) throws PicoCompositionException { } public void accept(PicoVisitor visitor) { } public ComponentAdapter getDelegate() { return null; } public ComponentAdapter findAdapterOfType(Class adapterType) { return null; } public String getDescriptor() { return "ProviderAdapter"; } public void start(Object component) { lifecycleStrategy.start(component); } public void stop(Object component) { lifecycleStrategy.stop(component); } public void dispose(Object component) { lifecycleStrategy.dispose(component); } public boolean hasLifecycle(Class type) { return lifecycleStrategy.hasLifecycle(type); } public boolean isLazy(ComponentAdapter adapter) { return lifecycleStrategy.isLazy(adapter); } } libpicocontainer-java-2.15/org/picocontainer/injectors/Reinjection.java000066400000000000000000000051261242247644300264600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.InjectionFactory; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.Characteristics; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.lang.reflect.Type; import java.util.Properties; public class Reinjection extends CompositeInjection { public Reinjection(InjectionFactory reinjectionFactory, final PicoContainer parent) { super(new AbstractInjectionFactory() { public ComponentAdapter createComponentAdapter( ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return new ReinjectionInjector(componentKey, componentImplementation, parameters, componentMonitor, parent, useNames); } }, reinjectionFactory); } private static class ReinjectionInjector extends AbstractInjector { private final PicoContainer parent; public ReinjectionInjector(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor componentMonitor, PicoContainer parent, boolean useNames) { super(componentKey, componentImplementation, parameters, componentMonitor, useNames); this.parent = parent; } public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return parent.getComponent(getComponentKey()); } } } libpicocontainer-java-2.15/org/picocontainer/injectors/Reinjector.java000066400000000000000000000155551242247644300263220ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; 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; /** * A Reinjector allows methods on pre-instantiated classes to be invoked, * with appropriately scoped parameters. */ public class Reinjector { private final PicoContainer parent; private final ComponentMonitor monitor; private static NullLifecycleStrategy NO_LIFECYCLE = new NullLifecycleStrategy(); private static Properties NO_PROPERTIES = new Properties(); /** * Make a reinjector with a parent container from which to pull components to be reinjected to. * With this constructor, a NullComponentMonitor is used. * @param parentContainer the parent container */ public Reinjector(PicoContainer parentContainer) { this(parentContainer, parentContainer instanceof ComponentMonitorStrategy ? ((ComponentMonitorStrategy) parentContainer).currentMonitor() : new NullComponentMonitor()); } /** * Make a reinjector with a parent container from which to pull components to be reinjected to * @param parentContainer the parent container * @param monitor the monitor to use for 'instantiating' events */ public Reinjector(PicoContainer parentContainer, ComponentMonitor monitor) { this.parent = parentContainer; this.monitor = monitor; } /** * Reinjecting into a method. * @param key the component-key from the parent set of components to inject into * @param reinjectionMethod the reflection method to use for injection. * @return the result of the reinjection-method invocation. */ public Object reinject(Class key, Method reinjectionMethod) { return reinject(key, key, parent.getComponent(key), NO_PROPERTIES, new MethodInjection(reinjectionMethod)); } /** * 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() { 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. */ public Object reinject(Class key, InjectionFactory reinjectionFactory) { Object o = reinject(key, key, parent.getComponent(key), NO_PROPERTIES, reinjectionFactory); return o; } /** * Reinjecting into a method. * @param key the component-key from the parent set of components to inject into * @param impl the implementation of the component that is going to result. * @param reinjectionFactory the InjectionFactory to use for reinjection. * @return */ public Object reinject(Class key, Class impl, InjectionFactory reinjectionFactory) { return reinject(key, impl, parent.getComponent(key), NO_PROPERTIES, reinjectionFactory); } /** * 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 instance the object that has the provider method to be invoked * @param reinjectionFactory the InjectionFactory to use for reinjection. * @return the result of the reinjection-method invocation. */ public Object reinject(Class key, Class implementation, Object instance, InjectionFactory reinjectionFactory) { return reinject(key, implementation, instance, NO_PROPERTIES, reinjectionFactory); } /** * 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 instance the object that has the provider method to be invoked * @param properties for reinjection * @param reinjectionFactory the InjectionFactory to use for reinjection. * @return the result of the reinjection-method invocation. */ public Object reinject(Class key, Class implementation, Object instance, Properties properties, InjectionFactory reinjectionFactory) { Reinjection reinjection = new Reinjection(reinjectionFactory, parent); org.picocontainer.Injector injector = (org.picocontainer.Injector) reinjection.createComponentAdapter( monitor, NO_LIFECYCLE, properties, key, implementation, null); return injector.decorateComponentInstance(parent, null, instance); } } libpicocontainer-java-2.15/org/picocontainer/injectors/SetterInjection.java000066400000000000000000000063151242247644300273210ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.Characteristics; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.behaviors.AbstractBehaviorFactory; import java.util.Properties; /** * A {@link org.picocontainer.InjectionFactory} for JavaBeans. * The factory creates {@link SetterInjector}. * * @author Jörg Schaible */ @SuppressWarnings("serial") public class SetterInjection extends AbstractInjectionFactory { private final String prefix; private String notThisOneThough; private boolean optional; public SetterInjection(String prefix) { this.prefix = prefix; } public SetterInjection() { this("set"); } /** * Specify a prefix and an exclusion * @param prefix the prefix like 'set' * @param notThisOneThough to exclude, like 'setMetaClass' for Groovy */ public SetterInjection(String prefix, String notThisOneThough) { this(prefix); this.notThisOneThough = notThisOneThough; } /** * Create a {@link SetterInjector}. * * @param monitor * @param lifecycleStrategy * @param componentProperties * @param componentKey The component's key * @param componentImplementation The class of the bean. * @param parameters Any parameters for the setters. If null the adapter * solves the dependencies for all setters internally. Otherwise * the number parameters must match the number of the setter. * @return Returns a new {@link SetterInjector}. * @throws PicoCompositionException if dependencies cannot be solved */ public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); return wrapLifeCycle(monitor.newInjector(new SetterInjector(componentKey, componentImplementation, parameters, monitor, prefix, notThisOneThough != null ? notThisOneThough : "", optional, useNames)), lifecycleStrategy); } public SetterInjection withInjectionOptional() { optional = true; return this; } } libpicocontainer-java-2.15/org/picocontainer/injectors/SetterInjector.java000066400000000000000000000114761242247644300271600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.behaviors.PropertyApplicator; import org.picocontainer.behaviors.Cached; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.AccessibleObject; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Set; /** * Instantiates components using empty constructors and * Setter Injection. * For easy setting of primitive properties, also see {@link PropertyApplicator}. *

      * * Note that this class doesn't cache instances. If you want caching, * use a {@link Cached} around this one. * *

      * * @author Aslak Hellesøy * @author Jörg Schaible * @author Mauro Talevi * @author Paul Hammant */ @SuppressWarnings("serial") public class SetterInjector extends IterativeInjector { protected final String prefix; private final boolean optional; private final String notThisOneThough; /** * Constructs a SetterInjector * * * @param componentKey the search key for this implementation * @param componentImplementation the concrete implementation * @param parameters the parameters to use for the initialization * @param monitor the component monitor used by this addAdapter * @param prefix the prefix to use (e.g. 'set') * @param notThisOneThough a setter name that's not for injecting through * @param optional not all setters need to be injected * @param useNames @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is null */ public SetterInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, String prefix, String notThisOneThough, boolean optional, boolean useNames) throws NotConcreteRegistrationException { super(componentKey, componentImplementation, parameters, monitor, useNames); this.prefix = prefix; this.optional = optional; this.notThisOneThough = notThisOneThough != null ? notThisOneThough : ""; } protected Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance) { return member != null && ((Method)member).getReturnType()!=void.class ? lastReturn : instance; } @Override protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException { return ((Method)member).invoke(componentInstance, toInject); } @Override protected boolean isInjectorMethod(Method method) { String methodName = method.getName(); return methodName.length() >= getInjectorPrefix().length() + 1 // long enough && methodName.startsWith(getInjectorPrefix()) && !methodName.equals(notThisOneThough) && Character.isUpperCase(methodName.charAt(getInjectorPrefix().length())); } protected String getInjectorPrefix() { return prefix; } @Override public String getDescriptor() { return "SetterInjector-"; } @Override protected void unsatisfiedDependencies(PicoContainer container, Set unsatisfiableDependencyTypes, List unsatisfiableDependencyMembers) { if (!optional) { throw new UnsatisfiableDependenciesException(this.getComponentImplementation().getName() + " has unsatisfied dependencies " + unsatisfiableDependencyTypes + " for members " + unsatisfiableDependencyMembers + " from " + container); } } } libpicocontainer-java-2.15/org/picocontainer/injectors/SingleMemberInjector.java000066400000000000000000000126611242247644300302600ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.injectors; import com.thoughtworks.paranamer.AdaptiveParanamer; import com.thoughtworks.paranamer.AnnotationParanamer; import com.thoughtworks.paranamer.CachingParanamer; import com.thoughtworks.paranamer.Paranamer; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Bind; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Type; import static org.picocontainer.injectors.PrimitiveMemberChecker.isPrimitiveArgument; /** * Injection will happen in a single member function on the component. * * @author Paul Hammant * */ @SuppressWarnings("serial") public abstract class SingleMemberInjector extends AbstractInjector { private transient Paranamer paranamer; public SingleMemberInjector(Object componentKey, Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor, boolean useNames) { super(componentKey, componentImplementation, parameters, monitor, useNames); } protected Paranamer getParanamer() { if (paranamer == null) { paranamer = new CachingParanamer(new AnnotationParanamer(new AdaptiveParanamer())); } return paranamer; } @SuppressWarnings("unchecked") protected Object[] getMemberArguments(PicoContainer container, final AccessibleObject member, final Type[] parameterTypes, final Annotation[] bindings) { boxParameters(parameterTypes); Object[] result = new Object[parameterTypes.length]; final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes.length); for (int i = 0; i < currentParameters.length; i++) { result[i] = getParameter(container, member, i, parameterTypes[i], bindings[i], currentParameters[i], null); } return result; } protected void boxParameters(Type[] parameterTypes) { for (int i = 0; i < parameterTypes.length; i++) { parameterTypes[i] = box(parameterTypes[i]); } } protected Object getParameter(PicoContainer container, AccessibleObject member, int i, Type parameterType, Annotation binding, Parameter currentParameter, ComponentAdapter injecteeAdapter) { ParameterNameBinding expectedNameBinding = new ParameterNameBinding(getParanamer(), member, i); Object result = null; try { result = currentParameter.resolve(container, this, injecteeAdapter, parameterType, expectedNameBinding, useNames(), binding).resolveInstance(); } catch (AmbiguousComponentResolutionException e) { e.setMember(member); throw e; } nullCheck(member, i, expectedNameBinding, result); return result; } @SuppressWarnings("synthetic-access") protected void nullCheck(AccessibleObject member, int i, ParameterNameBinding expectedNameBinding, Object result) { if (result == null && !isNullParamAllowed(member, i)) { throw new ParameterCannotBeNullException(i, member, expectedNameBinding.getName()); } } /** * Checks to see if a null parameter is allowed in the given * constructor/field/method. The default version allows null * if the target object is not a primitive type. * @param member constructor method or field * @param i parameter #. * @return true if the null parameter might be allowed. */ protected boolean isNullParamAllowed(AccessibleObject member, int i) { return !(isPrimitiveArgument(member, i)); } protected Annotation[] getBindings(Annotation[][] annotationss) { Annotation[] retVal = new Annotation[annotationss.length]; for (int i = 0; i < annotationss.length; i++) { Annotation[] annotations = annotationss[i]; for (Annotation annotation : annotations) { if (annotation.annotationType().getAnnotation(Bind.class) != null) { retVal[i] = annotation; break; } } } return retVal; } public static class ParameterCannotBeNullException extends PicoCompositionException { private final String name; private ParameterCannotBeNullException(int ix, AccessibleObject member, String name) { super("Parameter " + ix + " of '" + member + "' named '" + name + "' cannot be null"); this.name = name; } public String getParameterName() { return name; } } } libpicocontainer-java-2.15/org/picocontainer/injectors/TypedFieldInjection.java000066400000000000000000000051441242247644300301030ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.LifecycleStrategy; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import java.util.Properties; import static org.picocontainer.Characteristics.immutable; /** * A {@link org.picocontainer.InjectionFactory} for named fields. * * Use like so: pico.as(injectionFieldNames("field1", "field2")).addComponent(...) * * The factory creates {@link TypedFieldInjector}. * * @author Paul Hammant */ @SuppressWarnings("serial") public class TypedFieldInjection extends AbstractInjectionFactory { private static final String INJECTION_FIELD_TYPES = "injectionFieldTypes"; public ComponentAdapter createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException { String fieldTypes = (String) componentProperties.remove(INJECTION_FIELD_TYPES); if (fieldTypes == null) { fieldTypes = ""; } return wrapLifeCycle(monitor.newInjector(new TypedFieldInjector(componentKey, componentImplementation, parameters, monitor, fieldTypes)), lifecycleStrategy); } public static Properties injectionFieldTypes(String... fieldTypes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fieldTypes.length; i++) { sb.append(" ").append(fieldTypes[i]); } return immutable(INJECTION_FIELD_TYPES, sb.toString().trim()); } }libpicocontainer-java-2.15/org/picocontainer/injectors/TypedFieldInjector.java000066400000000000000000000101461242247644300277340ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.injectors; import org.picocontainer.ComponentMonitor; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.annotations.Bind; import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; /** * Injection happens after instantiation, and fields are marked as * injection points via a field type. */ @SuppressWarnings("serial") public class TypedFieldInjector extends AbstractFieldInjector { private final List classes; public TypedFieldInjector(Object key, Class impl, Parameter[] parameters, ComponentMonitor componentMonitor, String classNames) { super(key, impl, parameters, componentMonitor, true); this.classes = Arrays.asList(classNames.trim().split(" ")); } @Override protected void initializeInjectionMembersAndTypeLists() { injectionMembers = new ArrayList(); List bindingIds = new ArrayList(); final List typeList = new ArrayList(); final Field[] fields = getFields(); for (final Field field : fields) { if (isTypedForInjection(field)) { injectionMembers.add(field); typeList.add(box(field.getType())); bindingIds.add(getBinding(field)); } } injectionTypes = typeList.toArray(new Type[0]); bindings = bindingIds.toArray(new Annotation[0]); } private Annotation getBinding(Field field) { Annotation[] annotations = field.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(Bind.class)) { return annotation; } } return null; } protected boolean isTypedForInjection(Field field) { return classes.contains(field.getType().getName()); } private Field[] getFields() { return AccessController.doPrivileged(new PrivilegedAction() { public Field[] run() { return getComponentImplementation().getDeclaredFields(); } }); } protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject) throws IllegalAccessException, InvocationTargetException { Field field = (Field) member; field.setAccessible(true); field.set(componentInstance, toInject); return null; } @Override public String getDescriptor() { return "TypedFieldInjector-"; } @Override protected NameBinding makeParameterNameImpl(final AccessibleObject member) { return new NameBinding() { public String getName() { return ((Field) member).getName(); } }; } protected Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance) { return instance; } List getInjectionFieldTypes() { return Collections.unmodifiableList(classes); } }libpicocontainer-java-2.15/org/picocontainer/injectors/package.html000066400000000000000000000006771242247644300256330ustar00rootroot00000000000000 Insert title here

      InjectionFactories make Injectors which implement specific types of dependency injection

      libpicocontainer-java-2.15/org/picocontainer/lifecycle/000077500000000000000000000000001242247644300232775ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/lifecycle/AbstractMonitoringLifecycleStrategy.java000066400000000000000000000040341242247644300333170ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import java.io.Serializable; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.ComponentMonitorStrategy; import org.picocontainer.LifecycleStrategy; /** * Abstract base class for lifecycle strategy implementation supporting a {@link ComponentMonitor}. * * @author Jörg Schaible */ public abstract class AbstractMonitoringLifecycleStrategy implements LifecycleStrategy, ComponentMonitorStrategy, Serializable { /** * Component monitor that receives lifecycle state. */ private ComponentMonitor componentMonitor; /** * Construct a AbstractMonitoringLifecycleStrategy. * * @param monitor the componentMonitor to use * @throws NullPointerException if the monitor is null */ public AbstractMonitoringLifecycleStrategy(final ComponentMonitor monitor) { changeMonitor(monitor); } /** * Swaps the current monitor with a replacement. * @param monitor The new monitor. * @throws NullPointerException if the passed in monitor is null. */ public void changeMonitor(final ComponentMonitor monitor) { if (monitor == null) { throw new NullPointerException("Monitor is null"); } this.componentMonitor = monitor; } public ComponentMonitor currentMonitor() { return componentMonitor; } public boolean isLazy(ComponentAdapter adapter) { return false; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/CompositeLifecycleStrategy.java000066400000000000000000000043331242247644300314520ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; /** * Allow for use of alternate LifecycleStrategy strategies to be used * at the same time. A component can be started/stopped/disposed according * to *any* of the supplied LifecycleStrategy instances. * * @author Paul Hammant */ public class CompositeLifecycleStrategy implements LifecycleStrategy { private final LifecycleStrategy[] alternateStrategies; public CompositeLifecycleStrategy(LifecycleStrategy... alternateStrategies) { this.alternateStrategies = alternateStrategies; } public void start(Object component) { for (LifecycleStrategy lifecycleStrategy : alternateStrategies) { lifecycleStrategy.start(component); } } public void stop(Object component) { for (LifecycleStrategy lifecycleStrategy : alternateStrategies) { lifecycleStrategy.stop(component); } } public void dispose(Object component) { for (LifecycleStrategy lifecycleStrategy : alternateStrategies) { lifecycleStrategy.dispose(component); } } public boolean hasLifecycle(Class type) { for (LifecycleStrategy lifecycleStrategy : alternateStrategies) { if (lifecycleStrategy.hasLifecycle(type)) { return true; } } return false; } public boolean isLazy(ComponentAdapter adapter) { for (LifecycleStrategy lifecycleStrategy : alternateStrategies) { if (lifecycleStrategy.isLazy(adapter)) { return true; } } return false; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/DefaultLifecycleState.java000066400000000000000000000057411242247644300303560ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import org.picocontainer.PicoCompositionException; import java.io.Serializable; /** * Bean-like implementation of LifecycleState. * @author Paul Hammant * @author Michael Rimov * */ @SuppressWarnings("serial") public class DefaultLifecycleState implements LifecycleState, Serializable { /** * Default state of a container once it has been built. */ private static final String CONSTRUCTED = "CONSTRUCTED"; /** * 'Start' Lifecycle has been called. */ private static final String STARTED = "STARTED"; /** * 'Stop' lifecycle has been called. */ private static final String STOPPED = "STOPPED"; /** * 'Dispose' lifecycle has been called. */ private static final String DISPOSED = "DISPOSED"; /** * Initial state. */ private String state = CONSTRUCTED; /** {@inheritDoc} **/ public void removingComponent() { if (isStarted()) { throw new PicoCompositionException("Cannot remove components after the container has started"); } if (isDisposed()) { throw new PicoCompositionException("Cannot remove components after the container has been disposed"); } } /** {@inheritDoc} **/ public void starting() { if (isConstructed() || isStopped()) { state = STARTED; return; } throw new IllegalStateException("Cannot start. Current container state was: " + state); } /** {@inheritDoc} **/ public void stopping() { if (!(isStarted())) { throw new IllegalStateException("Cannot stop. Current container state was: " + state); } } /** {@inheritDoc} **/ public void stopped() { state = STOPPED; } /** {@inheritDoc} **/ public boolean isStarted() { return state == STARTED; } /** {@inheritDoc} **/ public void disposing() { if (!(isStopped() || isConstructed())) { throw new IllegalStateException("Cannot dispose. Current lifecycle state is: " + state); } } /** {@inheritDoc} **/ public void disposed() { state = DISPOSED; } /** {@inheritDoc} **/ public boolean isDisposed() { return state == DISPOSED; } /** {@inheritDoc} **/ public boolean isStopped() { return state == STOPPED; } /** * Returns true if no other state has been triggered so far. * @return */ public boolean isConstructed() { return state == CONSTRUCTED; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/JavaEE5LifecycleStrategy.java000066400000000000000000000104161242247644300306670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import org.picocontainer.ComponentMonitor; import org.picocontainer.PicoLifecycleException; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; /** * Java EE 5 has some annotations PreDestroy and PostConstruct that map to start() and dispose() in our world * * @author Paul Hammant */ @SuppressWarnings("serial") public final class JavaEE5LifecycleStrategy extends AbstractMonitoringLifecycleStrategy { /** * Construct a JavaEE5LifecycleStrategy. * * @param monitor the monitor to use * @throws NullPointerException if the monitor is null */ public JavaEE5LifecycleStrategy(final ComponentMonitor monitor) { super(monitor); } /** {@inheritDoc} **/ public void start(final Object component) { doLifecycleMethod(component, PostConstruct.class, true); } /** {@inheritDoc} **/ public void stop(final Object component) { } /** {@inheritDoc} **/ public void dispose(final Object component) { doLifecycleMethod(component, PreDestroy.class, false); } private void doLifecycleMethod(final Object component, Class annotation, boolean superFirst) { doLifecycleMethod(component, annotation, component.getClass(), superFirst, new HashSet()); } private void doLifecycleMethod(Object component, Class annotation, Class clazz, boolean superFirst, Set doneAlready) { Class parent = clazz.getSuperclass(); if (superFirst && parent != Object.class) { doLifecycleMethod(component, annotation, parent, superFirst, doneAlready); } Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { String signature = signature(method); if (method.isAnnotationPresent(annotation) && !doneAlready.contains(signature)) { try { long str = System.currentTimeMillis(); currentMonitor().invoking(null, null, method, component, new Object[0]); method.invoke(component); doneAlready.add(signature); currentMonitor().invoked(null, null, method, component, System.currentTimeMillis() - str, new Object[0], null); } catch (IllegalAccessException e) { throw new PicoLifecycleException(method, component, e); } catch (InvocationTargetException e) { throw new PicoLifecycleException(method, component, e); } } } if (!superFirst && parent != Object.class) { doLifecycleMethod(component, annotation, parent, superFirst, doneAlready); } } private static String signature(Method method) { StringBuilder sb = new StringBuilder(method.getName()); Class[] pt = method.getParameterTypes(); for (Class objectClass : pt) { sb.append(objectClass.getName()); } return sb.toString(); } /** * {@inheritDoc} The component has a lifecycle PreDestroy or PostConstruct are on a method */ public boolean hasLifecycle(final Class type) { Method[] methods = type.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (method.isAnnotationPresent(PreDestroy.class) || method.isAnnotationPresent(PostConstruct.class)) { return true; } } return false; } }libpicocontainer-java-2.15/org/picocontainer/lifecycle/LifecycleState.java000066400000000000000000000042711242247644300270460ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; /** * Current lifecycle state of the container. * @author Michael Rimov * @author Paul Hammant */ public interface LifecycleState { /** * Lifecycle state for when a component is being removed. */ void removingComponent(); /** * Start is normally allowed if the object is constructed or * already stopped. It is not allowed if the system is already * started or disposed. * @return true if start lifecycle methods should be allowed. */ void starting(); /** * Lifecycle state for when the container is being stopped. (Ie, right after Picocontainer.stop() * has been called, but before any components are stopped. */ void stopping(); /** * Lifecycle state for when stop has been completed. */ void stopped(); /** * Checks if current lifecycle is started. * @return true if the current container state is STARTED. */ boolean isStarted(); /** * Turns the lifecycle state to indicate that the dispose() process is being * executed on the container. */ void disposing(); /** * Turns the lifecycle state to completely disposed. Internally called after PicoContainer.dispose() * is finished. */ void disposed(); /** * Checks if the current lifecycle is disposed. * @return true if the current state is DISPOSED. */ boolean isDisposed(); /** * Checks if the current lifecyle is stopped. * @return true if the current state is STOPPED; * @return */ boolean isStopped(); } libpicocontainer-java-2.15/org/picocontainer/lifecycle/NullLifecycleStrategy.java000066400000000000000000000027601242247644300304240ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.lifecycle; import java.io.Serializable; import org.picocontainer.ComponentAdapter; import org.picocontainer.LifecycleStrategy; /** * Lifecycle strategy that does nothing. * */ @SuppressWarnings("serial") public class NullLifecycleStrategy implements LifecycleStrategy, Serializable { /** {@inheritDoc} **/ public void start(final Object component) { //Does nothing } /** {@inheritDoc} **/ public void stop(final Object component) { //Does nothing } /** {@inheritDoc} **/ public void dispose(final Object component) { //Does nothing } /** {@inheritDoc} **/ public boolean hasLifecycle(final Class type) { return false; } public boolean isLazy(ComponentAdapter adapter) { return false; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/ReflectionLifecycleException.java000066400000000000000000000023751242247644300317420ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import org.picocontainer.PicoException; /** * Subclass of {@link PicoException} that is thrown when there is a problem * invoking lifecycle methods via reflection. * * @author Paul Hammant * @author Mauro Talevi */ @SuppressWarnings("serial") public class ReflectionLifecycleException extends PicoException { /** * Construct a new exception with the specified cause and the specified detail message. * * @param message the message detailing the exception. * @param cause the exception that caused this one. */ protected ReflectionLifecycleException(final String message, final Throwable cause) { super(message, cause); } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/ReflectionLifecycleStrategy.java000066400000000000000000000147251242247644300316100ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import org.picocontainer.ComponentMonitor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * Reflection lifecycle strategy. Starts, stops, disposes of component if appropriate methods are * present. The component may implement only one of the three methods. * * @author Paul Hammant * @author Mauro Talevi * @author Jörg Schaible * @see org.picocontainer.Startable * @see org.picocontainer.Disposable * @see org.picocontainer.lifecycle.StartableLifecycleStrategy */ @SuppressWarnings("serial") public class ReflectionLifecycleStrategy extends AbstractMonitoringLifecycleStrategy { /** * Index in the methodnames array that contains the name of the 'start' * method. */ private final static int START = 0; /** * Index in the methodNames array that contains the name of the 'stop' * method. */ private final static int STOP = 1; /** * Index in the methodNames array that contains the name of the 'dispose' * method. */ private final static int DISPOSE = 2; /** * An array of method names that are part of the lifecycle functions. */ private final String[] methodNames; /** * Map of classes mapped to method arrays that are cached for reflection. */ private final transient Map, Method[]> methodMap = new HashMap, Method[]>(); /** * Construct a ReflectionLifecycleStrategy. * * @param monitor the monitor to use * @throws NullPointerException if the monitor is null */ public ReflectionLifecycleStrategy(final ComponentMonitor monitor) { this(monitor, "start", "stop", "dispose"); } /** * Construct a ReflectionLifecycleStrategy with individual method names. Note, that a lifecycle * method does not have any arguments. * * @param monitor the monitor to use * @param startMethodName the name of the start method * @param stopMethodName the name of the stop method * @param disposeMethodName the name of the dispose method * @throws NullPointerException if the monitor is null */ public ReflectionLifecycleStrategy( final ComponentMonitor monitor, final String startMethodName, final String stopMethodName, final String disposeMethodName) { super(monitor); methodNames = new String[]{startMethodName, stopMethodName, disposeMethodName}; } /** {@inheritDoc} **/ public void start(final Object component) { Method[] methods = init(component.getClass()); invokeMethod(component, methods[START]); } /** {@inheritDoc} **/ public void stop(final Object component) { Method[] methods = init(component.getClass()); invokeMethod(component, methods[STOP]); } /** {@inheritDoc} **/ public void dispose(final Object component) { Method[] methods = init(component.getClass()); invokeMethod(component, methods[DISPOSE]); } private void invokeMethod(final Object component, final Method method) { if (component != null && method != null) { try { long str = System.currentTimeMillis(); currentMonitor().invoking(null, null, method, component, new Object[0]); method.invoke(component); currentMonitor().invoked(null, null, method, component, System.currentTimeMillis() - str, new Object[0], null); } catch (IllegalAccessException e) { monitorAndThrowReflectionLifecycleException(method, e, component); } catch (InvocationTargetException e) { monitorAndThrowReflectionLifecycleException(method, e.getCause(), component); } } } protected void monitorAndThrowReflectionLifecycleException(final Method method, final Throwable e, final Object component) { RuntimeException re; if (e.getCause() instanceof RuntimeException) { re = (RuntimeException) e.getCause(); // TODO - change lifecycleInvocationFailed to take a throwable in future version // } else if (e.getCause() instanceof Error) { // re = (Error) e.getCause(); } else { re = new RuntimeException("wrapper", e); } currentMonitor().lifecycleInvocationFailed(null, null, method, component, re); } /** * {@inheritDoc} The component has a lifecycle if at least one of the three methods is present. */ public boolean hasLifecycle(final Class type) { Method[] methods = init(type); for (Method method : methods) { if (method != null) { return true; } } return false; } /** * Initializes the method array with the given type. * @param type the type to examine for reflection lifecycle methods. * @return Method array containing start/stop/dispose methods. */ private Method[] init(final Class type) { Method[] methods; synchronized (methodMap) { methods = methodMap.get(type); if (methods == null) { methods = new Method[methodNames.length]; for (int i = 0; i < methods.length; i++) { try { final String methodName = methodNames[i]; if (methodName == null) { // skipping, we're not interested in this lifecycle method. continue; } methods[i] = type.getMethod(methodName); } catch (NoSuchMethodException e) { continue; } } methodMap.put(type, methods); } } return methods; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/StartableLifecycleStrategy.java000066400000000000000000000136531242247644300314360ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.lifecycle; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.picocontainer.ComponentMonitor; import org.picocontainer.Disposable; import org.picocontainer.PicoLifecycleException; import org.picocontainer.Startable; /** * Startable lifecycle strategy. Starts and stops component if Startable, * and disposes it if Disposable. * * A subclass of this class can define other intrfaces for Startable/Disposable as well as other method names * for start/stop/dispose * * @author Mauro Talevi * @author Jörg Schaible * @see Startable * @see Disposable */ @SuppressWarnings("serial") public class StartableLifecycleStrategy extends AbstractMonitoringLifecycleStrategy { private transient Method start, stop, dispose; public StartableLifecycleStrategy(final ComponentMonitor monitor) { super(monitor); } private void doMethodsIfNotDone() { try { if (start == null) { start = getStartableInterface().getMethod(getStartMethodName()); } if (stop == null) { stop = getStartableInterface().getMethod(getStopMethodName()); } if (dispose == null) { dispose = getDisposableInterface().getMethod(getDisposeMethodName()); } } catch (NoSuchMethodException e) { } } /** * Retrieve the lifecycle method name that represents the dispose method. * @return the dispose method name. ('dispose') */ protected String getDisposeMethodName() { return "dispose"; } /** * Retrieve the lifecycle method name that represents the stop method. * @return the stop method name ('stop') */ protected String getStopMethodName() { return "stop"; } /** * Retrieve the lifecycle method name that represents the start method. * @return the stop method name ('start') */ protected String getStartMethodName() { return "start"; } /** {@inheritDoc} **/ public void start(final Object component) { doMethodsIfNotDone(); if (component != null && getStartableInterface().isAssignableFrom(component.getClass())) { long str = System.currentTimeMillis(); currentMonitor().invoking(null, null, start, component, new Object[0]); try { startComponent(component); currentMonitor().invoked(null, null, start, component, System.currentTimeMillis() - str, new Object[0], null); } catch (RuntimeException cause) { currentMonitor().lifecycleInvocationFailed(null, null, start, component, cause); // may re-throw } } } protected void startComponent(final Object component) { doLifecycleMethod(component, start); } private void doLifecycleMethod(Object component, Method lifecycleMethod) { try { lifecycleMethod.invoke(component); } catch (IllegalAccessException e) { throw new PicoLifecycleException(lifecycleMethod, component, e); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof RuntimeException) { throw (RuntimeException) e.getTargetException(); } throw new PicoLifecycleException(lifecycleMethod, component, e.getTargetException()); } } protected void stopComponent(final Object component) { doLifecycleMethod(component, stop); } protected void disposeComponent(final Object component) { doLifecycleMethod(component, dispose); } /** {@inheritDoc} **/ public void stop(final Object component) { doMethodsIfNotDone(); if (component != null && getStartableInterface().isAssignableFrom(component.getClass())) { long str = System.currentTimeMillis(); currentMonitor().invoking(null, null, stop, component, new Object[0]); try { stopComponent(component); currentMonitor().invoked(null, null, stop, component, System.currentTimeMillis() - str, new Object[0], null); } catch (RuntimeException cause) { currentMonitor().lifecycleInvocationFailed(null, null, stop, component, cause); // may re-throw } } } /** {@inheritDoc} **/ public void dispose(final Object component) { doMethodsIfNotDone(); if (component != null && getDisposableInterface().isAssignableFrom(component.getClass())) { long str = System.currentTimeMillis(); currentMonitor().invoking(null, null, dispose, component, new Object[0]); try { disposeComponent(component); currentMonitor().invoked(null, null, dispose, component, System.currentTimeMillis() - str, new Object[0], null); } catch (RuntimeException cause) { currentMonitor().lifecycleInvocationFailed(null, null, dispose, component, cause); // may re-throw } } } /** {@inheritDoc} **/ public boolean hasLifecycle(final Class type) { return getStartableInterface().isAssignableFrom(type) || getDisposableInterface().isAssignableFrom(type); } protected Class getDisposableInterface() { return Disposable.class; } protected Class getStartableInterface() { return Startable.class; } } libpicocontainer-java-2.15/org/picocontainer/lifecycle/package.html000066400000000000000000000013671242247644300255670ustar00rootroot00000000000000 Insert title here

      Alternative implementations of lifecycle strategy for use with a container. Currently supported options are:

      • Implement Startable and/or Disposable (or other strong interface)
      • Use configuration to wire methods that are start/stop/dispose equivalent.
      • J2EE 5.0 Annotation-based lifecycles.
      • Combinations thereof (composite)
      libpicocontainer-java-2.15/org/picocontainer/monitors/000077500000000000000000000000001242247644300232125ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/monitors/AbstractComponentMonitor.java000066400000000000000000000133571242247644300310640ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Mauro Talevi * *****************************************************************************/ package org.picocontainer.monitors; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.ComponentMonitorStrategy; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.Injector; import org.picocontainer.Behavior; /** *

      * A {@link ComponentMonitor monitor} which delegates to another monitor. * It provides a {@link NullComponentMonitor default ComponentMonitor}, * but does not allow to use null for the delegate. *

      *

      * It also supports a {@link org.picocontainer.ComponentMonitorStrategy monitor strategy} * that allows to change the delegate. *

      * * @author Mauro Talevi */ @SuppressWarnings("serial") public class AbstractComponentMonitor implements ComponentMonitor, ComponentMonitorStrategy, Serializable { /** * Delegate monitor to allow for component monitor chaining. */ private ComponentMonitor delegate; /** * Creates a AbstractComponentMonitor with a given delegate * @param delegate the ComponentMonitor to which this monitor delegates */ public AbstractComponentMonitor(ComponentMonitor delegate) { checkMonitor(delegate); this.delegate = delegate; } /** * Creates a AbstractComponentMonitor with an instance of * {@link NullComponentMonitor}. */ public AbstractComponentMonitor() { this(new NullComponentMonitor()); } public Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor) { return delegate.instantiating(container, componentAdapter, constructor); } public void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] injected, long duration) { delegate.instantiated(container, componentAdapter, constructor, instantiated, injected, duration); } public void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception e) { delegate.instantiationFailed(container, componentAdapter, constructor, e); } public Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args) { return delegate.invoking(container, componentAdapter, member, instance, args); } public void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal) { delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal); } public void invocationFailed(Member member, Object instance, Exception e) { delegate.invocationFailed(member, instance, e); } public void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause) { delegate.lifecycleInvocationFailed(container, componentAdapter, method,instance, cause); } public Object noComponentFound(MutablePicoContainer container, Object componentKey) { return delegate.noComponentFound(container, componentKey); } public Injector newInjector(Injector injector) { return injector; } public Behavior newBehavior(Behavior behavior) { return behavior; } /** * If the delegate supports a {@link ComponentMonitorStrategy monitor strategy}, * this is used to changed the monitor while keeping the same delegate. * Else the delegate is replaced by the new monitor. * {@inheritDoc} */ public void changeMonitor(ComponentMonitor monitor) { checkMonitor(monitor); if ( delegate instanceof ComponentMonitorStrategy ){ ((ComponentMonitorStrategy)delegate).changeMonitor(monitor); } else { delegate = monitor; } } public ComponentMonitor currentMonitor() { if ( delegate instanceof ComponentMonitorStrategy ){ return ((ComponentMonitorStrategy)delegate).currentMonitor(); } else { return delegate; } } private void checkMonitor(ComponentMonitor monitor) { if ( monitor == null ){ throw new NullPointerException("monitor"); } } } libpicocontainer-java-2.15/org/picocontainer/monitors/ComponentMonitorHelper.java000066400000000000000000000075541242247644300305420ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammaant * *****************************************************************************/ package org.picocontainer.monitors; import java.text.MessageFormat; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.Member; import org.picocontainer.ComponentMonitor; /** * An abstract {@link ComponentMonitor} which supports all the message formats. * * @author Mauro Talevi */ public final class ComponentMonitorHelper { public final static String INSTANTIATING = "PicoContainer: instantiating {0}"; public final static String INSTANTIATED = "PicoContainer: instantiated {0} [{1} ms], component {2}, injected [{3}]"; public final static String INSTANTIATION_FAILED = "PicoContainer: instantiation failed: {0}, reason: {1}"; public final static String INVOKING = "PicoContainer: invoking {0} on {1}"; public final static String INVOKED = "PicoContainer: invoked {0} on {1} [{2} ms]"; public final static String INVOCATION_FAILED = "PicoContainer: invocation failed: {0} on {1}, reason: {2}"; public final static String LIFECYCLE_INVOCATION_FAILED = "PicoContainer: lifecycle invocation failed: {0} on {1}, reason: {2}"; public final static String NO_COMPONENT = "PicoContainer: No component for key: {0}"; public static String format(String template, Object... arguments) { return MessageFormat.format(template, arguments); } public static String parmsToString(Object[] injected) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < injected.length; i++) { String s = injected[i].getClass().getName(); sb.append(s); if (i < injected.length-1) { sb.append(", "); } } return sb.toString(); } public static String ctorToString(Constructor constructor) { Class[] params = constructor.getParameterTypes(); StringBuffer sb = new StringBuffer(constructor.getName()); sb.append("("); for (int i = 0; i < params.length; i++) { String s = params[i].getName(); sb.append(s); if (i < params.length-1) { sb.append(", "); } } sb.append(")"); return sb.toString(); } public static String methodToString(Member member) { StringBuffer sb = new StringBuffer(member.getName()); if (member instanceof Method) { Class[] params = ((Method) member).getParameterTypes(); sb.append("("); for (int i = 0; i < params.length; i++) { String s = params[i].getName(); sb.append(s); if (i < params.length-1) { sb.append(", "); } } sb.append(")"); } return sb.toString(); } public static String memberToString(Member m) { if (m instanceof Field) { return toString((Field) m); } else { return methodToString((Method) m); } } public static String toString(Field field) { StringBuffer sb = new StringBuffer(field.getName()); sb.append("(").append(field.getName()).append(")"); return sb.toString(); } } libpicocontainer-java-2.15/org/picocontainer/monitors/ComposingMonitor.java000066400000000000000000000034001242247644300273600ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.monitors; import org.picocontainer.ComponentMonitor; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; /** * The first of a list of composers passed in that responds with an instance for a missing component will * be used. */ public class ComposingMonitor extends AbstractComponentMonitor { private Composer[] composers; public ComposingMonitor(ComponentMonitor delegate, Composer... composers) { super(delegate); this.composers = composers; } public ComposingMonitor(Composer... composers) { this.composers = composers; } @Override public Object noComponentFound(MutablePicoContainer container, Object componentKey) { for (Composer composer : composers) { Object retVal = composer.compose(container, componentKey); if (retVal != null) { return retVal; } } return super.noComponentFound(container, componentKey); } /** * A Composer can be used to make components that are otherwise missing. */ public static interface Composer { public Object compose(PicoContainer container, Object componentKey); } } libpicocontainer-java-2.15/org/picocontainer/monitors/ConsoleComponentMonitor.java000066400000000000000000000152441242247644300307200ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammaant * *****************************************************************************/ package org.picocontainer.monitors; import static org.picocontainer.monitors.ComponentMonitorHelper.ctorToString; import static org.picocontainer.monitors.ComponentMonitorHelper.format; import static org.picocontainer.monitors.ComponentMonitorHelper.memberToString; import static org.picocontainer.monitors.ComponentMonitorHelper.methodToString; import static org.picocontainer.monitors.ComponentMonitorHelper.parmsToString; import java.io.OutputStream; import java.io.PrintStream; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.Injector; import org.picocontainer.Behavior; /** * A {@link ComponentMonitor} which writes to a {@link OutputStream}. * This is typically used to write to a console. * (TODO After serialization, the output printstream is null) * * @author Paul Hammant * @author Aslak Hellesøy * @author Mauro Talevi */ @SuppressWarnings("serial") public class ConsoleComponentMonitor implements ComponentMonitor, Serializable { /** * The outgoing print stream. */ private final transient PrintStream out; /** * Delegate component monitor (for component monitor chains). */ private final ComponentMonitor delegate; /** * Constructs a console component monitor that sends output to System.out. */ public ConsoleComponentMonitor() { this(System.out); } /** * Constructs a console component monitor that sends output to the specified output stream. * * @param out the designated output stream. Options include System.out, Socket streams, File streams, * etc. */ public ConsoleComponentMonitor(OutputStream out) { this(out, new NullComponentMonitor()); } /** * Constructs a console component monitor chain that sends output to the specified output stream * and then sends all events to the delegate component monitor. * @param out the output stream of choice. * @param delegate the next monitor in the component monitor chain to receive event information. */ public ConsoleComponentMonitor(OutputStream out, ComponentMonitor delegate) { this.out = new PrintStream(out); this.delegate = delegate; } public Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor ) { out.println(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor))); return delegate.instantiating(container, componentAdapter, constructor); } public void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] parameters, long duration) { out.println(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(parameters))); delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration); } public void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception cause) { out.println(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage())); delegate.instantiationFailed(container, componentAdapter, constructor, cause); } public Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args) { out.println(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance)); return delegate.invoking(container, componentAdapter, member, instance, args); } public void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal) { out.println(format(ComponentMonitorHelper.INVOKED, methodToString(member), instance, duration)); delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal); } public void invocationFailed(Member member, Object instance, Exception cause) { out.println(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage())); delegate.invocationFailed(member, instance, cause); } public void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause) { out.println(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage())); delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause); } public Object noComponentFound(MutablePicoContainer container, Object componentKey) { out.println(format(ComponentMonitorHelper.NO_COMPONENT, componentKey)); return delegate.noComponentFound(container, componentKey); } public Injector newInjector(Injector injector) { return delegate.newInjector(injector); } /** {@inheritDoc} **/ public Behavior newBehavior(Behavior behavior) { return delegate.newBehavior(behavior); } } libpicocontainer-java-2.15/org/picocontainer/monitors/LifecycleComponentMonitor.java000066400000000000000000000134121242247644300312100ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.monitors; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.PicoException; import org.picocontainer.PicoLifecycleException; import org.picocontainer.Injector; import org.picocontainer.Behavior; /** * A {@link ComponentMonitor} which collects lifecycle failures * and rethrows them on demand after the failures. * * @author Paul Hammant * @author Mauro Talevi */ @SuppressWarnings("serial") public final class LifecycleComponentMonitor implements ComponentMonitor { /** * Delegate for chained component monitors. */ private final ComponentMonitor delegate; private final List lifecycleFailures = new ArrayList(); public LifecycleComponentMonitor(ComponentMonitor delegate) { this.delegate = delegate; } public LifecycleComponentMonitor() { this(new NullComponentMonitor()); } public Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor) { return delegate.instantiating(container, componentAdapter, constructor); } public void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] parameters, long duration) { delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration); } public void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception cause) { delegate.instantiationFailed(container, componentAdapter, constructor, cause); } public Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args) { return delegate.invoking(container, componentAdapter, member, instance, args); } public void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal) { delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal); } public void invocationFailed(Member member, Object instance, Exception cause) { delegate.invocationFailed(member, instance, cause); } public void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause) { lifecycleFailures.add(cause); try { delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause); } catch (PicoLifecycleException e) { // do nothing, exception already logged for later rethrow. } } public Object noComponentFound(MutablePicoContainer container, Object componentKey) { return delegate.noComponentFound(container, componentKey); } public Injector newInjector(Injector injector) { return delegate.newInjector(injector); } /** {@inheritDoc} **/ public Behavior newBehavior(Behavior behavior) { return delegate.newBehavior(behavior); } public void rethrowLifecycleFailuresException() { throw new LifecycleFailuresException(lifecycleFailures); } /** * Subclass of {@link PicoException} that is thrown when the collected * lifecycle failures need to be be collectively rethrown. * * @author Paul Hammant * @author Mauro Talevi */ public final class LifecycleFailuresException extends PicoException { private final List lifecycleFailures; public LifecycleFailuresException(List lifecycleFailures) { this.lifecycleFailures = lifecycleFailures; } public String getMessage() { StringBuffer message = new StringBuffer(); for (Object lifecycleFailure : lifecycleFailures) { Exception failure = (Exception)lifecycleFailure; message.append(failure.getMessage()).append("; "); } return message.toString(); } public Collection getFailures() { return lifecycleFailures; } } } libpicocontainer-java-2.15/org/picocontainer/monitors/NullComponentMonitor.java000066400000000000000000000067461242247644300302370ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammant & Obie Fernandez & Aslak Hellesøy * *****************************************************************************/ package org.picocontainer.monitors; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.PicoLifecycleException; import org.picocontainer.Injector; import org.picocontainer.Behavior; /** * A {@link ComponentMonitor} which does nothing. * * @author Paul Hammant * @author Obie Fernandez */ @SuppressWarnings("serial") public class NullComponentMonitor implements ComponentMonitor, Serializable { public Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor) { return constructor; } public void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception e) { } public void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] injected, long duration) { } public Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args) { return KEEP; } public void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal) { } public void invocationFailed(Member member, Object instance, Exception e) { } public void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause) { if (cause instanceof PicoLifecycleException) { throw cause; } throw new PicoLifecycleException(method, instance, cause); } public Object noComponentFound(MutablePicoContainer container, Object componentKey) { return null; } public Injector newInjector(Injector injector) { return injector; } /** {@inheritDoc} **/ public Behavior newBehavior(Behavior behavior) { return behavior; } } libpicocontainer-java-2.15/org/picocontainer/monitors/WriterComponentMonitor.java000066400000000000000000000130541242247644300305670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by Paul Hammaant * *****************************************************************************/ package org.picocontainer.monitors; import static org.picocontainer.monitors.ComponentMonitorHelper.ctorToString; import static org.picocontainer.monitors.ComponentMonitorHelper.format; import static org.picocontainer.monitors.ComponentMonitorHelper.memberToString; import static org.picocontainer.monitors.ComponentMonitorHelper.methodToString; import static org.picocontainer.monitors.ComponentMonitorHelper.parmsToString; import java.io.PrintWriter; import java.io.Writer; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentMonitor; import org.picocontainer.MutablePicoContainer; import org.picocontainer.PicoContainer; import org.picocontainer.Injector; import org.picocontainer.Behavior; /** * A {@link ComponentMonitor} which writes to a {@link Writer}. * * @author Paul Hammant * @author Aslak Hellesøy * @author Mauro Talevi */ public class WriterComponentMonitor implements ComponentMonitor { private final PrintWriter out; private final ComponentMonitor delegate; public WriterComponentMonitor(Writer out) { this(out, new NullComponentMonitor()); } public WriterComponentMonitor(Writer out, ComponentMonitor delegate) { this.out = new PrintWriter(out); this.delegate = delegate; } public Constructor instantiating(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor) { out.println(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor))); return delegate.instantiating(container, componentAdapter, constructor); } public void instantiated(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Object instantiated, Object[] injected, long duration) { out.println(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(injected))); delegate.instantiated(container, componentAdapter, constructor, instantiated, injected, duration); } public void instantiationFailed(PicoContainer container, ComponentAdapter componentAdapter, Constructor constructor, Exception cause) { out.println(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage())); delegate.instantiationFailed(container, null, constructor, cause); } public Object invoking(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, Object[] args) { out.println(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance)); return delegate.invoking(container, componentAdapter, member, instance, args); } public void invoked(PicoContainer container, ComponentAdapter componentAdapter, Member member, Object instance, long duration, Object[] args, Object retVal) { out.println(format(ComponentMonitorHelper.INVOKED, methodToString(member), instance, duration)); delegate.invoked(container, componentAdapter, member, instance, duration, args, retVal); } public void invocationFailed(Member member, Object instance, Exception cause) { out.println(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage())); delegate.invocationFailed(member, instance, cause); } public void lifecycleInvocationFailed(MutablePicoContainer container, ComponentAdapter componentAdapter, Method method, Object instance, RuntimeException cause) { out.println(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage())); delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause); } public Object noComponentFound(MutablePicoContainer container, Object componentKey) { out.println(format(ComponentMonitorHelper.NO_COMPONENT, componentKey)); return delegate.noComponentFound(container, componentKey); } public Injector newInjector(Injector injector) { return delegate.newInjector(injector); } /** {@inheritDoc} **/ public Behavior newBehavior(Behavior behavior) { return delegate.newBehavior(behavior); } } libpicocontainer-java-2.15/org/picocontainer/monitors/package.html000066400000000000000000000010501242247644300254670ustar00rootroot00000000000000 Insert title here

      A Monitor is something PicoContainer uses to inform on events in component instantiation and lifecycle. One use would be an instance based logger. Many alternative implementations in here.

      libpicocontainer-java-2.15/org/picocontainer/package.html000066400000000000000000000023021242247644300236160ustar00rootroot00000000000000

      This package contains the core API for PicoContainer, a compact container for working with the dependency injection pattern.

      When you use PicoContainer for dependency injection, you create a new instance of {@link org.picocontainer.MutablePicoContainer}, register classes (and possibly {@link org.picocontainer.ComponentAdapter}s and component instances created through other means).

      Object instances can then be accessed through the {@link org.picocontainer.PicoContainer} interface. The container will create all instances for you automatically, resolving their dependencies and order of instantiation. The default container implementation is the {@link org.picocontainer.DefaultPicoContainer} class.

      An extensive user guide, a list of Frequently Asked Questions (FAQ) with answers and a lot more information is available from the PicoContainer website. You can also find various extensions, wrappers and utility libraries that are based on this core API there.

      libpicocontainer-java-2.15/org/picocontainer/parameters/000077500000000000000000000000001242247644300235035ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/parameters/AbstractParameter.java000066400000000000000000000031461242247644300277560ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.parameters; import org.picocontainer.PicoContainer; import org.picocontainer.ComponentAdapter; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import java.lang.reflect.Type; import java.lang.annotation.Annotation; public abstract class AbstractParameter implements Parameter { @Deprecated public final Object resolveInstance(PicoContainer container, ComponentAdapter forAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { return resolve(container, forAdapter, null, expectedType, expectedNameBinding, useNames, binding).resolveInstance(); } @Deprecated public final boolean isResolvable(PicoContainer container, ComponentAdapter forAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { return resolve(container, forAdapter, null, expectedType, expectedNameBinding, useNames, binding).isResolved(); } } libpicocontainer-java-2.15/org/picocontainer/parameters/BasicComponentParameter.java000066400000000000000000000322161242247644300311170ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.parameters; import org.picocontainer.Behavior; import org.picocontainer.ComponentAdapter; import org.picocontainer.Converters; import org.picocontainer.Converting; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.LifecycleStrategy; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.adapters.InstanceAdapter; import org.picocontainer.injectors.AbstractInjector; import org.picocontainer.injectors.InjectInto; import org.picocontainer.injectors.Provider; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * A BasicComponentParameter should be used to pass in a particular component as argument to a * different component's constructor. This is particularly useful in cases where several * components of the same type have been registered, but with a different key. Passing a * ComponentParameter as a parameter when registering a component will give PicoContainer a hint * about what other component to use in the constructor. This Parameter will never resolve * against a collecting type, that is not directly registered in the PicoContainer itself. * * @author Jon Tirsén * @author Aslak Hellesøy * @author Jörg Schaible * @author Thomas Heller */ @SuppressWarnings("serial") public class BasicComponentParameter extends AbstractParameter implements Parameter, Serializable { /** BASIC_DEFAULT is an instance of BasicComponentParameter using the default constructor. */ public static final BasicComponentParameter BASIC_DEFAULT = new BasicComponentParameter(); private Object componentKey; /** * Expect a parameter matching a component of a specific key. * * @param componentKey the key of the desired addComponent */ public BasicComponentParameter(Object componentKey) { this.componentKey = componentKey; } /** Expect any parameter of the appropriate type. */ public BasicComponentParameter() { } /** * Check whether the given Parameter can be satisfied by the container. * * @return true if the Parameter can be verified. * * @throws org.picocontainer.PicoCompositionException * {@inheritDoc} * @see Parameter#isResolvable(PicoContainer, ComponentAdapter, Class, NameBinding ,boolean, Annotation) */ public Resolver resolve(final PicoContainer container, final ComponentAdapter forAdapter, final ComponentAdapter injecteeAdapter, final Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { Class resolvedClassType = null; // TODO take this out for Pico3 if (!(expectedType instanceof Class)) { if (expectedType instanceof ParameterizedType) { resolvedClassType = (Class) ((ParameterizedType)expectedType).getRawType(); } else { return new Parameter.NotResolved(); } } else { resolvedClassType = (Class)expectedType; } assert resolvedClassType != null; ComponentAdapter componentAdapter0; if (injecteeAdapter == null) { componentAdapter0 = resolveAdapter(container, forAdapter, resolvedClassType, expectedNameBinding, useNames, binding); } else { componentAdapter0 = injecteeAdapter; } final ComponentAdapter componentAdapter = componentAdapter0; return new Resolver() { public boolean isResolved() { return componentAdapter != null; } public Object resolveInstance() { if (componentAdapter == null) { return null; } if (componentAdapter instanceof DefaultPicoContainer.LateInstance) { return convert(getConverters(container), ((DefaultPicoContainer.LateInstance) componentAdapter).getComponentInstance(), expectedType); // } else if (injecteeAdapter != null && injecteeAdapter instanceof DefaultPicoContainer.KnowsContainerAdapter) { // return convert(((DefaultPicoContainer.KnowsContainerAdapter) injecteeAdapter).getComponentInstance(makeInjectInto(forAdapter)), expectedType); } else { return convert(getConverters(container), container.getComponent(componentAdapter.getComponentKey(), makeInjectInto(forAdapter)), expectedType); } } public ComponentAdapter getComponentAdapter() { return componentAdapter; } }; } private Converters getConverters(PicoContainer container) { return container instanceof Converting ? ((Converting) container).getConverters() : null; } private static InjectInto makeInjectInto(ComponentAdapter forAdapter) { return new InjectInto(forAdapter.getComponentImplementation(), forAdapter.getComponentKey()); } private static Object convert(Converters converters, Object obj, Type expectedType) { if (obj instanceof String && expectedType != String.class) { obj = converters.convert((String) obj, expectedType); } return obj; } public void verify(PicoContainer container, ComponentAdapter forAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { final ComponentAdapter componentAdapter = resolveAdapter(container, forAdapter, (Class)expectedType, expectedNameBinding, useNames, binding); if (componentAdapter == null) { final Set set = new HashSet(); set.add(expectedType); throw new AbstractInjector.UnsatisfiableDependenciesException( forAdapter.getComponentImplementation().getName() + " has unsatisfied dependencies: " + set + " from " + container); } componentAdapter.verify(container); } /** * Visit the current {@link Parameter}. * * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor) */ public void accept(final PicoVisitor visitor) { visitor.visitParameter(this); } protected ComponentAdapter resolveAdapter(PicoContainer container, ComponentAdapter adapter, Class expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { Class type = expectedType; if (type.isPrimitive()) { String expectedTypeName = expectedType.getName(); if (expectedTypeName == "int") { type = Integer.class; } else if (expectedTypeName == "long") { type = Long.class; } else if (expectedTypeName == "float") { type = Float.class; } else if (expectedTypeName == "double") { type = Double.class; } else if (expectedTypeName == "boolean") { type = Boolean.class; } else if (expectedTypeName == "char") { type = Character.class; } else if (expectedTypeName == "short") { type = Short.class; } else if (expectedTypeName == "byte") { type = Byte.class; } } ComponentAdapter result = null; if (componentKey != null) { // key tells us where to look so we follow result = typeComponentAdapter(container.getComponentAdapter(componentKey)); } else if (adapter == null) { result = container.getComponentAdapter(type, (NameBinding) null); } else { Object excludeKey = adapter.getComponentKey(); ComponentAdapter byKey = container.getComponentAdapter((Object)expectedType); if (byKey != null && !excludeKey.equals(byKey.getComponentKey())) { result = typeComponentAdapter(byKey); } if (result == null && useNames) { ComponentAdapter found = container.getComponentAdapter(expectedNameBinding.getName()); if ((found != null) && areCompatible(container, expectedType, found) && found != adapter) { result = found; } } if (result == null) { List> found = binding == null ? container.getComponentAdapters(expectedType) : container.getComponentAdapters(expectedType, binding.annotationType()); removeExcludedAdapterIfApplicable(excludeKey, found); if (found.size() == 0) { result = noMatchingAdaptersFound(container, expectedType, expectedNameBinding, binding); } else if (found.size() == 1) { result = found.get(0); } else { throw tooManyMatchingAdaptersFound(expectedType, found); } } } if (result == null) { return null; } if (!type.isAssignableFrom(result.getComponentImplementation())) { // if (!(result.getComponentImplementation() == String.class && stringConverters.containsKey(type))) { if (!(result.getComponentImplementation() == String.class && getConverters(container).canConvert(type))) { return null; } } return result; } @SuppressWarnings({ "unchecked" }) private static ComponentAdapter typeComponentAdapter(ComponentAdapter componentAdapter) { return (ComponentAdapter)componentAdapter; } private ComponentAdapter noMatchingAdaptersFound(PicoContainer container, Class expectedType, NameBinding expectedNameBinding, Annotation binding) { if (container.getParent() != null) { if (binding != null) { return container.getParent().getComponentAdapter(expectedType, binding.getClass()); } else { return container.getParent().getComponentAdapter(expectedType, expectedNameBinding); } } else { return null; } } private AbstractInjector.AmbiguousComponentResolutionException tooManyMatchingAdaptersFound(Class expectedType, List> found) { String[] foundStrings = makeFoundAmbiguousStrings(found); return new AbstractInjector.AmbiguousComponentResolutionException(expectedType, foundStrings); } public static String[] makeFoundAmbiguousStrings(Collection> found) { String[] foundStrings = new String[found.size()]; int ix = 0; for (ComponentAdapter f : found) { f = findInjectorOrInstanceAdapter(f); foundStrings[ix++] = f.toString(); } return foundStrings; } public static ComponentAdapter findInjectorOrInstanceAdapter(ComponentAdapter f) { while (f instanceof Behavior || (f instanceof LifecycleStrategy && !(f instanceof InstanceAdapter) && !(f instanceof Provider))) { f = f.getDelegate(); } return f; } private void removeExcludedAdapterIfApplicable(Object excludeKey, List> found) { ComponentAdapter exclude = null; for (ComponentAdapter work : found) { if (work.getComponentKey().equals(excludeKey)) { exclude = work; break; } } found.remove(exclude); } private boolean areCompatible(PicoContainer container, Class expectedType, ComponentAdapter found) { Class foundImpl = found.getComponentImplementation(); return expectedType.isAssignableFrom(foundImpl) || //(foundImpl == String.class && stringConverters.containsKey(expectedType)) ; (foundImpl == String.class && getConverters(container) != null && getConverters(container).canConvert(expectedType)) ; } } libpicocontainer-java-2.15/org/picocontainer/parameters/CollectionComponentParameter.java000066400000000000000000000442021242247644300321670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.parameters; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; import org.picocontainer.ComponentAdapter; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; /** * A CollectionComponentParameter should be used to support inject an {@link Array}, a * {@link Collection}or {@link Map}of components automatically. The collection will contain * all components of a special type and additionally the type of the key may be specified. In * case of a map, the map's keys are the one of the component adapter. * * @author Aslak Hellesøy * @author Jörg Schaible */ @SuppressWarnings("serial") public class CollectionComponentParameter extends AbstractParameter implements Parameter, Serializable { /** * Use ARRAY as {@link Parameter}for an Array that must have elements. */ public static final CollectionComponentParameter ARRAY = new CollectionComponentParameter(); /** * Use ARRAY_ALLOW_EMPTY as {@link Parameter}for an Array that may have no * elements. */ public static final CollectionComponentParameter ARRAY_ALLOW_EMPTY = new CollectionComponentParameter(true); private final boolean emptyCollection; private final Class componentKeyType; private final Class componentValueType; /** * Expect an {@link Array}of an appropriate type as parameter. At least one component of * the array's component type must exist. */ public CollectionComponentParameter() { this(false); } /** * Expect an {@link Array}of an appropriate type as parameter. * * @param emptyCollection true if an empty array also is a valid dependency * resolution. */ public CollectionComponentParameter(final boolean emptyCollection) { this(Void.TYPE, emptyCollection); } /** * Expect any of the collection types {@link Array},{@link Collection}or {@link Map}as * parameter. * * @param componentValueType the type of the components (ignored in case of an Array) * @param emptyCollection true if an empty collection resolves the * dependency. */ public CollectionComponentParameter(final Class componentValueType, final boolean emptyCollection) { this(Object.class, componentValueType, emptyCollection); } /** * Expect any of the collection types {@link Array},{@link Collection}or {@link Map}as * parameter. * * @param componentKeyType the type of the component's key * @param componentValueType the type of the components (ignored in case of an Array) * @param emptyCollection true if an empty collection resolves the * dependency. */ public CollectionComponentParameter(final Class componentKeyType, final Class componentValueType, final boolean emptyCollection) { this.emptyCollection = emptyCollection; this.componentKeyType = componentKeyType; this.componentValueType = componentValueType; } /** * Check for a successful dependency resolution of the parameter for the expected type. The * dependency can only be satisfied if the expected type is one of the collection types * {@link Array},{@link Collection}or {@link Map}. An empty collection is only a valid * resolution, if the emptyCollection flag was set. * * @param container {@inheritDoc} * @param injecteeAdapter *@param expectedType {@inheritDoc} * @param expectedNameBinding {@inheritDoc} * @param useNames * @param binding @return true if matching components were found or an empty collective type * is allowed */ public Resolver resolve(final PicoContainer container, final ComponentAdapter forAdapter, final ComponentAdapter injecteeAdapter, final Type expectedType, final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) { final Class collectionType = getCollectionType(expectedType); if (collectionType != null) { final Map> componentAdapters = getMatchingComponentAdapters(container, forAdapter, componentKeyType, getValueType(expectedType)); return new Resolver() { public boolean isResolved() { return emptyCollection || componentAdapters.size() > 0; } public Object resolveInstance() { Object result = null; if (collectionType.isArray()) { result = getArrayInstance(container, collectionType, componentAdapters); } else if (Map.class.isAssignableFrom(collectionType)) { result = getMapInstance(container, collectionType, componentAdapters); } else if (Collection.class.isAssignableFrom(collectionType)) { result = getCollectionInstance(container, collectionType, componentAdapters, expectedNameBinding, useNames); } else { throw new PicoCompositionException(expectedType + " is not a collective type"); } return result; } public ComponentAdapter getComponentAdapter() { return null; } }; } return new Parameter.NotResolved(); } private Class getCollectionType(final Type expectedType) { if (expectedType instanceof Class) { return getCollectionType((Class) expectedType); } else if (expectedType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) expectedType; return getCollectionType(type.getRawType()); } else if (expectedType instanceof GenericArrayType) { GenericArrayType type = (GenericArrayType) expectedType; Class baseType = getGenericArrayBaseType(type.getGenericComponentType()); return Array.newInstance(baseType, 0).getClass(); } throw new IllegalArgumentException("Unable to get collection type from " + expectedType); } private Class getGenericArrayBaseType(final Type expectedType) { if (expectedType instanceof Class) { Class type = (Class) expectedType; return type; } else if (expectedType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) expectedType; return getGenericArrayBaseType(type.getRawType()); } throw new IllegalArgumentException("Unable to get collection type from " + expectedType); } /** * Verify a successful dependency resolution of the parameter for the expected type. The * method will only return if the expected type is one of the collection types {@link Array}, * {@link Collection}or {@link Map}. An empty collection is only a valid resolution, if * the emptyCollection flag was set. * * @param container {@inheritDoc} * @param adapter {@inheritDoc} * @param expectedType {@inheritDoc} * @param expectedNameBinding {@inheritDoc} * @param useNames * @param binding * @throws PicoCompositionException {@inheritDoc} */ public void verify(final PicoContainer container, final ComponentAdapter adapter, final Type expectedType, final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) { final Class collectionType = getCollectionType(expectedType); if (collectionType != null) { final Class valueType = getValueType(expectedType); final Collection componentAdapters = getMatchingComponentAdapters(container, adapter, componentKeyType, valueType).values(); if (componentAdapters.isEmpty()) { if (!emptyCollection) { throw new PicoCompositionException(expectedType + " not resolvable, no components of type " + valueType.getName() + " available"); } } else { for (Object componentAdapter1 : componentAdapters) { final ComponentAdapter componentAdapter = (ComponentAdapter) componentAdapter1; componentAdapter.verify(container); } } } else { throw new PicoCompositionException(expectedType + " is not a collective type"); } } /** * Visit the current {@link Parameter}. * * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor) */ public void accept(final PicoVisitor visitor) { visitor.visitParameter(this); } /** * Evaluate whether the given component adapter will be part of the collective type. * * @param adapter a ComponentAdapter value * @return true if the adapter takes part */ protected boolean evaluate(final ComponentAdapter adapter) { return adapter != null; // use parameter, prevent compiler warning } /** * Collect the matching ComponentAdapter instances. * * @param container container to use for dependency resolution * @param adapter {@link ComponentAdapter} to exclude * @param keyType the compatible type of the key * @param valueType the compatible type of the addComponent * @return a {@link Map} with the ComponentAdapter instances and their component keys as map key. */ @SuppressWarnings({"unchecked"}) protected Map> getMatchingComponentAdapters(final PicoContainer container, final ComponentAdapter adapter, final Class keyType, final Class valueType) { final Map> adapterMap = new LinkedHashMap>(); final PicoContainer parent = container.getParent(); if (parent != null) { adapterMap.putAll(getMatchingComponentAdapters(parent, adapter, keyType, valueType)); } final Collection> allAdapters = container.getComponentAdapters(); for (ComponentAdapter componentAdapter : allAdapters) { adapterMap.remove(componentAdapter.getComponentKey()); } final List adapterList = List.class.cast(container.getComponentAdapters(valueType)); for (ComponentAdapter componentAdapter : adapterList) { final Object key = componentAdapter.getComponentKey(); if (adapter != null && key.equals(adapter.getComponentKey())) { continue; } if (keyType.isAssignableFrom(key.getClass()) && evaluate(componentAdapter)) { adapterMap.put(key, componentAdapter); } } return adapterMap; } private Class getCollectionType(final Class collectionType) { if (collectionType.isArray() || Map.class.isAssignableFrom(collectionType) || Collection.class.isAssignableFrom(collectionType)) { return collectionType; } return null; } private Class getValueType(final Type collectionType) { if (collectionType instanceof Class) { return getValueType((Class) collectionType); } else if (collectionType instanceof ParameterizedType) { return getValueType((ParameterizedType) collectionType); } else if (collectionType instanceof GenericArrayType) { GenericArrayType genericArrayType = (GenericArrayType) collectionType; return getGenericArrayBaseType(genericArrayType.getGenericComponentType()); } throw new IllegalArgumentException("Unable to determine collection type from " + collectionType); } private Class getValueType(final Class collectionType) { Class valueType = componentValueType; if (collectionType.isArray()) { valueType = collectionType.getComponentType(); } return valueType; } private Class getValueType(final ParameterizedType collectionType) { Class valueType = componentValueType; if (Collection.class.isAssignableFrom((Class) collectionType.getRawType())) { Type type = collectionType.getActualTypeArguments()[0]; if (type instanceof Class) { if (((Class)type).isAssignableFrom(valueType)) { return valueType; } valueType = (Class) type; } } return valueType; } private Object[] getArrayInstance(final PicoContainer container, final Class expectedType, final Map> adapterList) { final Object[] result = (Object[]) Array.newInstance(expectedType.getComponentType(), adapterList.size()); int i = 0; for (ComponentAdapter componentAdapter : adapterList.values()) { result[i] = container.getComponent(componentAdapter.getComponentKey()); i++; } return result; } @SuppressWarnings({"unchecked"}) private Collection getCollectionInstance(final PicoContainer container, final Class expectedType, final Map> adapterList, final NameBinding expectedNameBinding, final boolean useNames) { Class collectionType = expectedType; if (collectionType.isInterface()) { // The order of tests are significant. The least generic types last. if (List.class.isAssignableFrom(collectionType)) { collectionType = ArrayList.class; // } else if (BlockingQueue.class.isAssignableFrom(collectionType)) { // collectionType = ArrayBlockingQueue.class; // } else if (Queue.class.isAssignableFrom(collectionType)) { // collectionType = LinkedList.class; } else if (SortedSet.class.isAssignableFrom(collectionType)) { collectionType = TreeSet.class; } else if (Set.class.isAssignableFrom(collectionType)) { collectionType = HashSet.class; } else if (Collection.class.isAssignableFrom(collectionType)) { collectionType = ArrayList.class; } } try { Collection result = collectionType.newInstance(); for (ComponentAdapter componentAdapter : adapterList.values()) { if (!useNames || componentAdapter.getComponentKey() == expectedNameBinding) { result.add(container.getComponent(componentAdapter.getComponentKey())); } } return result; } catch (InstantiationException e) { ///CLOVER:OFF throw new PicoCompositionException(e); ///CLOVER:ON } catch (IllegalAccessException e) { ///CLOVER:OFF throw new PicoCompositionException(e); ///CLOVER:ON } } @SuppressWarnings({"unchecked"}) private Map getMapInstance(final PicoContainer container, final Class expectedType, final Map> adapterList) { Class collectionType = expectedType; if (collectionType.isInterface()) { // The order of tests are significant. The least generic types last. if (SortedMap.class.isAssignableFrom(collectionType)) { collectionType = TreeMap.class; // } else if (ConcurrentMap.class.isAssignableFrom(collectionType)) { // collectionType = ConcurrentHashMap.class; } else if (Map.class.isAssignableFrom(collectionType)) { collectionType = HashMap.class; } } try { Map result = collectionType.newInstance(); for (Map.Entry> entry : adapterList.entrySet()) { final Object key = entry.getKey(); result.put(key, container.getComponent(key)); } return result; } catch (InstantiationException e) { ///CLOVER:OFF throw new PicoCompositionException(e); ///CLOVER:ON } catch (IllegalAccessException e) { ///CLOVER:OFF throw new PicoCompositionException(e); ///CLOVER:ON } } } libpicocontainer-java-2.15/org/picocontainer/parameters/ComponentParameter.java000066400000000000000000000201771242247644300301600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Original code by * *****************************************************************************/ package org.picocontainer.parameters; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; import org.picocontainer.NameBinding; import org.picocontainer.injectors.AbstractInjector; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * A ComponentParameter should be used to pass in a particular component as argument to a * different component's constructor. This is particularly useful in cases where several * components of the same type have been registered, but with a different key. Passing a * ComponentParameter as a parameter when registering a component will give PicoContainer a hint * about what other component to use in the constructor. Collecting parameter types are * supported for {@link java.lang.reflect.Array},{@link java.util.Collection}and * {@link java.util.Map}. * * @author Jon Tirsén * @author Aslak Hellesøy * @author Jörg Schaible * @author Thomas Heller */ @SuppressWarnings("serial") public class ComponentParameter extends BasicComponentParameter { /** * DEFAULT is an instance of ComponentParameter using the default constructor. */ public static final ComponentParameter DEFAULT = new ComponentParameter(); /** * Use ARRAY as {@link Parameter}for an Array that must have elements. */ public static final ComponentParameter ARRAY = new ComponentParameter(false); /** * Use ARRAY_ALLOW_EMPTY as {@link Parameter}for an Array that may have no * elements. */ public static final ComponentParameter ARRAY_ALLOW_EMPTY = new ComponentParameter(true); private final Parameter collectionParameter; /** * Expect a parameter matching a component of a specific key. * * @param componentKey the key of the desired addComponent */ public ComponentParameter(Object componentKey) { this(componentKey, null); } /** * Expect any scalar parameter of the appropriate type or an {@link java.lang.reflect.Array}. */ public ComponentParameter() { this(false); } /** * Expect any scalar parameter of the appropriate type or an {@link java.lang.reflect.Array}. * Resolve the parameter even if no compnoent is of the array's component type. * * @param emptyCollection true allows an Array to be empty */ public ComponentParameter(boolean emptyCollection) { this(null, emptyCollection ? CollectionComponentParameter.ARRAY_ALLOW_EMPTY : CollectionComponentParameter.ARRAY); } /** * Expect any scalar parameter of the appropriate type or the collecting type * {@link java.lang.reflect.Array},{@link java.util.Collection}or {@link java.util.Map}. * The components in the collection will be of the specified type. * * @param componentValueType the component's type (ignored for an Array) * @param emptyCollection true allows the collection to be empty */ public ComponentParameter(Class componentValueType, boolean emptyCollection) { this(null, new CollectionComponentParameter(componentValueType, emptyCollection)); } /** * Expect any scalar parameter of the appropriate type or the collecting type * {@link java.lang.reflect.Array},{@link java.util.Collection}or {@link java.util.Map}. * The components in the collection will be of the specified type and their adapter's key * must have a particular type. * * @param componentKeyType the component adapter's key type * @param componentValueType the component's type (ignored for an Array) * @param emptyCollection true allows the collection to be empty */ public ComponentParameter(Class componentKeyType, Class componentValueType, boolean emptyCollection) { this(null, new CollectionComponentParameter(componentKeyType, componentValueType, emptyCollection)); } private ComponentParameter(Object componentKey, Parameter collectionParameter) { super(componentKey); this.collectionParameter = collectionParameter; } public Resolver resolve(final PicoContainer container, final ComponentAdapter forAdapter, final ComponentAdapter injecteeAdapter, final Type expectedType, final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) { return new Resolver() { final Resolver resolver = ComponentParameter.super.resolve(container, forAdapter, injecteeAdapter, expectedType, expectedNameBinding, useNames, binding); public boolean isResolved() { boolean superResolved = resolver.isResolved(); if (!superResolved) { if (collectionParameter != null) { return collectionParameter.resolve(container, forAdapter, null, expectedType, expectedNameBinding, useNames, binding).isResolved(); } return false; } return superResolved; } public Object resolveInstance() { Object result = null; if (expectedType instanceof Class) { result = ComponentParameter.super.resolve(container, forAdapter, injecteeAdapter, expectedType, expectedNameBinding, useNames, binding).resolveInstance(); } else if (expectedType instanceof ParameterizedType) { result = ComponentParameter.super.resolve(container, forAdapter, injecteeAdapter, ((ParameterizedType) expectedType).getRawType(), expectedNameBinding, useNames, binding).resolveInstance(); } if (result == null && collectionParameter != null) { result = collectionParameter.resolve(container, forAdapter, injecteeAdapter, expectedType, expectedNameBinding, useNames, binding).resolveInstance(); } return result; } public ComponentAdapter getComponentAdapter() { return resolver.getComponentAdapter(); } }; } public void verify(PicoContainer container, ComponentAdapter adapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { try { super.verify(container, adapter, expectedType, expectedNameBinding, useNames, binding); } catch (AbstractInjector.UnsatisfiableDependenciesException e) { if (collectionParameter != null) { collectionParameter.verify(container, adapter, expectedType, expectedNameBinding, useNames, binding); return; } throw e; } } /** * Accept the visitor for the current {@link Parameter}. If internally a * {@link CollectionComponentParameter}is used, it is visited also. * * @see BasicComponentParameter#accept(org.picocontainer.PicoVisitor) */ public void accept(PicoVisitor visitor) { super.accept(visitor); if (collectionParameter != null) { collectionParameter.accept(visitor); } } } libpicocontainer-java-2.15/org/picocontainer/parameters/ConstantParameter.java000066400000000000000000000102641242247644300300030ustar00rootroot00000000000000/***************************************************************************** * Copyright (c) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * * Idea by Rachel Davies, Original code by Jon Tirsen * *****************************************************************************/ package org.picocontainer.parameters; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoException; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoVisitor; import org.picocontainer.NameBinding; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.annotation.Annotation; /** * A ConstantParameter should be used to pass in "constant" arguments to constructors. This * includes {@link String}s,{@link Integer}s or any other object that is not registered in * the container. * * @author Jon Tirsén * @author Aslak Hellesøy * @author Jörg Schaible * @author Thomas Heller */ @SuppressWarnings("serial") public class ConstantParameter extends AbstractParameter implements Parameter, Serializable { private final Object value; public ConstantParameter(Object value) { this.value = value; } public Resolver resolve(PicoContainer container, ComponentAdapter forAdapter, ComponentAdapter injecteeAdapter, final Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { if (expectedType instanceof Class) { return new Parameter.ValueResolver(isAssignable((Class) expectedType), value, null); } else if (expectedType instanceof ParameterizedType) { return new Parameter.ValueResolver(isAssignable(((ParameterizedType)expectedType).getRawType()), value, null); } return new Parameter.ValueResolver(true, value, null); } /** * {@inheritDoc} * * @see Parameter#verify(org.picocontainer.PicoContainer,org.picocontainer.ComponentAdapter,java.lang.reflect.Type,org.picocontainer.NameBinding,boolean,java.lang.annotation.Annotation) */ public void verify(PicoContainer container, ComponentAdapter adapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) throws PicoException { if (!isAssignable(expectedType)) { throw new PicoCompositionException( expectedType + " is not assignable from " + (value != null ? value.getClass().getName() : "null")); } } protected boolean isAssignable(Type expectedType) { boolean isAssignable; if (expectedType instanceof Class) { Class expectedClass = (Class) expectedType; if (checkPrimitive(expectedClass) || expectedClass.isInstance(value)) { return true; } } return false; } /** * Visit the current {@link Parameter}. * * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor) */ public void accept(final PicoVisitor visitor) { visitor.visitParameter(this); } private boolean checkPrimitive(Class expectedType) { try { if (expectedType.isPrimitive()) { final Field field = value.getClass().getField("TYPE"); final Class type = (Class) field.get(value); return expectedType.isAssignableFrom(type); } } catch (NoSuchFieldException e) { //ignore } catch (IllegalAccessException e) { //ignore } return false; } } libpicocontainer-java-2.15/org/picocontainer/parameters/DefaultConstructorParameter.java000066400000000000000000000052711242247644300320460ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.parameters; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Type; import org.picocontainer.ComponentAdapter; import org.picocontainer.NameBinding; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; /** * Part of the replacement construct for Parameter.ZERO * @since PicoContainer 2.8 */ @SuppressWarnings("serial") public final class DefaultConstructorParameter extends AbstractParameter implements Parameter, Serializable { /** * The one and only instance */ public static final DefaultConstructorParameter INSTANCE = new DefaultConstructorParameter(); /** * No instantiation */ public void accept(PicoVisitor visitor) { visitor.visitParameter(this); } public Resolver resolve(PicoContainer container, ComponentAdapter forAdapter, ComponentAdapter injecteeAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { return new Parameter.NotResolved(); } public void verify(PicoContainer container, ComponentAdapter adapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { if (!(expectedType instanceof Class)) { throw new ClassCastException("Unable to use except for class types. Offending type: " + expectedType); } Class type = (Class)expectedType; try { Constructor constructor = type.getConstructor(); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("No default constructor for type " + expectedType,e ); } } @Override public String toString() { return "Force Default Constructor Parameter"; } /** * Returns true if the object object is a DEFAULT_CONSTRUCTOR object. * {@inheritDoc} * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object other) { if (other == null) { return false; } return (other.getClass().getName()).equals(getClass().getName()); } } libpicocontainer-java-2.15/org/picocontainer/parameters/NullParameter.java000066400000000000000000000063061242247644300271260ustar00rootroot00000000000000/******************************************************************************* * Copyright (C) PicoContainer Organization. All rights reserved. * --------------------------------------------------------------------------- * The software in this package is published under the terms of the BSD style * license a copy of which has been included with this distribution in the * LICENSE.txt file. ******************************************************************************/ package org.picocontainer.parameters; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import org.picocontainer.ComponentAdapter; import org.picocontainer.NameBinding; import org.picocontainer.PicoCompositionException; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVisitor; /** * Once in a great while, you actually want to pass in 'null' as an argument. Instead * of bypassing the type checking mechanisms available in * {@link org.picocontainer.parameters.ConstantParameter ConstantParameter}, we provide a Special Type * geared to marking nulls. * @author Michael Rimov * */ @SuppressWarnings("serial") public class NullParameter extends AbstractParameter implements Serializable { /** * The one and only instance of null parameter. */ public static final NullParameter INSTANCE = new NullParameter(); /** * Only once instance of Null parameter needed. */ protected NullParameter() { } /** * {@inheritDoc} * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor) */ public void accept(PicoVisitor visitor) { visitor.visitParameter(this); } /** * {@inheritDoc} * @see org.picocontainer.Parameter#resolve(org.picocontainer.PicoContainer, org.picocontainer.ComponentAdapter, org.picocontainer.ComponentAdapter, java.lang.reflect.Type, org.picocontainer.NameBinding, boolean, java.lang.annotation.Annotation) */ public Resolver resolve(PicoContainer container, ComponentAdapter forAdapter, ComponentAdapter injecteeAdapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { return new ValueResolver(isAssignable(expectedType), null, null); } /** * {@inheritDoc} * @see org.picocontainer.Parameter#verify(org.picocontainer.PicoContainer, org.picocontainer.ComponentAdapter, java.lang.reflect.Type, org.picocontainer.NameBinding, boolean, java.lang.annotation.Annotation) */ public void verify(PicoContainer container, ComponentAdapter adapter, Type expectedType, NameBinding expectedNameBinding, boolean useNames, Annotation binding) { if (!isAssignable(expectedType)) { throw new PicoCompositionException(expectedType + " cannot be assigned a null value"); } } /** * Nulls cannot be assigned to primitives. * @param expectedType * @return */ protected boolean isAssignable(Type expectedType) { if (expectedType instanceof Class) { Class expectedClass = Class.class.cast(expectedType); if (expectedClass.isPrimitive()) { return false; } } return true; } } libpicocontainer-java-2.15/org/picocontainer/references/000077500000000000000000000000001242247644300234615ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/references/SimpleReference.java000066400000000000000000000022421242247644300273740ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.references; import java.io.Serializable; import org.picocontainer.ObjectReference; /** * Simple instance implementation of ObjectReference. * * @author Aslak Hellesøy * @author Konstantin Pribluda */ @SuppressWarnings("serial") public class SimpleReference implements ObjectReference, Serializable { private T instance; public SimpleReference() { // no-op } public T get() { return instance; } public void set(T item) { this.instance = item; } } libpicocontainer-java-2.15/org/picocontainer/references/ThreadLocalMapObjectReference.java000066400000000000000000000026451242247644300321210ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.references; import org.picocontainer.ObjectReference; import java.util.Map; /** * Gets and sets references on a map stored in Thread Local * @author Paul Hammant */ public class ThreadLocalMapObjectReference implements ObjectReference { private final ThreadLocal> threadLocal; private final Object componentKey; public ThreadLocalMapObjectReference(ThreadLocal> threadLocal, Object componentKey) { this.threadLocal = threadLocal; this.componentKey = componentKey; } @SuppressWarnings("unchecked") public T get() { return threadLocal.get().get(componentKey) ; } @SuppressWarnings("unchecked") public void set(T item) { threadLocal.get().put(componentKey, item) ; } } libpicocontainer-java-2.15/org/picocontainer/references/ThreadLocalReference.java000066400000000000000000000024331242247644300303270ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.references; import org.picocontainer.ObjectReference; import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; /** * Gets and sets references on Thread Local * @author Paul Hammant */ @SuppressWarnings("serial") public class ThreadLocalReference extends ThreadLocal implements ObjectReference, Serializable { private void writeObject(final ObjectOutputStream out) { if(out != null); // eliminate warning because of unused parameter } private void readObject(final ObjectInputStream in) { if(in != null); // eliminate warning because of unused parameter } } libpicocontainer-java-2.15/org/picocontainer/security/000077500000000000000000000000001242247644300232075ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/security/CustomPermissionsURLClassLoader.java000066400000000000000000000070031242247644300322600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * * * *****************************************************************************/ package org.picocontainer.security; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Permissions; import java.security.PrivilegedAction; import java.util.Map; /** * CustomPermissionsURLClassLoader extends URLClassLoader, adding the abilty to programatically add permissions easily. * To be effective for permission management, it should be run in conjunction with a policy that restricts * some of the classloaders, but not all. * It's not ordinarily used by PicoContainer, but is here because PicoContainer is common * to most classloader trees. * * @author Paul Hammant */ public class CustomPermissionsURLClassLoader extends URLClassLoader { private final Map permissionsMap; public CustomPermissionsURLClassLoader(URL[] urls, Map permissionsMap, ClassLoader parent) { super(urls, parent); this.permissionsMap = permissionsMap; } public Class loadClass(String name) throws ClassNotFoundException { try { return super.loadClass(name); } catch (ClassNotFoundException e) { throw decorateException(name, e); } } protected Class findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException e) { throw decorateException(name, e); } } private ClassNotFoundException decorateException(String name, ClassNotFoundException e) { if (name.startsWith("class ")) { return new ClassNotFoundException("Class '" + name + "' is not a classInstance.getName(). " + "It's a classInstance.toString(). The clue is that it starts with 'class ', no classname contains a space."); } ClassLoader classLoader = this; StringBuffer sb = new StringBuffer("'").append(name).append("' classloader stack ["); while (classLoader != null) { sb.append(classLoader.toString()).append("\n"); final ClassLoader cl = classLoader; classLoader = AccessController.doPrivileged(new PrivilegedAction() { public ClassLoader run() { return cl.getParent(); } }); } return new ClassNotFoundException(sb.append("]").toString(), e); } public String toString() { String result = CustomPermissionsURLClassLoader.class.getName() + " " + System.identityHashCode(this) + ":"; URL[] urls = getURLs(); for (URL url : urls) { result += "\n\t" + url.toString(); } return result; } public PermissionCollection getPermissions(CodeSource codeSource) { return (Permissions) permissionsMap.get(codeSource.getLocation()); } } libpicocontainer-java-2.15/org/picocontainer/visitors/000077500000000000000000000000001242247644300232225ustar00rootroot00000000000000libpicocontainer-java-2.15/org/picocontainer/visitors/AbstractPicoVisitor.java000066400000000000000000000072221242247644300300260ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.visitors; import org.picocontainer.PicoVisitor; import org.picocontainer.PicoException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; /** * Abstract PicoVisitor implementation. A generic traverse method is implemented, that * accepts any object with a method named "accept", that takes a * {@link PicoVisitor} as argument and and invokes it. Additionally it provides the * {@link #checkTraversal()} method, that throws a {@link PicoVisitorTraversalException}, * if currently no traversal is running. * * @author Jörg Schaible */ @SuppressWarnings("serial") public abstract class AbstractPicoVisitor implements PicoVisitor { private boolean traversal; public Object traverse(final Object node) { traversal = true; Object retval = AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { return node.getClass().getMethod("accept", PicoVisitor.class); } catch (NoSuchMethodException e) { return e; } } }); try { if (retval instanceof NoSuchMethodException) { throw (NoSuchMethodException) retval; } Method accept = (Method) retval; accept.invoke(node, this); return Void.TYPE; } catch (NoSuchMethodException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { Throwable cause = e.getTargetException(); if (cause instanceof RuntimeException) { throw (RuntimeException)cause; } else if (cause instanceof Error) { throw (Error)cause; } } finally { traversal = false; } throw new IllegalArgumentException(node.getClass().getName() + " is not a valid type for traversal"); } /** * Checks the traversal flag, indicating a currently running traversal of the visitor. * @throws PicoVisitorTraversalException if no traversal is active. */ protected void checkTraversal() { if (!traversal) { throw new PicoVisitorTraversalException(this); } } /** * Exception for a PicoVisitor, that is dependent on a defined starting point of the traversal. * If the traversal is not initiated with a call of {@link PicoVisitor#traverse} * * @author joehni */ public static class PicoVisitorTraversalException extends PicoException { /** * Construct the PicoVisitorTraversalException. * * @param visitor The visitor casing the exception. */ public PicoVisitorTraversalException(PicoVisitor visitor) { super("Traversal for PicoVisitor of type " + visitor.getClass().getName() + " must start with the visitor's traverse method"); } } } libpicocontainer-java-2.15/org/picocontainer/visitors/MethodCallingVisitor.java000066400000000000000000000110151242247644300301550ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.visitors; import org.picocontainer.PicoContainer; import org.picocontainer.PicoCompositionException; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * A PicoVisitor implementation, that calls methods on the components of a specific type. * * @author Aslak Hellesøy * @author Jörg Schaible */ @SuppressWarnings("serial") public class MethodCallingVisitor extends TraversalCheckingVisitor implements Serializable { // TODO: we must serialize method with read/writeObject ... and are our parent serializable ??? private transient Method method; private final Object[] arguments; private final Class type; private final boolean visitInInstantiationOrder; private final List componentInstances; /** * Construct a MethodCallingVisitor for a method with arguments. * * @param method the {@link Method} to invoke * @param ofType the type of the components, that will be invoked * @param visitInInstantiationOrder true if components are visited in instantiation order * @param arguments the arguments for the method invocation (may be null) * @throws NullPointerException if method, or ofType is null */ public MethodCallingVisitor(Method method, Class ofType, Object[] arguments, boolean visitInInstantiationOrder) { if (method == null) { throw new NullPointerException(); } this.method = method; this.arguments = arguments; this.type = ofType; this.visitInInstantiationOrder = visitInInstantiationOrder; this.componentInstances = new ArrayList(); } /** * Construct a MethodCallingVisitor for standard methods visiting the component in instantiation order. * * @param method the method to invoke * @param ofType the type of the components, that will be invoked * @param arguments the arguments for the method invocation (may be null) * @throws NullPointerException if method, or ofType is null */ public MethodCallingVisitor(Method method, Class ofType, Object[] arguments) { this(method, ofType, arguments, true); } public Object traverse(Object node) { componentInstances.clear(); try { super.traverse(node); if (!visitInInstantiationOrder) { Collections.reverse(componentInstances); } for (Object componentInstance : componentInstances) { invoke(componentInstance); } } finally { componentInstances.clear(); } return Void.TYPE; } public boolean visitContainer(PicoContainer pico) { super.visitContainer(pico); componentInstances.addAll(pico.getComponents(type)); return CONTINUE_TRAVERSAL; } protected Method getMethod() { return method; } protected Object[] getArguments() { return arguments; } protected void invoke(final Object[] targets) { for (Object target : targets) { invoke(target); } } protected Class invoke(final Object target) { final Method method = getMethod(); try { method.invoke(target, getArguments()); } catch (IllegalArgumentException e) { throw new PicoCompositionException("Can't call " + method.getName() + " on " + target, e); } catch (IllegalAccessException e) { throw new PicoCompositionException("Can't call " + method.getName() + " on " + target, e); } catch (InvocationTargetException e) { throw new PicoCompositionException("Failed when calling " + method.getName() + " on " + target, e .getTargetException()); } return Void.TYPE; } } libpicocontainer-java-2.15/org/picocontainer/visitors/TraversalCheckingVisitor.java000066400000000000000000000041571242247644300310530ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.visitors; import org.picocontainer.ComponentAdapter; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.ComponentFactory; import org.picocontainer.visitors.AbstractPicoVisitor; /** * Concrete implementation of Visitor which simply checks traversals. * This can be a useful class for other Visitor implementations to extend, * as it provides a default implementation in case you one is only interested * in one PicoVisitor type. Example: * *
       * PicoContainer container = new DefaultPicoContainer();
       * PicoContainer child = container.makeChildContainer();
       *
       * final List allContainers = new ArrayList();
       *
       * PicoVisitor visitor = new TraversalCheckingVisitor() {
       *     public boolean visitContainer(PicoContainer pico) {
       *         super.visitContainer(pico);  //Calls checkTraversal for us.
       *         allContainers.add(pico);
       *         return true;
       *     }
       * }
       * 
      * * @author Michael Rimov */ public class TraversalCheckingVisitor extends AbstractPicoVisitor { /** {@inheritDoc} **/ public boolean visitContainer(PicoContainer pico) { checkTraversal(); return CONTINUE_TRAVERSAL; } /** {@inheritDoc} **/ public void visitComponentAdapter(ComponentAdapter componentAdapter) { checkTraversal(); } /** {@inheritDoc} **/ public void visitComponentFactory(ComponentFactory componentFactory) { checkTraversal(); } /** {@inheritDoc} **/ public void visitParameter(Parameter parameter) { checkTraversal(); } } libpicocontainer-java-2.15/org/picocontainer/visitors/VerifyingVisitor.java000066400000000000000000000105601242247644300274110ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) PicoContainer Organization. All rights reserved. * * ------------------------------------------------------------------------- * * The software in this package is published under the terms of the BSD * * style license a copy of which has been included with this distribution in * * the LICENSE.txt file. * *****************************************************************************/ package org.picocontainer.visitors; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.picocontainer.ComponentAdapter; import org.picocontainer.ComponentFactory; import org.picocontainer.Parameter; import org.picocontainer.PicoContainer; import org.picocontainer.PicoVerificationException; import org.picocontainer.PicoVisitor; /** * Visitor to verify {@link PicoContainer} instances. The visitor walks down the logical container hierarchy. * * @author Jörg Schaible */ public class VerifyingVisitor extends TraversalCheckingVisitor { private final List nestedVerificationExceptions; private final Set verifiedComponentAdapters; private final Set verifiedComponentFactories; private final PicoVisitor componentAdapterCollector; private PicoContainer currentPico; /** * Construct a VerifyingVisitor. */ public VerifyingVisitor() { nestedVerificationExceptions = new ArrayList(); verifiedComponentAdapters = new HashSet(); verifiedComponentFactories = new HashSet(); componentAdapterCollector = new ComponentAdapterCollector(); } /** * Traverse through all components of the {@link PicoContainer} hierarchy and verify the components. * * @throws PicoVerificationException if some components could not be verified. * @see org.picocontainer.PicoVisitor#traverse(java.lang.Object) */ public Object traverse(Object node) throws PicoVerificationException { nestedVerificationExceptions.clear(); verifiedComponentAdapters.clear(); try { super.traverse(node); if (!nestedVerificationExceptions.isEmpty()) { throw new PicoVerificationException(new ArrayList(nestedVerificationExceptions)); } } finally { nestedVerificationExceptions.clear(); verifiedComponentAdapters.clear(); } return Void.TYPE; } public boolean visitContainer(PicoContainer pico) { super.visitContainer(pico); currentPico = pico; return CONTINUE_TRAVERSAL; } public void visitComponentAdapter(ComponentAdapter componentAdapter) { super.visitComponentAdapter(componentAdapter); if (!verifiedComponentAdapters.contains(componentAdapter)) { try { componentAdapter.verify(currentPico); } catch (RuntimeException e) { nestedVerificationExceptions.add(e); } componentAdapter.accept(componentAdapterCollector); } } public void visitComponentFactory(ComponentFactory componentFactory) { super.visitComponentFactory(componentFactory); if (!verifiedComponentFactories.contains(componentFactory)) { try { componentFactory.verify(currentPico); } catch (RuntimeException e) { nestedVerificationExceptions.add(e); } componentFactory.accept(componentAdapterCollector); } } private class ComponentAdapterCollector implements PicoVisitor { // /CLOVER:OFF public Object traverse(Object node) { return null; } public boolean visitContainer(PicoContainer pico) { return CONTINUE_TRAVERSAL; } // /CLOVER:ON public void visitComponentAdapter(ComponentAdapter componentAdapter) { verifiedComponentAdapters.add(componentAdapter); } public void visitComponentFactory(ComponentFactory componentFactory) { verifiedComponentFactories.add(componentFactory); } public void visitParameter(Parameter parameter) { } } }