[jboss-cvs] JBossAS SVN: r93992 - in projects/microcontainer/branches/gatein_mc_pico: picocontainer-mc and 17 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Sep 24 10:08:12 EDT 2009
Author: mstruk
Date: 2009-09-24 10:08:11 -0400 (Thu, 24 Sep 2009)
New Revision: 93992
Added:
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/microcontainer/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/microcontainer/KernelControllerHelper.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Disposable.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/LifecycleManager.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/MutablePicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Parameter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInitializationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInstantiationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoIntrospectionException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoLifecycleException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoRegistrationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVerificationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Startable.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/AbstractDelegatingMutablePicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/CachingPicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/EmptyPicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImmutablePicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingCachingPicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingPicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractMonitoringLifecycleStrategy.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractPicoVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AmbiguousComponentResolutionException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AssignabilityRegistrationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BasicComponentParameter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CollectionComponentParameter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentMonitorStrategy.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentParameter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstantParameter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CustomPermissionsURLClassLoader.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyGuard.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultLifecycleStrategy.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultPicoContainer.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DelegatingComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DuplicateComponentKeyRegistrationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImmutablePicoContainerProxyFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstanceComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstantiatingComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleStrategy.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MapFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MethodCallingVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/NotConcreteRegistrationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ObjectReference.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoInvocationTargetInitializationException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoVisitorTraversalException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SimpleReference.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapter.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapterFactory.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ThreadLocalCyclicDependencyGuard.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TooManySatisfiableConstructorsException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TraversalCheckingVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/UnsatisfiableDependenciesException.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/VerifyingVisitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/package.html
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/AbstractComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/ConsoleComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/DefaultComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/LifecycleComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/NullComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/WriterComponentMonitor.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/package.html
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/KernelInstanceRefTest.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/ChildSingleton.java
projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/Singleton.java
Log:
Initial commit
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/microcontainer/KernelControllerHelper.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/microcontainer/KernelControllerHelper.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/jboss/microcontainer/KernelControllerHelper.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,61 @@
+package org.jboss.microcontainer;
+
+import org.jboss.kernel.plugins.dependency.AbstractKernelController;
+import org.jboss.kernel.plugins.dependency.ScopeHierarchyBuilder;
+import org.jboss.kernel.plugins.bootstrap.basic.BasicBootstrap;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.metadata.spi.scope.ScopeKey;
+import org.jboss.metadata.spi.scope.CommonLevels;
+import org.jboss.metadata.plugins.scope.ApplicationScope;
+import org.picocontainer.ComponentAdapter;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * @author <a href="mailto:mstrukel at redhat.com">Marko Strukelj</a>
+ */
+public class KernelControllerHelper {
+
+ private static AbstractKernelController singleton;
+
+ public synchronized static AbstractKernelController getRootKernelControllerInstance() {
+ if (singleton == null) {
+ BasicBootstrap bootstrap = new BasicBootstrap();
+ bootstrap.run();
+ singleton = (AbstractKernelController) bootstrap.getKernel().getController();
+ }
+ return singleton;
+ }
+
+ public static AbstractKernelController createChildKernelController(AbstractKernelController controller, String name) {
+ try {
+ return (AbstractKernelController) ScopeHierarchyBuilder.buildControllerHierarchy(controller,
+ controller.getKernel().getMetaDataRepository().getMetaDataRepository(),
+ new ScopeKey(CommonLevels.APPLICATION, name));
+ } catch (Throwable ex) {
+ throw new RuntimeException("Failed to create child controller: " + name + " (parent: " + controller + ")", ex);
+ }
+ }
+
+ public static Annotation getAppScopeAnnotation(final String name) {
+ return new ApplicationScope() {
+ public String value() {
+ return name;
+ }
+ public Class<? extends Annotation> annotationType() {
+ return ApplicationScope.class;
+ }
+ };
+ }
+
+ public static List<ComponentAdapter> unwrapComponentAdapters(final Set<ControllerContext> set) {
+ LinkedList<ComponentAdapter> ret = new LinkedList();
+ for (ControllerContext cc: set) {
+ ret.add((ComponentAdapter) cc.getTarget());
+ }
+ return ret;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * 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 component adapter is responsible for providing a specific component instance. An instance of an implementation of
+ * this interface is used inside a {@link PicoContainer} for every registered component or instance. Each
+ * <code>ComponentAdapter</code> 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.
+ *
+ * @author Jon Tirsén
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @version $Revision: 1801 $
+ * @see MutablePicoContainer an extension of the PicoContainer interface which allows you to modify the contents of the
+ * container.
+ * @since 1.0
+ */
+public interface ComponentAdapter {
+ /**
+ * 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.defaults.CachingComponentAdapter} 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 PicoInitializationException if the component could not be instantiated.
+ * @throws PicoIntrospectionException if the component has dependencies which could not be resolved, or
+ * instantiation of the component lead to an ambigous situation within the
+ * container.
+ */
+ Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException;
+
+ /**
+ * Verify that all dependencies for this adapter can be satisifed. Normally, the adapter should verify this by
+ * checking that the associated PicoContainer contains all the needed dependnecies.
+ *
+ * @param container the {@link PicoContainer}, that is used to resolve any possible dependencies of the instance.
+ * @throws PicoIntrospectionException if one or more dependencies cannot be resolved.
+ */
+ void verify(PicoContainer container) throws PicoIntrospectionException;
+
+ /**
+ * 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.
+ * @since 1.1
+ */
+ void accept(PicoVisitor visitor);
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/ComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ * 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.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
+ * @version $Revision: 2782 $
+ * @since 1.2
+ */
+public interface ComponentMonitor {
+
+ /**
+ * Event thrown as the component is being instantiated using the given constructor
+ *
+ * @param constructor the Constructor used to instantiate the component
+ */
+ void instantiating(Constructor constructor);
+
+ /**
+ * Event thrown after the component has been instantiated using the given constructor
+ *
+ * @param constructor the Constructor used to instantiate the component
+ * @param duration the duration in millis of the instantiation
+ */
+ void instantiated(Constructor constructor, long duration);
+
+ /**
+ * Event thrown if the component instantiation failed using the given constructor
+ *
+ * @param constructor the Constructor used to instantiate the component
+ * @param cause the Exception detailing the cause of the failure
+ */
+ void instantiationFailed(Constructor constructor, Exception cause);
+
+ /**
+ * Event thrown as the component method is being invoked on the given instance
+ *
+ * @param method the Method invoked on the component instance
+ * @param instance the component instance
+ */
+ void invoking(Method method, Object instance);
+
+ /**
+ * Event thrown after the component method has been invoked on the given instance
+ *
+ * @param method the Method invoked on the component instance
+ * @param instance the component instance
+ * @param duration the duration in millis of the invocation
+ */
+ void invoked(Method method, Object instance, long duration);
+
+ /**
+ * Event thrown if the component method invocation failed on the given instance
+ *
+ * @param method the Method invoked on the component instance
+ * @param instance the component instance
+ * @param cause the Exception detailing the cause of the failure
+ */
+ void invocationFailed(Method method, Object instance, Exception cause);
+
+ /**
+ * Event thrown if a lifecycle method invocation - start, stop or dispose -
+ * failed on the given instance
+ *
+ * @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(Method method, Object instance, RuntimeException cause);
+
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Disposable.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Disposable.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Disposable.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * 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).
+ * @version $Revision: 1570 $
+ * @see org.picocontainer.Startable the Startable interface if you need to <code>start()</code> and
+ * <code>stop()</code> semantics.
+ * @see org.picocontainer.PicoContainer the main PicoContainer interface (and hence its subinterfaces and
+ * implementations like {@link org.picocontainer.defaults.DefaultPicoContainer}) implement this interface.
+ * @since 1.0
+ */
+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();
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/LifecycleManager.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/LifecycleManager.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/LifecycleManager.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * 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;
+
+/**
+ * A manager for the lifecycle of a container's components.
+ * The lifecycle manager is implemented by the component adapters
+ * which will resolve the dependencies of the component instance and
+ * delegate the implementation of the lifecycle control to the
+ * {@link org.picocontainer.defaults.LifecycleStrategy lifecycle strategy}.
+ *
+ * @author Paul Hammant
+ * @author Jörg Schaible
+ * @author Mauro Talevi
+ * @version $Revision: 2631 $
+ * @see org.picocontainer.defaults.LifecycleStrategy
+ * @since 1.2
+ */
+public interface LifecycleManager {
+
+ /**
+ * Invoke the "start" method on the container's components.
+ * @param container the container to "start" its components' lifecycle
+ */
+ void start(PicoContainer container);
+
+ /**
+ * Invoke the "stop" method on the container's components.
+ * @param container the container to "stop" its components' lifecycle
+ */
+ void stop(PicoContainer container);
+
+ /**
+ * Invoke the "dispose" method on the container's components.
+ * @param container the container to "dispose" its components' lifecycle
+ */
+ void dispose(PicoContainer container);
+
+ /**
+ * Test if a container's component has a lifecycle.
+ * @return <code>true</code> if the component has a lifecycle
+ */
+ boolean hasLifecycle();
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/MutablePicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/MutablePicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/MutablePicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,162 @@
+/*****************************************************************************
+ * 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;
+
+/**
+ * This is the core interface used for registration of components with a container. It is possible to register {@link
+ * #registerComponentImplementation(Object,Class) an implementation class}, {@link #registerComponentInstance(Object) an
+ * instance} or {@link #registerComponent(ComponentAdapter) a ComponentAdapter}.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Jon Tirsén
+ * @version $Revision: 2285 $
+ * @see <a href="package-summary.html#package_description">See package description for basic overview how to use PicoContainer.</a>
+ * @since 1.0
+ */
+public interface MutablePicoContainer extends PicoContainer {
+
+ /**
+ * Register a component.
+ *
+ * @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 componentImplementation the component's implementation class. This must be a concrete class (ie, a
+ * class that can be instantiated).
+ * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
+ * value can be safely ignored, as one of the <code>getXXX()</code> methods of the
+ * {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
+ * @throws PicoRegistrationException if registration of the component fails.
+ * @see #registerComponentImplementation(Object,Class,Parameter[]) a variant of this method that allows more control
+ * over the parameters passed into the componentImplementation constructor when constructing an instance.
+ */
+ ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation);
+
+ /**
+ * Register a component.
+ *
+ * @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 componentImplementation the component's implementation class. This must be a concrete class (ie, a
+ * class that can be instantiated).
+ * @param parameters an array of 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 ComponentAdapter that has been associated with this component. In the majority of cases, this return
+ * value can be safely ignored, as one of the <code>getXXX()</code> methods of the
+ * {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
+ * @throws PicoRegistrationException if registration of the component fails.
+ */
+ ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters);
+
+ /**
+ * Register a component using the componentImplementation as key. Calling this method is equivalent to calling
+ * <code>registerComponentImplementation(componentImplementation, componentImplementation)</code>.
+ *
+ * @param componentImplementation the concrete component class.
+ * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
+ * value can be safely ignored, as one of the <code>getXXX()</code> methods of the
+ * {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
+ * @throws PicoRegistrationException if registration fails.
+ */
+ ComponentAdapter registerComponentImplementation(Class componentImplementation);
+
+ /**
+ * Register an arbitrary object. The class of the object will be used as a key. Calling this method is equivalent to
+ * calling * <code>registerComponentImplementation(componentImplementation, componentImplementation)</code>.
+ *
+ * @param componentInstance
+ * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
+ * value can be safely ignored, as one of the <code>getXXX()</code> methods of the
+ * {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
+ * @throws PicoRegistrationException if registration fails.
+ */
+ ComponentAdapter registerComponentInstance(Object componentInstance);
+
+ /**
+ * Register an arbitrary object as a component in the container. This is handy when other components in the same
+ * container have dependencies on this kind of object, but where letting the container manage and instantiate it is
+ * impossible.
+ * <p/>
+ * Beware that too much use of this method is an <a href="http://docs.codehaus.org/display/PICO/Instance+Registration">antipattern</a>.
+ *
+ * @param componentKey a key that identifies the component. Must be unique within the conainer. The type of the
+ * key object has no semantic significance unless explicitly specified in the implementing
+ * container.
+ * @param componentInstance an arbitrary object.
+ * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return
+ * value can be safely ignored, as one of the <code>getXXX()</code> methods of the
+ * {@link PicoContainer} interface can be used to retrieve a reference to the component later on.
+ * @throws PicoRegistrationException if registration fails.
+ */
+ ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance);
+
+ /**
+ * Register a component via a ComponentAdapter. Use this if you need fine grained control over what
+ * ComponentAdapter to use for a specific component.
+ *
+ * @param componentAdapter the adapter
+ * @return the same adapter that was passed as an argument.
+ * @throws PicoRegistrationException if registration fails.
+ */
+ ComponentAdapter registerComponent(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 unregisterComponent(Object componentKey);
+
+ /**
+ * Unregister a component by instance.
+ *
+ * @param componentInstance the component instance to unregister.
+ * @return the ComponentAdapter that was associated with this component.
+ */
+ ComponentAdapter unregisterComponentByInstance(Object componentInstance);
+
+ /**
+ * Make a child container, using the same implementation of MutablePicoContainer as the parent.
+ * 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.
+ *
+ * @return the new child container.
+ * @since 1.1
+ */
+ 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 <code>true</code> if the child container was not already in.
+ * @since 1.1
+ */
+ boolean 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 <code>true</code> if the child container has been removed.
+ * @since 1.1
+ */
+ boolean removeChildContainer(PicoContainer child);
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Parameter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Parameter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Parameter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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;
+
+/**
+ * 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#registerComponentImplementation(Object,Class,Parameter[]) a method on the
+ * {@link MutablePicoContainer} interface which allows passing in of an array of {@linkplain Parameter Parameters}.
+ * @see org.picocontainer.defaults.ComponentParameter an implementation of this interface that allows you to specify the key
+ * used for resolving the parameter.
+ * @see org.picocontainer.defaults.ConstantParameter an implementation of this interface that allows you to specify a constant
+ * that will be used for resolving the parameter.
+ * @since 1.0
+ */
+public interface Parameter {
+ /**
+ * Retrieve the object from the Parameter that statisfies the expected type.
+ *
+ * @param container the container from which dependencies are resolved.
+ * @param adapter the {@link ComponentAdapter} that is asking for the instance
+ * @param expectedType the type that the returned instance needs to match.
+ * @return the instance or <code>null</code> if no suitable instance can be found.
+ * @throws PicoInitializationException if a referenced component could not be instantiated.
+ * @since 1.1
+ */
+ Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType);
+
+ /**
+ * Check if the Parameter can statisfy 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 instance
+ * @param expectedType the required type
+ * @return <code>true</code> if the component parameter can be resolved.
+ * @since 1.1
+ */
+ boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType);
+
+ /**
+ * Verify that the Parameter can statisfied 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
+ * @throws PicoIntrospectionException if parameter and its dependencies cannot be resolved
+ * @since 1.1
+ */
+ void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType);
+
+ /**
+ * 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.
+ * @since 1.1
+ */
+ void accept(PicoVisitor visitor);
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * 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;
+
+
+/**
+ * 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 org.picocontainer.defaults.DefaultPicoContainer}.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Jon Tirsén
+ * @version $Revision: 2285 $
+ * @see <a href="package-summary.html#package_description">See package description for basic overview how to use
+ * PicoContainer.</a>
+ * @since 1.0
+ */
+public interface PicoContainer extends Startable, Disposable {
+
+ /**
+ * Retrieve a component instance registered with a specific key. If a component 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 an instantiated component, or <code>null</code> if no component has been registered for the specified
+ * key.
+ */
+ Object getComponentInstance(Object componentKey);
+
+ /**
+ * Find a component instance matching the specified type.
+ *
+ * @param componentType the type of the component
+ * @return an instantiated component matching the class, or <code>null</code> if no component has been registered
+ * with a matching type
+ * @throws PicoException if the instantiation of the component fails
+ */
+ Object getComponentInstanceOfType(Class componentType);
+
+ /**
+ * 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 getComponentInstances();
+
+ /**
+ * Retrieve the parent container of this container.
+ *
+ * @return a {@link PicoContainer} instance, or <code>null</code> 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 <code>null</code> if no component has been
+ * registered for the specified key.
+ */
+ ComponentAdapter getComponentAdapter(Object componentKey);
+
+ /**
+ * Find a component adapter associated with the specified 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 <code>null</code> if no component has been
+ * registered for the specified key.
+ */
+ ComponentAdapter getComponentAdapterOfType(Class componentType);
+
+ /**
+ * 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 #getComponentAdaptersOfType(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 component
+ * 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 getComponentAdaptersOfType(Class componentType);
+
+ /**
+ * Verify that the dependencies for all the registered components can be satisfied. No components are instantiated
+ * during the verification process.
+ *
+ * @throws PicoVerificationException if there are unsatisifiable dependencies.
+ * @deprecated since 1.1 - Use "new VerifyingVisitor().traverse(this)"
+ */
+ void verify() throws PicoVerificationException;
+
+ /**
+ * 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
+ * @since 1.1
+ */
+ List getComponentInstancesOfType(Class componentType);
+
+ /**
+ * Accepts a visitor that should visit the child containers, component adapters and component instances.
+ *
+ * @param visitor the visitor
+ * @since 1.1
+ */
+ void accept(PicoVisitor visitor);
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,110 @@
+/*****************************************************************************
+ * 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.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * 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
+ * <code>null</code> values are provided for method arguments, and this is not allowed.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @version $Revision: 1812 $
+ * @since 1.0
+ */
+public abstract class PicoException extends RuntimeException {
+ /**
+ * The exception that caused this one.
+ */
+ private Throwable cause;
+
+ /**
+ * 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) {
+ this.cause = 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);
+ this.cause = cause;
+ }
+
+ /**
+ * Retrieve the exception that caused this one.
+ *
+ * @return the exception that caused this one, or null if it was not set.
+ * @see Throwable#getCause() the method available since JDK 1.4 that is overridden by this method.
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+
+ /**
+ * Overridden to provide 1.4 style stack traces on pre-1.4.
+ *
+ * @param s the {@link PrintStream} used to print the stack trace
+ */
+ public void printStackTrace() {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Overridden to provide 1.4 style stack traces on pre-1.4.
+ */
+ public void printStackTrace(PrintStream s) {
+ super.printStackTrace(s);
+ if(cause!=null) {
+ s.println("Caused by:\n");
+ cause.printStackTrace(s);
+ }
+ }
+
+ /**
+ * Overridden to provide 1.4 style stack traces on pre-1.4.
+ *
+ * @param s the {@link PrintWriter} used to print the stack trace
+ */
+ public void printStackTrace(PrintWriter s) {
+ super.printStackTrace(s);
+ if(cause!=null) {
+ s.println("Caused by:\n");
+ cause.printStackTrace(s);
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInitializationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInitializationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInitializationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * 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 or some other
+ * part of the PicoContainer api, for example, when a cyclic dependency between components occurs.
+ *
+ * @version $Revision$
+ * @since 1.0
+ */
+public class PicoInitializationException extends PicoException {
+ /**
+ * Construct a new exception with no cause and no detail message. Note modern JVMs may still track the exception
+ * that caused this one.
+ * @deprecated Use public constructors
+ */
+ protected PicoInitializationException() {
+ }
+
+ /**
+ * 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 PicoInitializationException(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 PicoInitializationException(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 PicoInitializationException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInstantiationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInstantiationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoInstantiationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * 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 creating an instance of a container or some
+ * other part of the PicoContainer api, for example, when an invocation through the reflection api fails.
+ *
+ * @version $Revision$
+ * @since 1.0
+ * @deprecated since 1.2; it was actually not instantiated anywhere
+ */
+public class PicoInstantiationException extends PicoInitializationException {
+ /**
+ * 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.
+ * @deprecated since 1.2; it was actually not instantiated anywhere
+ */
+ protected PicoInstantiationException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoIntrospectionException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoIntrospectionException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoIntrospectionException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * 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;
+
+/**
+ * Subclass of {@link PicoException} that is thrown when there is a problem creating, providing or locating a component
+ * instance or a part of the PicoContainer API, for example, when a request for a component is ambiguous.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @version $Revision: 1.3 $
+ * @since 1.0
+ */
+public class PicoIntrospectionException 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 PicoIntrospectionException(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 PicoIntrospectionException(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 PicoIntrospectionException(final String message, final Throwable cause) {
+ super(message,cause);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoLifecycleException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoLifecycleException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoLifecycleException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * 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;
+
+public class PicoLifecycleException extends PicoException {
+
+ private final Method method;
+ private final Object instance;
+
+ public PicoLifecycleException(final Method method, final Object instance, final RuntimeException 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();
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoRegistrationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoRegistrationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoRegistrationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * 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 registering a component with the container
+ * or another part of the PicoContainer API, for example, when a request for a component is ambiguous.
+ *
+ * @version $Revision$
+ * @since 1.0
+ */
+public class PicoRegistrationException 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 PicoRegistrationException(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 PicoRegistrationException(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 PicoRegistrationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVerificationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVerificationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVerificationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * 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 occuring at the verification of the complete container
+ * hierarchy. The verification is normally done with the
+ * {@link org.picocontainer.defaults.VerifyingVisitor}, that will throw this exception.
+ *
+ * @version $Revision: 1801 $
+ * @since 1.0
+ */
+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();
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/PicoVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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
+ * @version $Revision: 1753 $
+ * @since 1.1
+ */
+public interface PicoVisitor {
+ /**
+ * 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.
+ * @since 1.1
+ */
+ Object traverse(Object node);
+
+ /**
+ * Visit a {@link PicoContainer} that has to accept the visitor.
+ *
+ * @param pico the visited container.
+ * @since 1.1
+ */
+
+ void visitContainer(PicoContainer pico);
+ /**
+ * Visit a {@link ComponentAdapter} that has to accept the visitor.
+ *
+ * @param componentAdapter the visited ComponentAdapter.
+ * @since 1.1
+ */
+
+ void visitComponentAdapter(ComponentAdapter componentAdapter);
+ /**
+ * Visit a {@link Parameter} that has to accept the visitor.
+ *
+ * @param parameter the visited Parameter.
+ * @since 1.1
+ */
+ void visitParameter(Parameter parameter);
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Startable.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Startable.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/Startable.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * 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;
+
+/**
+ * <p>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()}.</p>
+ * <p/>
+ * <p>For more advanced and pluggable lifecycle support, see the functionality offered by picocontainer-gems
+ * subproject.</p>
+ * @version $Revision: 2281 $
+ * @see org.picocontainer.Disposable the Disposable interface if you need to <code>dispose()</code> semantics.
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @since 1.0
+ */
+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();
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/AbstractDelegatingMutablePicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/AbstractDelegatingMutablePicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/AbstractDelegatingMutablePicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoException;
+import org.picocontainer.PicoRegistrationException;
+import org.picocontainer.PicoVerificationException;
+import org.picocontainer.PicoVisitor;
+
+/**
+ * @author Paul Hammant
+ * @version $Revision: 2230 $
+ */
+public abstract class AbstractDelegatingMutablePicoContainer implements MutablePicoContainer, Serializable {
+
+ private MutablePicoContainer delegate;
+
+ public AbstractDelegatingMutablePicoContainer(MutablePicoContainer delegate) {
+ this.delegate = delegate;
+ }
+
+ protected MutablePicoContainer getDelegate() {
+ return delegate;
+ }
+
+ public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) throws PicoRegistrationException {
+ return delegate.registerComponentImplementation(componentKey, componentImplementation);
+ }
+
+ public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException {
+ return delegate.registerComponentImplementation(componentKey, componentImplementation, parameters);
+ }
+
+
+ public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException {
+ return delegate.registerComponentImplementation(componentImplementation);
+ }
+
+ public ComponentAdapter registerComponentInstance(Object componentInstance) throws PicoRegistrationException {
+ return delegate.registerComponentInstance(componentInstance);
+ }
+
+ public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException {
+ return delegate.registerComponentInstance(componentKey, componentInstance);
+ }
+
+ public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws PicoRegistrationException {
+ return delegate.registerComponent(componentAdapter);
+ }
+
+ public ComponentAdapter unregisterComponent(Object componentKey) {
+ return delegate.unregisterComponent(componentKey);
+ }
+
+ public ComponentAdapter unregisterComponentByInstance(Object componentInstance) {
+ return delegate.unregisterComponentByInstance(componentInstance);
+ }
+
+ public Object getComponentInstance(Object componentKey) {
+ return delegate.getComponentInstance(componentKey);
+ }
+
+ public Object getComponentInstanceOfType(Class componentType) {
+ return delegate.getComponentInstanceOfType(componentType);
+ }
+
+ public List getComponentInstances() {
+ return delegate.getComponentInstances();
+ }
+
+ public PicoContainer getParent() {
+ return delegate.getParent();
+ }
+
+ public ComponentAdapter getComponentAdapter(Object componentKey) {
+ return delegate.getComponentAdapter(componentKey);
+ }
+
+ public ComponentAdapter getComponentAdapterOfType(Class componentType) {
+ return delegate.getComponentAdapterOfType(componentType);
+ }
+
+ public Collection getComponentAdapters() {
+ return delegate.getComponentAdapters();
+ }
+
+ public List getComponentAdaptersOfType(Class componentType) {
+ return delegate.getComponentAdaptersOfType(componentType);
+ }
+
+ /**
+ * @deprecated since 1.1 - Use new VerifyingVisitor().traverse(this)
+ */
+ public void verify() throws PicoVerificationException {
+ delegate.verify();
+ }
+
+ public void start() {
+ delegate.start();
+ }
+
+ public void stop() {
+ delegate.stop();
+ }
+
+ public void dispose() {
+ delegate.dispose();
+ }
+
+ public boolean addChildContainer(PicoContainer child) {
+ return delegate.addChildContainer(child);
+ }
+
+ public boolean removeChildContainer(PicoContainer child) {
+ return delegate.removeChildContainer(child);
+ }
+
+ public void accept(PicoVisitor visitor) {
+ delegate.accept(visitor);
+ }
+
+ public List getComponentInstancesOfType(Class type) throws PicoException {
+ return delegate.getComponentInstancesOfType(type);
+ }
+
+ 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)
+ final boolean result = delegate.equals(obj) || this == obj;
+ return result;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/CachingPicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/CachingPicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/CachingPicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import java.io.Serializable;
+
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.defaults.CachingComponentAdapterFactory;
+import org.picocontainer.defaults.ComponentAdapterFactory;
+import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory;
+import org.picocontainer.defaults.DefaultPicoContainer;
+
+/**
+ * The Caching version of {@link org.picocontainer.defaults.DefaultPicoContainer}
+ *
+ * @see ImplementationHidingCachingPicoContainer
+ * @see ImplementationHidingPicoContainer
+ * @author Paul Hammant
+ * @version $Revision: 2381 $
+ */
+public class CachingPicoContainer extends AbstractDelegatingMutablePicoContainer implements Serializable {
+ private final ComponentAdapterFactory caf;
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public CachingPicoContainer(ComponentAdapterFactory caf, PicoContainer parent) {
+ super(new DefaultPicoContainer(makeComponentAdapterFactory(caf), parent));
+ this.caf = caf;
+ }
+
+ private static CachingComponentAdapterFactory makeComponentAdapterFactory(ComponentAdapterFactory caf) {
+ if (caf instanceof CachingComponentAdapterFactory) {
+ return (CachingComponentAdapterFactory) caf;
+ }
+ return new CachingComponentAdapterFactory(caf);
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public CachingPicoContainer(PicoContainer parent) {
+ this(makeComponentAdapterFactory(new ConstructorInjectionComponentAdapterFactory()), parent);
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public CachingPicoContainer(ComponentAdapterFactory caf) {
+ this(makeComponentAdapterFactory(caf), null);
+ }
+
+
+ /**
+ * Creates a new container with no parent container.
+ */
+ public CachingPicoContainer() {
+ this((PicoContainer) null);
+ }
+
+
+ public MutablePicoContainer makeChildContainer() {
+ CachingPicoContainer pc = new CachingPicoContainer(caf, this);
+ getDelegate().addChildContainer(pc);
+ return pc;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/EmptyPicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/EmptyPicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/EmptyPicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Collection;
+import java.util.List;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoVisitor;
+import org.picocontainer.ComponentAdapter;
+
+/**
+ * empty pico container serving as recoil damper in situations where you
+ * do not like to check whether container reference suplpied to you
+ * is null or not
+ * @author Konstantin Pribluda
+ * @since 1.1
+*/
+public class EmptyPicoContainer implements PicoContainer, Serializable {
+ public Object getComponentInstance(Object componentKey) {
+ return null;
+ }
+
+ public Object getComponentInstanceOfType(Class componentType) {
+ return null;
+ }
+ public List getComponentInstances() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public PicoContainer getParent() {
+ return null;
+ }
+ public ComponentAdapter getComponentAdapter(Object componentKey) {
+ return null;
+ }
+
+ public ComponentAdapter getComponentAdapterOfType(Class componentType) {
+ return null;
+ }
+
+ public Collection getComponentAdapters() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public List getComponentAdaptersOfType(Class componentType) {
+ return Collections.EMPTY_LIST;
+ }
+
+ public void verify() {}
+
+ public void accept(PicoVisitor visitor) { }
+
+ public List getComponentInstancesOfType(Class componentType) {
+ return Collections.EMPTY_LIST;
+ }
+
+ public void start() {}
+ public void stop() {}
+ public void dispose() {}
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImmutablePicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImmutablePicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImmutablePicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoException;
+import org.picocontainer.PicoVerificationException;
+import org.picocontainer.PicoVisitor;
+import org.picocontainer.defaults.VerifyingVisitor;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+// TODO: replace this with a proxy? It don't do nothing! (AH)
+// Am open to elegant solution. This, at least, is instantiable (PH)
+
+/**
+ * @author Paul Hammant
+ * @version $Revision: 2286 $
+ * @since 1.1
+ * @deprecated since 1.2, use the {@link org.picocontainer.defaults.ImmutablePicoContainerProxyFactory}
+ */
+public class ImmutablePicoContainer implements PicoContainer, Serializable {
+
+ private PicoContainer delegate;
+
+ public ImmutablePicoContainer(PicoContainer delegate) {
+ if(delegate == null) throw new NullPointerException("You must pass in a picoContainer instance");
+ this.delegate = delegate;
+ }
+
+ public Object getComponentInstance(Object componentKey) {
+ return delegate.getComponentInstance(componentKey);
+ }
+
+ public Object getComponentInstanceOfType(Class componentType) {
+ return delegate.getComponentInstanceOfType(componentType);
+ }
+
+ public List getComponentInstances() {
+ return delegate.getComponentInstances();
+ }
+
+ public synchronized PicoContainer getParent() {
+ return delegate.getParent();
+ }
+
+ public ComponentAdapter getComponentAdapter(Object componentKey) {
+ return delegate.getComponentAdapter(componentKey);
+ }
+
+ public ComponentAdapter getComponentAdapterOfType(Class componentType) {
+ return delegate.getComponentAdapterOfType(componentType);
+ }
+
+ public Collection getComponentAdapters() {
+ return delegate.getComponentAdapters();
+ }
+
+ public List getComponentAdaptersOfType(Class componentType) {
+ return delegate.getComponentAdaptersOfType(componentType);
+ }
+
+ /**
+ * @deprecated since 1.1 - Use "new VerifyingVisitor().traverse(this)"
+ */
+ public void verify() throws PicoVerificationException {
+ new VerifyingVisitor().traverse(this);
+ }
+
+ public List getComponentInstancesOfType(Class type) throws PicoException {
+ return delegate.getComponentInstancesOfType(type);
+ }
+
+ public void accept(PicoVisitor visitor) {
+ delegate.accept(visitor);
+ }
+
+ public void start() {
+ // This is false security. As long as components can be accessed with getComponentInstance(), they can also be started. (AH).
+ throw new UnsupportedOperationException("This container is immutable, start() is not allowed");
+ }
+
+ public void stop() {
+ // This is false security. As long as components can be accessed with getComponentInstance(), they can also be stopped. (AH).
+ throw new UnsupportedOperationException("This container is immutable, stop() is not allowed");
+ }
+
+ public void dispose() {
+ // This is false security. As long as components can be accessed with getComponentInstance(), they can also be disposed. (AH).
+ throw new UnsupportedOperationException("This container is immutable, dispose() is not allowed");
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingCachingPicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingCachingPicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingCachingPicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import java.io.Serializable;
+
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.defaults.CachingComponentAdapterFactory;
+import org.picocontainer.defaults.ComponentAdapterFactory;
+import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory;
+import org.picocontainer.defaults.DefaultPicoContainer;
+
+/**
+ * This special MutablePicoContainer hides implementations of components if the key is an interface.
+ * It's very simple. Instances that are registered directly and components registered without key
+ * are not hidden. Hiding is achieved with dynamic proxies from Java's reflection api. It also exhibits caching
+ * functionality.
+ *
+ * @see CachingPicoContainer
+ * @see ImplementationHidingPicoContainer
+ * @author Paul Hammant
+ * @version $Revision: 2424 $
+ * @since 1.1
+ */
+public class ImplementationHidingCachingPicoContainer extends AbstractDelegatingMutablePicoContainer implements Serializable {
+ private final ComponentAdapterFactory caf;
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingCachingPicoContainer(ComponentAdapterFactory caf, PicoContainer parent) {
+ super(new DefaultPicoContainer(makeComponentAdapterFactory(caf), parent));
+ this.caf = caf;
+ }
+
+ private static CachingComponentAdapterFactory makeComponentAdapterFactory(ComponentAdapterFactory caf) {
+ if (caf instanceof CachingComponentAdapterFactory) {
+ // assume that implementation hiding CAF inside Caching one.
+ return (CachingComponentAdapterFactory) caf;
+ }
+ if (caf instanceof ImplementationHidingComponentAdapterFactory) {
+ return new CachingComponentAdapterFactory(caf);
+ }
+ return new CachingComponentAdapterFactory(new ImplementationHidingComponentAdapterFactory(caf, false));
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingCachingPicoContainer(PicoContainer parent) {
+ this(makeComponentAdapterFactory(new ConstructorInjectionComponentAdapterFactory()), parent);
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingCachingPicoContainer(ComponentAdapterFactory caf) {
+ this(makeComponentAdapterFactory(caf), null);
+ }
+
+
+ /**
+ * Creates a new container with no parent container.
+ */
+ public ImplementationHidingCachingPicoContainer() {
+ this((PicoContainer) null);
+ }
+
+
+ public MutablePicoContainer makeChildContainer() {
+ ImplementationHidingCachingPicoContainer pc = new ImplementationHidingCachingPicoContainer(caf, this);
+ getDelegate().addChildContainer(pc);
+ return pc;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import org.picocontainer.ComponentAdapter;
+
+
+/**
+ * This component adapter makes it possible to hide the implementation of a real subject (behind a proxy) provided the
+ * key is an interface. <p/> 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.HotSwappingComponentAdapter for a more feature-rich version of this class.
+ * @since 1.1
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+public class ImplementationHidingComponentAdapter extends
+ org.picocontainer.defaults.ImplementationHidingComponentAdapter {
+
+ /**
+ * Creates an ImplementationHidingComponentAdapter with a delegate
+ *
+ * @param delegate the component adapter to which this adapter delegates
+ * @param strict the scrict mode boolean
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+ public ImplementationHidingComponentAdapter(ComponentAdapter delegate, boolean strict) {
+ super(delegate, strict);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import org.picocontainer.defaults.ComponentAdapterFactory;
+
+
+/**
+ * @author Aslak Hellesøy
+ * @see org.picocontainer.gems.HotSwappingComponentAdapterFactory for a more feature-rich version of the class
+ * @since 1.1
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+public class ImplementationHidingComponentAdapterFactory extends
+ org.picocontainer.defaults.ImplementationHidingComponentAdapterFactory {
+
+ /**
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+ ImplementationHidingComponentAdapterFactory() {
+ super();
+ }
+
+ /**
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+ public ImplementationHidingComponentAdapterFactory(ComponentAdapterFactory delegate, boolean strict) {
+ super(delegate, strict);
+ }
+
+ /**
+ * @deprecated since 1.2, moved to package {@link org.picocontainer.defaults}
+ */
+ public ImplementationHidingComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ super(delegate);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingPicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingPicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/alternatives/ImplementationHidingPicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * 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.alternatives;
+
+import java.io.Serializable;
+
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.defaults.ComponentAdapterFactory;
+import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory;
+import org.picocontainer.defaults.DefaultPicoContainer;
+import org.picocontainer.defaults.ImplementationHidingComponentAdapterFactory;
+
+/**
+ * This special MutablePicoContainer hides implementations of components if the key is an interface.
+ * It's very simple. Instances that are registered directly and components registered without key
+ * are not hidden. Hiding is achieved with dynamic proxies from Java's reflection api.
+ *
+ * @see CachingPicoContainer
+ * @see ImplementationHidingCachingPicoContainer
+ * @author Paul Hammant
+ * @version $Revision: 2424 $
+ */
+public class ImplementationHidingPicoContainer extends AbstractDelegatingMutablePicoContainer implements Serializable {
+ private final ComponentAdapterFactory caf;
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingPicoContainer(ComponentAdapterFactory caf, PicoContainer parent) {
+ super(new DefaultPicoContainer(makeComponentAdapterFactory(caf), parent));
+ this.caf = caf;
+ }
+
+ private static ImplementationHidingComponentAdapterFactory makeComponentAdapterFactory(ComponentAdapterFactory caf) {
+ if (caf instanceof ImplementationHidingComponentAdapterFactory) {
+ return (ImplementationHidingComponentAdapterFactory) caf;
+ }
+ return new ImplementationHidingComponentAdapterFactory(caf, false);
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingPicoContainer(PicoContainer parent) {
+ this(makeComponentAdapterFactory(new ConstructorInjectionComponentAdapterFactory()), parent);
+ }
+
+ /**
+ * Creates a new container with a parent container.
+ */
+ public ImplementationHidingPicoContainer(ComponentAdapterFactory caf) {
+ this(makeComponentAdapterFactory(caf), null);
+ }
+
+
+ /**
+ * Creates a new container with no parent container.
+ */
+ public ImplementationHidingPicoContainer() {
+ this((PicoContainer) null);
+ }
+
+
+ public MutablePicoContainer makeChildContainer() {
+ ImplementationHidingPicoContainer pc = new ImplementationHidingPicoContainer(caf, this);
+ getDelegate().addChildContainer(pc);
+ return pc;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.PicoVisitor;
+
+/**
+ * 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 <code>null</code> 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
+ * @version $Revision: 2654 $
+ * @since 1.0
+ */
+public abstract class AbstractComponentAdapter extends MonitoringComponentAdapter {
+ private Object componentKey;
+ private Class componentImplementation;
+
+ /**
+ * Constructs a new ComponentAdapter for the given key and implementation.
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to.
+ */
+ protected AbstractComponentAdapter(Object componentKey, Class componentImplementation) throws AssignabilityRegistrationException {
+ this(componentKey, componentImplementation, new DelegatingComponentMonitor());
+ }
+
+ /**
+ * 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
+ * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to.
+ */
+ protected AbstractComponentAdapter(Object componentKey, Class componentImplementation, ComponentMonitor monitor) throws AssignabilityRegistrationException {
+ super(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() throws AssignabilityRegistrationException {
+ if (componentKey instanceof Class) {
+ Class componentType = (Class) componentKey;
+ if (!componentType.isAssignableFrom(componentImplementation)) {
+ throw new AssignabilityRegistrationException(componentType, componentImplementation);
+ }
+ }
+ }
+
+ /**
+ * @return Returns the ComponentAdapter's class name and the component's key.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return getClass().getName() + "[" + getComponentKey() + "]";
+ }
+
+ public void accept(PicoVisitor visitor) {
+ visitor.visitComponentAdapter(this);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractMonitoringLifecycleStrategy.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractMonitoringLifecycleStrategy.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractMonitoringLifecycleStrategy.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+
+import java.io.Serializable;
+
+/**
+ * Abstract base class for lifecycle strategy implementation supporting a {@link ComponentMonitor}.
+ *
+ * @author Jörg Schaible
+ * @since 1.2
+ */
+public abstract class AbstractMonitoringLifecycleStrategy implements LifecycleStrategy, ComponentMonitorStrategy, Serializable {
+
+ private ComponentMonitor componentMonitor;
+
+ /**
+ * Construct a AbstractMonitoringLifecylceStrategy.
+ *
+ * @param monitor the componentMonitor to use
+ * @throws NullPointerException if the monitor is <code>null</code>
+ */
+ public AbstractMonitoringLifecycleStrategy(ComponentMonitor monitor) {
+ if (monitor == null) {
+ throw new NullPointerException("Monitor is null");
+ }
+ this.componentMonitor = monitor;
+ }
+
+ public void changeMonitor(ComponentMonitor monitor) {
+ if (monitor == null) {
+ throw new NullPointerException("Monitor is null");
+ }
+ this.componentMonitor = monitor;
+ }
+
+ public ComponentMonitor currentMonitor() {
+ return componentMonitor;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractPicoVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractPicoVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AbstractPicoVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoVisitor;
+
+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
+ * @since 1.1
+ */
+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 {
+ Method method = node.getClass().getMethod("accept", new Class[]{PicoVisitor.class});
+ return method;
+ } catch (NoSuchMethodException e) {
+ return e;
+ }
+ }
+ });
+ try {
+ if (retval instanceof NoSuchMethodException) {
+ throw (NoSuchMethodException) retval;
+ }
+ Method accept = (Method) retval;
+ accept.invoke(node, new Object[]{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);
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AmbiguousComponentResolutionException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AmbiguousComponentResolutionException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AmbiguousComponentResolutionException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoIntrospectionException;
+
+import java.util.Arrays;
+
+/**
+ * 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
+ * @since 1.0
+ */
+public class AmbiguousComponentResolutionException extends PicoIntrospectionException {
+ private Class component;
+ private Class ambiguousDependency;
+ private final Object[] ambiguousComponentKeys;
+
+
+ /**
+ * Construct a new exception with the ambigous class type and the ambiguous component keys.
+ *
+ * @param ambiguousDependency the unresolved dependency type
+ * @param componentKeys the ambiguous keys.
+ */
+ public AmbiguousComponentResolutionException(Class ambiguousDependency, Object[] componentKeys) {
+ super("");
+ this.ambiguousDependency = ambiguousDependency;
+ this.ambiguousComponentKeys = new Class[componentKeys.length];
+ for (int i = 0; i < componentKeys.length; i++) {
+ ambiguousComponentKeys[i] = componentKeys[i];
+ }
+ }
+
+ /**
+ * @return Returns a string containing the unresolved class type and the ambiguous keys.
+ */
+ public String getMessage() {
+ StringBuffer msg = new StringBuffer();
+ msg.append(component);
+ msg.append(" has ambiguous dependency on ");
+ msg.append(ambiguousDependency);
+ msg.append(", ");
+ msg.append("resolves to multiple classes: ");
+ msg.append(Arrays.asList(getAmbiguousComponentKeys()));
+ return msg.toString();
+ }
+
+ /**
+ * @return Returns the ambiguous component keys as array.
+ */
+ public Object[] getAmbiguousComponentKeys() {
+ return ambiguousComponentKeys;
+ }
+
+ public void setComponent(Class component) {
+ this.component = component;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AssignabilityRegistrationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AssignabilityRegistrationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/AssignabilityRegistrationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoRegistrationException;
+
+/**
+ * A subclass of {@link PicoRegistrationException} that is thrown during component registration if the
+ * component's key is a type and the implementation is not assignable to.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Jon Tirsén
+ * @since 1.0
+ */
+public class AssignabilityRegistrationException extends PicoRegistrationException {
+ /**
+ * Construct an exception with the type and the unassignable class.
+ *
+ * @param type the type used as component key
+ * @param clazz the unassignable implementation class
+ */
+ public AssignabilityRegistrationException(Class type, Class clazz) {
+ super("The type:" + type.getName() + " was not assignable from the class " + clazz.getName());
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BasicComponentParameter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BasicComponentParameter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BasicComponentParameter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,166 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoVisitor;
+
+/**
+ * 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
+ * @version $Revision: 2817 $
+ */
+public class BasicComponentParameter
+ implements Parameter, Serializable {
+
+ /**
+ * <code>BASIC_DEFAULT</code> 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 component
+ */
+ public BasicComponentParameter(Object componentKey) {
+ this.componentKey = componentKey;
+ }
+
+ /**
+ * Expect any paramter of the appropriate type.
+ */
+ public BasicComponentParameter() {
+ }
+
+ /**
+ * Check wether the given Parameter can be statisfied by the container.
+ *
+ * @return <code>true</code> if the Parameter can be verified.
+ * @throws org.picocontainer.PicoInitializationException {@inheritDoc}
+ * @see org.picocontainer.Parameter#isResolvable(org.picocontainer.PicoContainer,
+ * org.picocontainer.ComponentAdapter, java.lang.Class)
+ */
+ public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ return resolveAdapter(container, adapter, expectedType) != null;
+ }
+
+ public Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ final ComponentAdapter componentAdapter = resolveAdapter(container, adapter, expectedType);
+ if (componentAdapter != null) {
+ return container.getComponentInstance(componentAdapter.getComponentKey());
+ }
+ return null;
+ }
+
+ public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ final ComponentAdapter componentAdapter = resolveAdapter(container, adapter, expectedType);
+ if (componentAdapter == null) {
+ final HashSet set = new HashSet();
+ set.add(expectedType);
+ throw new UnsatisfiableDependenciesException(adapter, set, 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);
+ }
+
+ private ComponentAdapter resolveAdapter(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+
+ final ComponentAdapter result = getTargetAdapter(container, expectedType,adapter);
+ if (result == null) {
+ return null;
+ }
+
+ if (!expectedType.isAssignableFrom(result.getComponentImplementation())) {
+ // check for primitive value
+ if (expectedType.isPrimitive()) {
+ try {
+ final Field field = result.getComponentImplementation().getField("TYPE");
+ final Class type = (Class) field.get(result.getComponentInstance(null));
+ if (expectedType.isAssignableFrom(type)) {
+ return result;
+ }
+ } catch (NoSuchFieldException e) {
+ } catch (IllegalArgumentException e) {
+ } catch (IllegalAccessException e) {
+ } catch (ClassCastException e) {
+ }
+ }
+ return null;
+ }
+ return result;
+ }
+
+ private ComponentAdapter getTargetAdapter(PicoContainer container, Class expectedType, ComponentAdapter excludeAdapter) {
+ if (componentKey != null) {
+ // key tells us where to look so we follow
+ return container.getComponentAdapter(componentKey);
+ } else if(excludeAdapter == null) {
+ return container.getComponentAdapterOfType(expectedType);
+ } else {
+ Object excludeKey = excludeAdapter.getComponentKey();
+ ComponentAdapter byKey = container.getComponentAdapter(expectedType);
+ if(byKey != null && !excludeKey.equals(byKey.getComponentKey())) {
+ return byKey;
+ }
+ List found = container.getComponentAdaptersOfType(expectedType);
+ ComponentAdapter exclude = null;
+ for(Iterator iterator = found.iterator(); iterator.hasNext();) {
+ ComponentAdapter work = (ComponentAdapter) iterator.next();
+ if( work.getComponentKey().equals(excludeKey)) {
+ exclude = work;
+ }
+ }
+ found.remove(exclude);
+ if(found.size() == 0) {
+ if( container.getParent() != null) {
+ return container.getParent().getComponentAdapterOfType(expectedType);
+ } else {
+ return null;
+ }
+ } else if(found.size() == 1) {
+ return (ComponentAdapter)found.get(0);
+ } else {
+ Class[] foundClasses = new Class[found.size()];
+ for (int i = 0; i < foundClasses.length; i++) {
+ foundClasses[i] = ((ComponentAdapter) found.get(i)).getComponentImplementation();
+ }
+ throw new AmbiguousComponentResolutionException(expectedType, foundClasses);
+ }
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,279 @@
+package org.picocontainer.defaults;
+
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+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.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * 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 <em>not</em> the same as {@link SetterInjectionComponentAdapter},
+ * which is a true Setter Injection adapter.
+ * <p/>
+ * 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 <code>setAsText</code> method.
+ * <p/>
+ * <em>
+ * Note that this class doesn't cache instances. If you want caching,
+ * use a {@link CachingComponentAdapter} around this one.
+ * </em>
+ *
+ * @author Aslak Hellesøy
+ * @version $Revision: 2793 $
+ * @since 1.0
+ */
+public class BeanPropertyComponentAdapter extends DecoratingComponentAdapter {
+ private Map properties;
+ private transient Map setters = null;
+
+ /**
+ * Construct a BeanPropertyComponentAdapter.
+ *
+ * @param delegate the wrapped {@link ComponentAdapter}
+ * @throws PicoInitializationException {@inheritDoc}
+ */
+ public BeanPropertyComponentAdapter(ComponentAdapter delegate) throws PicoInitializationException {
+ super(delegate);
+ }
+
+ /**
+ * Get a component instance and set given property values.
+ *
+ * @return the component instance with any properties of the properties map set.
+ * @throws PicoInitializationException {@inheritDoc}
+ * @throws PicoIntrospectionException {@inheritDoc}
+ * @throws AssignabilityRegistrationException
+ * {@inheritDoc}
+ * @throws NotConcreteRegistrationException
+ * {@inheritDoc}
+ * @see #setProperties(Map)
+ */
+ public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ final Object componentInstance = super.getComponentInstance(container);
+ if (setters == null) {
+ setters = getSetters(getComponentImplementation());
+ }
+
+ if (properties != null) {
+ ComponentMonitor componentMonitor = currentMonitor();
+ Set propertyNames = properties.keySet();
+ for (Iterator iterator = propertyNames.iterator(); iterator.hasNext();) {
+ final String propertyName = (String) iterator.next();
+ final Object propertyValue = properties.get(propertyName);
+ Method setter = (Method) setters.get(propertyName);
+
+ Object valueToInvoke = this.getSetterParameter(propertyName,propertyValue,componentInstance,container);
+
+ try {
+ componentMonitor.invoking(setter, componentInstance);
+ long startTime = System.currentTimeMillis();
+ setter.invoke(componentInstance, new Object[]{valueToInvoke});
+ componentMonitor.invoked(setter, componentInstance, System.currentTimeMillis() - startTime);
+ } catch (final Exception e) {
+ componentMonitor.invocationFailed(setter, componentInstance, e);
+ throw new PicoInitializationException("Failed to set property " + propertyName + " to " + propertyValue + ": " + e.getMessage(), e);
+ }
+ }
+ }
+ return componentInstance;
+ }
+
+ private Map getSetters(Class clazz) {
+ Map result = new HashMap();
+ Method[] methods = getMethods(clazz);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ 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) throws ClassNotFoundException {
+ 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.getComponentInstance(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
+ * @throws ClassNotFoundException if typeName is "class" or "java.lang.Class" and class couldn't be loaded.
+ */
+ public static Object convert(String typeName, String value, ClassLoader classLoader) throws ClassNotFoundException {
+ 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 new Character(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 PicoInitializationException(e);
+ }
+ } else if (typeName.equals(Class.class.getName()) || typeName.equals("class")) {
+ return classLoader.loadClass(value);
+ } else {
+ final Class clazz = classLoader.loadClass(typeName);
+ final PropertyEditor editor = PropertyEditorManager.findEditor(clazz);
+ if (editor != null) {
+ editor.setAsText(value);
+ return editor.getValue();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 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.
+ */
+ private Object getSetterParameter(final String propertyName, final Object propertyValue,
+ final Object componentInstance, PicoContainer container) throws PicoInitializationException, ClassCastException {
+
+ if (propertyValue == null) {
+ return null;
+ }
+
+ Method setter = (Method) 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 = null;
+
+ 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).
+ //
+ try {
+ convertedValue = convertType(container, setter, propertyValue.toString());
+ }
+ catch (ClassNotFoundException e) {
+ throw new PicoInvocationTargetInitializationException(e);
+ }
+
+ //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 component: "
+ + componentInstance.toString() + " can only take objects of: " + setterParameter.getName()
+ + " instead got: " + givenParameterClass.getName());
+ }
+ }
+ return convertedValue;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/BeanPropertyComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * A {@link ComponentAdapterFactory} that creates
+ * {@link BeanPropertyComponentAdapter} instances.
+ *
+ * @author Aslak Hellesøy
+ * @version $Revision: 2320 $
+ * @since 1.0
+ */
+public class BeanPropertyComponentAdapterFactory extends DecoratingComponentAdapterFactory {
+ private Map adapterCache = new HashMap();
+
+ /**
+ * Construct a BeanPropertyComponentAdapterFactory.
+ *
+ * @param delegate the wrapped factory.
+ */
+ public BeanPropertyComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ super(delegate);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ ComponentAdapter decoratedAdapter = super.createComponentAdapter(componentKey, componentImplementation, parameters);
+ BeanPropertyComponentAdapter propertyAdapter = new BeanPropertyComponentAdapter(decoratedAdapter);
+ adapterCache.put(componentKey, propertyAdapter);
+ return propertyAdapter;
+ }
+
+ // TODO: What is this method for? It is not used in complete Pico/Nano and caching is normally done by CachingCA ...
+ /**
+ * @deprecated
+ */
+ public BeanPropertyComponentAdapter getComponentAdapter(Object key) {
+ return (BeanPropertyComponentAdapter) adapterCache.get(key);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.LifecycleManager;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * <p>
+ * {@link ComponentAdapter} implementation that caches the component instance.
+ * </p>
+ * <p>
+ * This adapter supports components with a lifecycle, as it is a {@link LifecycleManager lifecycle manager}
+ * which will apply the delegate's {@link 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.
+ * </p>
+ *
+ * @author Mauro Talevi
+ * @version $Revision: 2827 $
+ */
+public class CachingComponentAdapter extends DecoratingComponentAdapter implements LifecycleManager {
+
+ private ObjectReference instanceReference;
+ private boolean disposed;
+ private boolean started;
+ private boolean delegateHasLifecylce;
+
+ public CachingComponentAdapter(ComponentAdapter delegate) {
+ this(delegate, new SimpleReference());
+ }
+
+ public CachingComponentAdapter(ComponentAdapter delegate, ObjectReference instanceReference) {
+ super(delegate);
+ this.instanceReference = instanceReference;
+ this.disposed = false;
+ this.started = false;
+ this.delegateHasLifecylce = delegate instanceof LifecycleStrategy
+ && ((LifecycleStrategy) delegate).hasLifecycle(delegate.getComponentImplementation());
+ }
+
+ public Object getComponentInstance(PicoContainer container)
+ throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ Object instance = instanceReference.get();
+ if (instance == null) {
+ instance = super.getComponentInstance(container);
+ instanceReference.set(instance);
+ }
+ return instance;
+ }
+
+ /**
+ * Flushes the cache.
+ * If the component instance is started is will stop and dispose it before
+ * flushing the cache.
+ */
+ public void flush() {
+ Object instance = instanceReference.get();
+ if ( instance != null && delegateHasLifecylce && started ) {
+ stop(instance);
+ dispose(instance);
+ }
+ instanceReference.set(null);
+ }
+
+ /**
+ * Starts the cached component instance
+ * {@inheritDoc}
+ */
+ public void start(PicoContainer container) {
+ if ( delegateHasLifecylce ){
+ if (disposed) throw new IllegalStateException("Already disposed");
+ if (started) throw new IllegalStateException("Already started");
+ start(getComponentInstance(container));
+ started = true;
+ }
+ }
+
+ /**
+ * Stops the cached component instance
+ * {@inheritDoc}
+ */
+ public void stop(PicoContainer container) {
+ if ( delegateHasLifecylce ){
+ if (disposed) throw new IllegalStateException("Already disposed");
+ if (!started) throw new IllegalStateException("Not started");
+ stop(getComponentInstance(container));
+ started = false;
+ }
+ }
+
+ /**
+ * Disposes the cached component instance
+ * {@inheritDoc}
+ */
+ public void dispose(PicoContainer container) {
+ if ( delegateHasLifecylce ){
+ if (disposed) throw new IllegalStateException("Already disposed");
+ dispose(getComponentInstance(container));
+ disposed = true;
+ }
+ }
+
+ public boolean hasLifecycle() {
+ return delegateHasLifecylce;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CachingComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * @author Aslak Hellesøy
+ * @author <a href="Rafal.Krzewski">rafal at caltha.pl</a>
+ * @version $Revision: 1651 $
+ */
+public class CachingComponentAdapterFactory extends DecoratingComponentAdapterFactory {
+ public CachingComponentAdapterFactory() {
+ this(null);
+ }
+
+ public CachingComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ super(delegate);
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters)
+ throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return new CachingComponentAdapter(super.createComponentAdapter(componentKey, componentImplementation, parameters));
+
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CollectionComponentParameter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CollectionComponentParameter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CollectionComponentParameter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,341 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoVisitor;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+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;
+
+
+/**
+ * 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
+ * @since 1.1
+ */
+public class CollectionComponentParameter
+ implements Parameter, Serializable {
+ private static final MapFactory mapFactory = new MapFactory();
+
+ /**
+ * Use <code>ARRAY</code> as {@link Parameter}for an Array that must have elements.
+ */
+ public static final CollectionComponentParameter ARRAY = new CollectionComponentParameter();
+ /**
+ * Use <code>ARRAY_ALLOW_EMPTY</code> 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 <code>true</code> if an empty array also is a valid dependency
+ * resolution.
+ */
+ public CollectionComponentParameter(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 <code>true</code> if an empty collection resolves the
+ * dependency.
+ */
+ public CollectionComponentParameter(Class componentValueType, 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 <code>true</code> if an empty collection resolves the
+ * dependency.
+ */
+ public CollectionComponentParameter(Class componentKeyType, Class componentValueType, boolean emptyCollection) {
+ this.emptyCollection = emptyCollection;
+ this.componentKeyType = componentKeyType;
+ this.componentValueType = componentValueType;
+ }
+
+ /**
+ * Resolve the parameter for the expected type. The method will return <code>null</code>
+ * If the expected type is not one of the collection types {@link Array},
+ * {@link Collection}or {@link Map}. An empty collection is only a valid resolution, if
+ * the <code>emptyCollection</code> flag was set.
+ *
+ * @param container {@inheritDoc}
+ * @param adapter {@inheritDoc}
+ * @param expectedType {@inheritDoc}
+ * @return the instance of the collection type or <code>null</code>
+ * @throws PicoInitializationException {@inheritDoc}
+ */
+ public Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ // type check is done in isResolvable
+ Object result = null;
+ final Class collectionType = getCollectionType(expectedType);
+ if (collectionType != null) {
+ final Map adapterMap = getMatchingComponentAdapters(container, adapter, componentKeyType, getValueType(expectedType));
+ if (Array.class.isAssignableFrom(collectionType)) {
+ result = getArrayInstance(container, expectedType, adapterMap);
+ } else if (Map.class.isAssignableFrom(collectionType)) {
+ result = getMapInstance(container, expectedType, adapterMap);
+ } else if (Collection.class.isAssignableFrom(collectionType)) {
+ result = getCollectionInstance(container, expectedType, adapterMap);
+ } else {
+ throw new PicoIntrospectionException(expectedType.getName() + " is not a collective type");
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 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 <code>emptyCollection</code> flag was set.
+ *
+ * @param container {@inheritDoc}
+ * @param adapter {@inheritDoc}
+ * @param expectedType {@inheritDoc}
+ * @return <code>true</code> if matching components were found or an empty collective type
+ * is allowed
+ */
+ public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ final Class collectionType = getCollectionType(expectedType);
+ final Class valueType = getValueType(expectedType);
+ return collectionType != null && (emptyCollection || getMatchingComponentAdapters(container, adapter, componentKeyType, valueType).size() > 0);
+ }
+
+ /**
+ * 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 <code>emptyCollection</code> flag was set.
+ *
+ * @param container {@inheritDoc}
+ * @param adapter {@inheritDoc}
+ * @param expectedType {@inheritDoc}
+ * @throws PicoIntrospectionException {@inheritDoc}
+ */
+ public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ 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 PicoIntrospectionException(expectedType.getName()
+ + " not resolvable, no components of type "
+ + getValueType(expectedType).getName()
+ + " available");
+ }
+ } else {
+ for (final Iterator iter = componentAdapters.iterator(); iter.hasNext();) {
+ final ComponentAdapter componentAdapter = (ComponentAdapter) iter.next();
+ componentAdapter.verify(container);
+ }
+ }
+ } else {
+ throw new PicoIntrospectionException(expectedType.getName() + " 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 <code>ComponentAdapter</code> value
+ * @return <code>true</code> 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 component
+ * @return a {@link Map} with the ComponentAdapter instances and their component keys as map key.
+ */
+ protected Map getMatchingComponentAdapters(PicoContainer container, ComponentAdapter adapter, Class keyType, Class valueType) {
+ final Map adapterMap = mapFactory.newInstance();
+ final PicoContainer parent = container.getParent();
+ if (parent != null) {
+ adapterMap.putAll(getMatchingComponentAdapters(parent, adapter, keyType, valueType));
+ }
+ final Collection allAdapters = container.getComponentAdapters();
+ for (final Iterator iter = allAdapters.iterator(); iter.hasNext();) {
+ final ComponentAdapter componentAdapter = (ComponentAdapter) iter.next();
+ adapterMap.remove(componentAdapter.getComponentKey());
+ }
+ final List adapterList = container.getComponentAdaptersOfType(valueType);
+ for (final Iterator iter = adapterList.iterator(); iter.hasNext();) {
+ final ComponentAdapter componentAdapter = (ComponentAdapter) iter.next();
+ 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) {
+ Class collectionClass = null;
+ if (collectionType.isArray()) {
+ collectionClass = Array.class;
+ } else if (Map.class.isAssignableFrom(collectionType)) {
+ collectionClass = Map.class;
+ } else if (Collection.class.isAssignableFrom(collectionType)) {
+ collectionClass = Collection.class;
+ }
+ return collectionClass;
+ }
+
+ private Class getValueType(final Class collectionType) {
+ Class valueType = componentValueType;
+ if (collectionType.isArray()) {
+ valueType = collectionType.getComponentType();
+ }
+ 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 (final Iterator iterator = adapterList.values().iterator(); iterator.hasNext();) {
+ final ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+ result[i] = container.getComponentInstance(componentAdapter.getComponentKey());
+ i++;
+ }
+ return result;
+ }
+
+ private Collection getCollectionInstance(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 (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 = (Collection) collectionType.newInstance();
+ for (final Iterator iterator = adapterList.values().iterator(); iterator.hasNext();) {
+ final ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+ result.add(container.getComponentInstance(componentAdapter.getComponentKey()));
+ }
+ return result;
+ } catch (InstantiationException e) {
+ ///CLOVER:OFF
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ } catch (IllegalAccessException e) {
+ ///CLOVER:OFF
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ }
+ }
+
+ 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 = (Map) collectionType.newInstance();
+ for (final Iterator iterator = adapterList.entrySet().iterator(); iterator.hasNext();) {
+ final Map.Entry entry = (Map.Entry) iterator.next();
+ final Object key = entry.getKey();
+ result.put(key, container.getComponentInstance(key));
+ }
+ return result;
+ } catch (InstantiationException e) {
+ ///CLOVER:OFF
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ } catch (IllegalAccessException e) {
+ ///CLOVER:OFF
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ }
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * <p>
+ * A component adapter factory is responsible for creating
+ * {@link ComponentAdapter} component adapters. The main use of the component adapter factory is
+ * inside {@link DefaultPicoContainer#DefaultPicoContainer(ComponentAdapterFactory)}, where it can
+ * be used to customize the default component adapter that is used when none is specified
+ * explicitly.
+ * </p>
+ *
+ * @author Jon Tirsén
+ * @author Mauro Talevi
+ * @version $Revision: 2230 $
+ */
+public interface ComponentAdapterFactory {
+
+ /**
+ * Create a new component adapter based on the specified arguments.
+ *
+ * @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 PicoIntrospectionException if the creation of the component adapter results in a
+ * {@link PicoIntrospectionException}.
+ * @throws AssignabilityRegistrationException
+ * if the creation of the component adapter results in a
+ * {@link AssignabilityRegistrationException}.
+ * @throws NotConcreteRegistrationException
+ * if the creation of the component adapter results in a
+ * {@link NotConcreteRegistrationException}.
+ */
+ ComponentAdapter createComponentAdapter(Object componentKey,
+ Class componentImplementation,
+ Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException;
+
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentMonitorStrategy.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentMonitorStrategy.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentMonitorStrategy.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.PicoContainer;
+
+/**
+ * <p>
+ * Interface responsible for changing monitoring strategy.
+ * It may be implemented by {@link PicoContainer containers} and
+ * single {@link ComponentAdapter component adapters}.
+ * The choice of supporting the monitor strategy is left to the
+ * implementers of the container and adapters.
+ * </p>
+ *
+ * @author Paul Hammant
+ * @author Joerg Schaible
+ * @author Mauro Talevi
+ * @version $Revision: $
+ * @since 1.2
+ */
+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();
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentParameter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentParameter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ComponentParameter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoVisitor;
+
+
+/**
+ * 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
+ * @version $Revision: 2285 $
+ */
+public class ComponentParameter
+ extends BasicComponentParameter {
+
+ /**
+ * <code>DEFAULT</code> is an instance of ComponentParameter using the default constructor.
+ */
+ public static final ComponentParameter DEFAULT = new ComponentParameter();
+ /**
+ * Use <code>ARRAY</code> as {@link Parameter}for an Array that must have elements.
+ */
+ public static final ComponentParameter ARRAY = new ComponentParameter(false);
+ /**
+ * Use <code>ARRAY_ALLOW_EMPTY</code> 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 component
+ */
+ public ComponentParameter(Object componentKey) {
+ this(componentKey, null);
+ }
+
+ /**
+ * Expect any scalar paramter of the appropriate type or an {@link java.lang.reflect.Array}.
+ */
+ public ComponentParameter() {
+ this(false);
+ }
+
+ /**
+ * Expect any scalar paramter of the appropriate type or an {@link java.lang.reflect.Array}.
+ * Resolve the parameter even if no compoennt is of the array's component type.
+ *
+ * @param emptyCollection <code>true</code> allows an Array to be empty
+ * @since 1.1
+ */
+ public ComponentParameter(boolean emptyCollection) {
+ this(null, emptyCollection ? CollectionComponentParameter.ARRAY_ALLOW_EMPTY : CollectionComponentParameter.ARRAY);
+ }
+
+ /**
+ * Expect any scalar paramter 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 <code>true</code> allows the collection to be empty
+ * @since 1.1
+ */
+ public ComponentParameter(Class componentValueType, boolean emptyCollection) {
+ this(null, new CollectionComponentParameter(componentValueType, emptyCollection));
+ }
+
+ /**
+ * Expect any scalar paramter 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 <code>true</code> allows the collection to be empty
+ * @since 1.1
+ */
+ 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 Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ // type check is done in isResolvable
+ Object result = super.resolveInstance(container, adapter, expectedType);
+ if (result == null && collectionParameter != null) {
+ result = collectionParameter.resolveInstance(container, adapter, expectedType);
+ }
+ return result;
+ }
+
+ public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ if (!super.isResolvable(container, adapter, expectedType)) {
+ if (collectionParameter != null) {
+ return collectionParameter.isResolvable(container, adapter, expectedType);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ try {
+ super.verify(container, adapter, expectedType);
+ } catch (UnsatisfiableDependenciesException e) {
+ if (collectionParameter != null) {
+ collectionParameter.verify(container, adapter, expectedType);
+ return;
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Accept the visitor for the current {@link Parameter}. If internally a
+ * {@link CollectionComponentParameter}is used, it is visited also.
+ *
+ * @see org.picocontainer.defaults.BasicComponentParameter#accept(org.picocontainer.PicoVisitor)
+ */
+ public void accept(PicoVisitor visitor) {
+ super.accept(visitor);
+ if (collectionParameter != null) {
+ collectionParameter.accept(visitor);
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstantParameter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstantParameter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstantParameter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoException;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoVisitor;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+
+
+/**
+ * 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
+ * @version $Revision: 1801 $
+ */
+public class ConstantParameter
+ implements Parameter, Serializable {
+
+ private final Object value;
+
+ public ConstantParameter(Object value) {
+ this.value = value;
+ }
+
+ public Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ return value;
+ }
+
+ public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType) {
+ try {
+ verify(container, adapter, expectedType);
+ return true;
+ } catch(final PicoIntrospectionException e) {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.picocontainer.Parameter#verify(org.picocontainer.PicoContainer,
+ * org.picocontainer.ComponentAdapter, java.lang.Class)
+ */
+ public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType) throws PicoException {
+ if (!checkPrimitive(expectedType) && !expectedType.isInstance(value)) {
+ throw new PicoIntrospectionException(expectedType.getClass().getName()
+ + " is not assignable from "
+ + value.getClass().getName());
+ }
+ }
+
+ /**
+ * 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) {
+ } catch (IllegalAccessException e) {
+ }
+ return false;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,290 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Instantiates components using Constructor Injection.
+ * <em>
+ * Note that this class doesn't cache instances. If you want caching,
+ * use a {@link CachingComponentAdapter} around this one.
+ * </em>
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Jon Tirsén
+ * @author Zohar Melamed
+ * @author Jörg Schaible
+ * @author Mauro Talevi
+ * @version $Revision: 2788 $
+ */
+public class ConstructorInjectionComponentAdapter extends InstantiatingComponentAdapter {
+ private transient List sortedMatchingConstructors;
+ private transient Guard instantiationGuard;
+
+ private static abstract class Guard extends ThreadLocalCyclicDependencyGuard {
+ protected PicoContainer guardedContainer;
+
+ private void setArguments(PicoContainer container) {
+ this.guardedContainer = container;
+ }
+ }
+
+ /**
+ * Creates a ConstructorInjectionComponentAdapter
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @param monitor the component monitor used by this adapter
+ * @param lifecycleStrategy the component lifecycle strategy used by this adapter
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public ConstructorInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses, monitor, lifecycleStrategy);
+ }
+
+ /**
+ * Creates a ConstructorInjectionComponentAdapter
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @param monitor the component monitor used by this adapter
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public ConstructorInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses, ComponentMonitor monitor) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses, monitor);
+ }
+
+ /**
+ * Creates a ConstructorInjectionComponentAdapter
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public ConstructorInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses);
+ }
+
+ /**
+ * Creates a ConstructorInjectionComponentAdapter with key, implementation and parameters
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public ConstructorInjectionComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters) {
+ this(componentKey, componentImplementation, parameters, false);
+ }
+
+ /**
+ * Creates a ConstructorInjectionComponentAdapter with key and implementation
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public ConstructorInjectionComponentAdapter(Object componentKey, Class componentImplementation) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ this(componentKey, componentImplementation, null);
+ }
+
+ protected Constructor getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException, UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ final Set conflicts = new HashSet();
+ final Set unsatisfiableDependencyTypes = new HashSet();
+ if (sortedMatchingConstructors == null) {
+ sortedMatchingConstructors = getSortedMatchingConstructors();
+ }
+ Constructor greediestConstructor = null;
+ int lastSatisfiableConstructorSize = -1;
+ Class unsatisfiedDependencyType = null;
+ for (int i = 0; i < sortedMatchingConstructors.size(); i++) {
+ boolean failedDependency = false;
+ Constructor constructor = (Constructor) sortedMatchingConstructors.get(i);
+ Class[] parameterTypes = constructor.getParameterTypes();
+ Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
+
+ // remember: all constructors with less arguments than the given parameters are filtered out already
+ for (int j = 0; j < currentParameters.length; j++) {
+ // check wether this constructor is statisfiable
+ if (currentParameters[j].isResolvable(container, this, parameterTypes[j])) {
+ continue;
+ }
+ unsatisfiableDependencyTypes.add(Arrays.asList(parameterTypes));
+ unsatisfiedDependencyType = parameterTypes[j];
+ failedDependency = true;
+ break;
+ }
+
+ if (greediestConstructor != null && parameterTypes.length != lastSatisfiableConstructorSize) {
+ if (conflicts.isEmpty()) {
+ // we found our match [aka. greedy and satisfied]
+ return greediestConstructor;
+ } else {
+ // fits although not greedy
+ conflicts.add(constructor);
+ }
+ } else if (!failedDependency && lastSatisfiableConstructorSize == parameterTypes.length) {
+ // satisfied and same size as previous one?
+ conflicts.add(constructor);
+ conflicts.add(greediestConstructor);
+ } else if (!failedDependency) {
+ greediestConstructor = constructor;
+ lastSatisfiableConstructorSize = parameterTypes.length;
+ }
+ }
+ if (!conflicts.isEmpty()) {
+ throw new TooManySatisfiableConstructorsException(getComponentImplementation(), conflicts);
+ } else if (greediestConstructor == null && !unsatisfiableDependencyTypes.isEmpty()) {
+ throw new UnsatisfiableDependenciesException(this, unsatisfiedDependencyType, unsatisfiableDependencyTypes, container);
+ } else if (greediestConstructor == null) {
+ // be nice to the user, show all constructors that were filtered out
+ final Set nonMatching = new HashSet();
+ final Constructor[] constructors = getConstructors();
+ for (int i = 0; i < constructors.length; i++) {
+ nonMatching.add(constructors[i]);
+ }
+ throw new PicoInitializationException("Either do the specified parameters not match any of the following constructors: " + nonMatching.toString() + " or the constructors were not accessible for '" + getComponentImplementation() + "'");
+ }
+ return greediestConstructor;
+ }
+
+ public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ if (instantiationGuard == null) {
+ instantiationGuard = new Guard() {
+ public Object run() {
+ final Constructor constructor;
+ try {
+ constructor = getGreediestSatisfiableConstructor(guardedContainer);
+ } catch (AmbiguousComponentResolutionException e) {
+ e.setComponent(getComponentImplementation());
+ throw e;
+ }
+ ComponentMonitor componentMonitor = currentMonitor();
+ try {
+ Object[] parameters = getConstructorArguments(guardedContainer, constructor);
+ componentMonitor.instantiating(constructor);
+ long startTime = System.currentTimeMillis();
+ Object inst = newInstance(constructor, parameters);
+ componentMonitor.instantiated(constructor, System.currentTimeMillis() - startTime);
+ return inst;
+ } catch (InvocationTargetException e) {
+ componentMonitor.instantiationFailed(constructor, e);
+ if (e.getTargetException() instanceof RuntimeException) {
+ throw (RuntimeException) e.getTargetException();
+ } else if (e.getTargetException() instanceof Error) {
+ throw (Error) e.getTargetException();
+ }
+ throw new PicoInvocationTargetInitializationException(e.getTargetException());
+ } catch (InstantiationException e) {
+ // can't get here because checkConcrete() will catch it earlier, but see PICO-191
+ ///CLOVER:OFF
+ componentMonitor.instantiationFailed(constructor, e);
+ throw new PicoInitializationException("Should never get here");
+ ///CLOVER:ON
+ } catch (IllegalAccessException e) {
+ // can't get here because either filtered or access mode set
+ ///CLOVER:OFF
+ componentMonitor.instantiationFailed(constructor, e);
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ }
+ }
+ };
+ }
+ instantiationGuard.setArguments(container);
+ return instantiationGuard.observe(getComponentImplementation());
+ }
+
+ protected Object[] getConstructorArguments(PicoContainer container, Constructor ctor) {
+ Class[] parameterTypes = ctor.getParameterTypes();
+ Object[] result = new Object[parameterTypes.length];
+ Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
+
+ for (int i = 0; i < currentParameters.length; i++) {
+ result[i] = currentParameters[i].resolveInstance(container, this, parameterTypes[i]);
+ }
+ return result;
+ }
+
+ private List getSortedMatchingConstructors() {
+ List matchingConstructors = new ArrayList();
+ Constructor[] allConstructors = getConstructors();
+ // filter out all constructors that will definately not match
+ for (int i = 0; i < allConstructors.length; i++) {
+ Constructor constructor = allConstructors[i];
+ if ((parameters == null || constructor.getParameterTypes().length == parameters.length) && (allowNonPublicClasses || (constructor.getModifiers() & Modifier.PUBLIC) != 0)) {
+ matchingConstructors.add(constructor);
+ }
+ }
+ // optimize list of constructors moving the longest at the beginning
+ if (parameters == null) {
+ Collections.sort(matchingConstructors, new Comparator() {
+ public int compare(Object arg0, Object arg1) {
+ return ((Constructor) arg1).getParameterTypes().length - ((Constructor) arg0).getParameterTypes().length;
+ }
+ });
+ }
+ return matchingConstructors;
+ }
+
+ private Constructor[] getConstructors() {
+ return (Constructor[]) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return getComponentImplementation().getDeclaredConstructors();
+ }
+ });
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ConstructorInjectionComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * @author Jon Tirsén
+ * @version $Revision: 2654 $
+ */
+public class ConstructorInjectionComponentAdapterFactory extends MonitoringComponentAdapterFactory {
+ private final boolean allowNonPublicClasses;
+ private LifecycleStrategy lifecycleStrategy;
+
+ public ConstructorInjectionComponentAdapterFactory(boolean allowNonPublicClasses,
+ ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy) {
+ this.allowNonPublicClasses = allowNonPublicClasses;
+ this.changeMonitor(monitor);
+ this.lifecycleStrategy = lifecycleStrategy;
+ }
+
+ public ConstructorInjectionComponentAdapterFactory(boolean allowNonPublicClasses, ComponentMonitor monitor) {
+ this(allowNonPublicClasses, monitor, new DefaultLifecycleStrategy(monitor));
+ }
+
+ public ConstructorInjectionComponentAdapterFactory(boolean allowNonPublicClasses, LifecycleStrategy lifecycleStrategy) {
+ this(allowNonPublicClasses, new DelegatingComponentMonitor(), lifecycleStrategy);
+ }
+
+ public ConstructorInjectionComponentAdapterFactory(boolean allowNonPublicClasses) {
+ this(allowNonPublicClasses, new DelegatingComponentMonitor());
+ }
+
+ public ConstructorInjectionComponentAdapterFactory() {
+ this(false);
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey,
+ Class componentImplementation,
+ Parameter[] parameters)
+ throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters,
+ allowNonPublicClasses, currentMonitor(), lifecycleStrategy);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CustomPermissionsURLClassLoader.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CustomPermissionsURLClassLoader.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CustomPermissionsURLClassLoader.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * 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.defaults;
+
+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 = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object 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 (int i = 0; i < urls.length; i++) {
+ URL url = urls[i];
+ result += "\n\t" + url.toString();
+ }
+
+ return result;
+ }
+
+ public PermissionCollection getPermissions(CodeSource codeSource) {
+ return (Permissions) permissionsMap.get(codeSource.getLocation());
+ }
+
+}
+
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoIntrospectionException;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Aslak Hellesøy
+ * @author Jörg Schaible
+ * @version $Revision: 1801 $
+ */
+public class CyclicDependencyException extends PicoIntrospectionException {
+ private final List stack;
+
+ /**
+ * @since 1.1
+ */
+ public CyclicDependencyException(Class element) {
+ super((Throwable)null);
+ this.stack = new LinkedList();
+ push(element);
+ }
+
+ /**
+ * @since 1.1
+ */
+ public void push(Class element) {
+ stack.add(element);
+ }
+
+ public Class[] getDependencies() {
+ return (Class[]) stack.toArray(new Class[stack.size()]);
+ }
+
+ public String getMessage() {
+ return "Cyclic dependency: " + stack.toString();
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyGuard.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyGuard.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/CyclicDependencyGuard.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * 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 Joerg Schaible *
+ *****************************************************************************/
+
+package org.picocontainer.defaults;
+
+/**
+ * Interface for a guard implementation looking after cyclic dependencies.
+ *
+ * @author Jörg Schaible
+ * @since 1.1
+ */
+public interface CyclicDependencyGuard {
+
+ /**
+ * 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 <code>null</code>
+ */
+ public Object run();
+
+ /**
+ * Call the observing function. The provided guard will hold the {@link Boolean} value.
+ * If the guard is already <code>Boolean.TRUE</code> a {@link CyclicDependencyException}
+ * will be thrown.
+ *
+ * @param stackFrame the current stack frame
+ * @return the result of the <code>run</code> method
+ */
+ public Object observe(Class stackFrame);
+}
\ No newline at end of file
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,209 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.LifecycleManager;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoVisitor;
+
+/**
+ * <p>
+ * Component adapter which decorates another adapter.
+ * </p>
+ * <p>
+ * This adapter supports a {@link ComponentMonitorStrategy component monitor strategy}
+ * and will propagate change of monitor to the delegate if the delegate itself
+ * support the monitor strategy.
+ * </p>
+ * <p>
+ * This adapter also supports a {@link LifecycleManager lifecycle manager} and a
+ * {@link LifecycleStrategy lifecycle strategy} if the delegate does.
+ * </p>
+ *
+ * @author Jon Tirsen
+ * @author Aslak Hellesoy
+ * @author Mauro Talevi
+ * @version $Revision: 2631 $
+ */
+public class DecoratingComponentAdapter implements ComponentAdapter, ComponentMonitorStrategy,
+ LifecycleManager, LifecycleStrategy, Serializable {
+
+ private ComponentAdapter delegate;
+
+ public DecoratingComponentAdapter(ComponentAdapter delegate) {
+ this.delegate = delegate;
+ }
+
+ public Object getComponentKey() {
+ return delegate.getComponentKey();
+ }
+
+ public Class getComponentImplementation() {
+ return delegate.getComponentImplementation();
+ }
+
+ public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException {
+ return delegate.getComponentInstance(container);
+ }
+
+ public void verify(PicoContainer container) throws PicoIntrospectionException {
+ delegate.verify(container);
+ }
+
+ public ComponentAdapter getDelegate() {
+ return delegate;
+ }
+
+ 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 PicoIntrospectionException if no component monitor is found in delegate
+ */
+ public ComponentMonitor currentMonitor() {
+ if ( delegate instanceof ComponentMonitorStrategy ){
+ return ((ComponentMonitorStrategy)delegate).currentMonitor();
+ }
+ throw new PicoIntrospectionException("No component monitor found in delegate");
+ }
+
+ // ~~~~~~~~ LifecylceManager ~~~~~~~~
+
+ /**
+ * Invokes delegate start method if the delegate is a LifecycleManager
+ * {@inheritDoc}
+ */
+ public void start(PicoContainer container) {
+ if ( delegate instanceof LifecycleManager ){
+ ((LifecycleManager)delegate).start(container);
+ }
+ }
+
+ /**
+ * Invokes delegate stop method if the delegate is a LifecycleManager
+ * {@inheritDoc}
+ */
+ public void stop(PicoContainer container) {
+ if ( delegate instanceof LifecycleManager ){
+ ((LifecycleManager)delegate).stop(container);
+ }
+ }
+
+ /**
+ * Invokes delegate dispose method if the delegate is a LifecycleManager
+ * {@inheritDoc}
+ */
+ public void dispose(PicoContainer container) {
+ if ( delegate instanceof LifecycleManager ){
+ ((LifecycleManager)delegate).dispose(container);
+ }
+ }
+
+ /**
+ * Invokes delegate hasLifecylce method if the delegate is a LifecycleManager
+ * {@inheritDoc}
+ */
+ public boolean hasLifecycle() {
+ if ( delegate instanceof LifecycleManager ){
+ return ((LifecycleManager)delegate).hasLifecycle();
+ }
+ if ( delegate instanceof LifecycleStrategy ){
+ return ((LifecycleStrategy)delegate).hasLifecycle(delegate.getComponentImplementation());
+ }
+ return false;
+ }
+
+ // ~~~~~~~~ LifecylceStrategy ~~~~~~~~
+
+ /**
+ * 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 hasLifecylce(Class) method if the delegate is a LifecycleStrategy
+ * {@inheritDoc}
+ */
+ public boolean hasLifecycle(Class type) {
+ if ( delegate instanceof LifecycleStrategy ){
+ return ((LifecycleStrategy)delegate).hasLifecycle(type);
+ }
+ return false;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("[");
+ buffer.append(getPrintableClassName());
+ buffer.append(" delegate=");
+ buffer.append(delegate);
+ buffer.append("]");
+ return buffer.toString();
+ }
+
+ private String getPrintableClassName() {
+ String name = getClass().getName();
+ name = name.substring(name.lastIndexOf('.')+1);
+ if (name.endsWith("ComponentAdapter")) {
+ name = name.substring(0, name.length() - "ComponentAdapter".length()) + "CA";
+ }
+ return name;
+ }
+
+}
+
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DecoratingComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+public class DecoratingComponentAdapterFactory extends MonitoringComponentAdapterFactory {
+ private ComponentAdapterFactory delegate;
+
+ public DecoratingComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ this.delegate = delegate;
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey,
+ Class componentImplementation,
+ Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return delegate.createComponentAdapter(componentKey, componentImplementation, parameters);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+
+/**
+ * Creates instances of {@link ConstructorInjectionComponentAdapter} decorated by
+ * {@link CachingComponentAdapter}.
+ *
+ * @author Jon Tirsén
+ * @author Aslak Hellesøy
+ * @version $Revision: 2779 $
+ */
+public class DefaultComponentAdapterFactory extends MonitoringComponentAdapterFactory {
+
+ private final LifecycleStrategy lifecycleStrategy;
+
+ public DefaultComponentAdapterFactory(ComponentMonitor monitor) {
+ super(monitor);
+ this.lifecycleStrategy = new DefaultLifecycleStrategy(monitor);
+ }
+
+ public DefaultComponentAdapterFactory(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy) {
+ super(monitor);
+ this.lifecycleStrategy = lifecycleStrategy;
+ }
+
+ public DefaultComponentAdapterFactory() {
+ this.lifecycleStrategy = new DefaultLifecycleStrategy(new DefaultComponentMonitor());
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters, false, currentMonitor(), lifecycleStrategy));
+ }
+
+ public void changeMonitor(ComponentMonitor monitor) {
+ super.changeMonitor(monitor);
+ if (lifecycleStrategy instanceof ComponentMonitorStrategy) {
+ ((ComponentMonitorStrategy) lifecycleStrategy).changeMonitor(monitor);
+ }
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultLifecycleStrategy.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultLifecycleStrategy.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultLifecycleStrategy.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Disposable;
+import org.picocontainer.Startable;
+
+import java.lang.reflect.Method;
+
+/**
+ * Default lifecycle strategy. Starts and stops component if Startable,
+ * and disposes it if Disposable.
+ *
+ * @author Mauro Talevi
+ * @author Jörg Schaible
+ * @see Startable
+ * @see Disposable
+ */
+public class DefaultLifecycleStrategy extends AbstractMonitoringLifecycleStrategy {
+
+ private static Method start, stop, dispose;
+ {
+ try {
+ start = Startable.class.getMethod("start", (Class[])null);
+ stop = Startable.class.getMethod("stop", (Class[])null);
+ dispose = Disposable.class.getMethod("dispose", (Class[])null);
+ } catch (NoSuchMethodException e) {
+ }
+ }
+
+ public DefaultLifecycleStrategy(ComponentMonitor monitor) {
+ super(monitor);
+ }
+
+ public void start(Object component) {
+ if (component != null && component instanceof Startable) {
+ long str = System.currentTimeMillis();
+ currentMonitor().invoking(start, component);
+ try {
+ ((Startable) component).start();
+ currentMonitor().invoked(start, component, System.currentTimeMillis() - str);
+ } catch (RuntimeException cause) {
+ currentMonitor().lifecycleInvocationFailed(start, component, cause); // may re-throw
+ }
+ }
+ }
+
+ public void stop(Object component) {
+ if (component != null && component instanceof Startable) {
+ long str = System.currentTimeMillis();
+ currentMonitor().invoking(stop, component);
+ try {
+ ((Startable) component).stop();
+ currentMonitor().invoked(stop, component, System.currentTimeMillis() - str);
+ } catch (RuntimeException cause) {
+ currentMonitor().lifecycleInvocationFailed(stop, component, cause); // may re-throw
+ }
+ }
+ }
+
+ public void dispose(Object component) {
+ if (component != null && component instanceof Disposable) {
+ long str = System.currentTimeMillis();
+ currentMonitor().invoking(dispose, component);
+ try {
+ ((Disposable) component).dispose();
+ currentMonitor().invoked(dispose, component, System.currentTimeMillis() - str);
+ } catch (RuntimeException cause) {
+ currentMonitor().lifecycleInvocationFailed(dispose, component, cause); // may re-throw
+ }
+ }
+ }
+
+ public boolean hasLifecycle(Class type) {
+ return Startable.class.isAssignableFrom(type) || Disposable.class.isAssignableFrom(type);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultPicoContainer.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultPicoContainer.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DefaultPicoContainer.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,777 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.LifecycleManager;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoException;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoVerificationException;
+import org.picocontainer.PicoVisitor;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+import org.jboss.kernel.spi.dependency.KernelController;
+import org.jboss.kernel.plugins.dependency.AbstractKernelController;
+import org.jboss.kernel.plugins.dependency.AbstractKernelControllerContext;
+import org.jboss.microcontainer.KernelControllerHelper;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+
+/**
+ * <p/>
+ * 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.
+ * </p>
+ * <p/>
+ * Using {@link Class} objects as keys to the various registerXXX() methods makes
+ * a subtle semantic difference:
+ * </p>
+ * <p/>
+ * 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 component
+ * will take precedence over other components during type resolution.
+ * </p>
+ * <p/>
+ * Another place where keys that are classes make a subtle difference is in
+ * {@link org.picocontainer.defaults.ImplementationHidingComponentAdapter}.
+ * </p>
+ * <p/>
+ * This implementation of {@link MutablePicoContainer} also supports
+ * {@link ComponentMonitorStrategy}.
+ * </p>
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Jon Tirsén
+ * @author Thomas Heller
+ * @author Mauro Talevi
+ * @version $Revision: 1.8 $
+ */
+public class DefaultPicoContainer implements MutablePicoContainer, ComponentMonitorStrategy, Serializable {
+ //private Map componentKeyToAdapterCache = new HashMap();
+ private ComponentAdapterFactory componentAdapterFactory;
+ private PicoContainer parent;
+ private Set children = new HashSet();
+
+ //private List componentAdapters = new ArrayList();
+ // Keeps track of instantiation order.
+ //private List orderedComponentAdapters = new ArrayList();
+
+ // Keeps track of the container started status
+ private boolean started = false;
+ // Keeps track of the container disposed status
+ private boolean disposed = false;
+ // Keeps track of child containers started status
+ private Set childrenStarted = new HashSet();
+
+ private LifecycleManager lifecycleManager = new OrderedComponentAdapterLifecycleManager();
+ private LifecycleStrategy lifecycleStrategyForInstanceRegistrations;
+
+ private KernelController controller;
+
+ /**
+ * Creates a new container with a custom ComponentAdapterFactory and a parent container.
+ * <p/>
+ * <em>
+ * Important note about caching: If you intend the components to be cached, you should pass
+ * in a factory that creates {@link CachingComponentAdapter} instances, such as for example
+ * {@link CachingComponentAdapterFactory}. CachingComponentAdapterFactory can delegate to
+ * other ComponentAdapterFactories.
+ * </em>
+ *
+ * @param componentAdapterFactory the factory to use for creation of ComponentAdapters.
+ * @param parent the parent container (used for component dependency lookups).
+ */
+ public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
+ this(componentAdapterFactory, new DefaultLifecycleStrategy(new DefaultComponentMonitor()), parent);
+ }
+
+ /**
+ * Creates a new container with a custom ComponentAdapterFactory, LifecycleStrategy for instance registration,
+ * and a parent container.
+ * <p/>
+ * <em>
+ * Important note about caching: If you intend the components to be cached, you should pass
+ * in a factory that creates {@link CachingComponentAdapter} instances, such as for example
+ * {@link CachingComponentAdapterFactory}. CachingComponentAdapterFactory can delegate to
+ * other ComponentAdapterFactories.
+ * </em>
+ *
+ * @param componentAdapterFactory the factory to use for creation of ComponentAdapters.
+ * @param lifecycleStrategyForInstanceRegistrations the lifecylce strategy chosen for regiered
+ * instance (not implementations!)
+ * @param parent the parent container (used for component dependency lookups).
+ */
+ public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory,
+ LifecycleStrategy lifecycleStrategyForInstanceRegistrations,
+ PicoContainer parent) {
+ if (componentAdapterFactory == null) throw new NullPointerException("componentAdapterFactory");
+ if (lifecycleStrategyForInstanceRegistrations == null) throw new NullPointerException("lifecycleStrategyForInstanceRegistrations");
+ this.componentAdapterFactory = componentAdapterFactory;
+ this.lifecycleStrategyForInstanceRegistrations = lifecycleStrategyForInstanceRegistrations;
+
+ //if (parent instanceof DefaultPicoContainer) {
+ // AbstractKernelController ctx = (AbstractKernelController) DefaultPicoContainer.class.cast(parent).getController();
+ // if (ctx != null)
+ // controller = KernelControllerHelper.createChildKernelController(ctx, toString());
+ //}
+
+ if (controller == null) {
+ AbstractKernelController ctx = (AbstractKernelController) KernelControllerHelper.getRootKernelControllerInstance();
+ controller = KernelControllerHelper.createChildKernelController(ctx, toString());
+ }
+
+ this.parent = parent == null ? null : ImmutablePicoContainerProxyFactory.newProxyInstance(parent);
+ }
+
+ /**
+ * Creates a new container with the DefaultComponentAdapterFactory using a
+ * custom ComponentMonitor
+ *
+ * @param monitor the ComponentMonitor to use
+ * @param parent the parent container (used for component dependency lookups).
+ */
+ public DefaultPicoContainer(ComponentMonitor monitor, PicoContainer parent) {
+ this(new DefaultComponentAdapterFactory(monitor), parent);
+ lifecycleStrategyForInstanceRegistrations = new DefaultLifecycleStrategy(monitor);
+ }
+
+ /**
+ * Creates a new container with the DefaultComponentAdapterFactory 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(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
+ this(new DefaultComponentAdapterFactory(monitor, lifecycleStrategy), lifecycleStrategy, parent);
+ }
+
+ /**
+ * Creates a new container with the DefaultComponentAdapterFactory using a
+ * custom lifecycle strategy
+ *
+ * @param lifecycleStrategy the lifecycle strategy to use.
+ * @param parent the parent container (used for component dependency lookups).
+ */
+ public DefaultPicoContainer(LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
+ this(new DefaultComponentMonitor(), lifecycleStrategy, parent);
+ }
+
+
+ /**
+ * Creates a new container with a custom ComponentAdapterFactory and no parent container.
+ *
+ * @param componentAdapterFactory the ComponentAdapterFactory to use.
+ */
+ public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory) {
+ this(componentAdapterFactory, null);
+ }
+
+ /**
+ * Creates a new container with the DefaultComponentAdapterFactory using a
+ * custom ComponentMonitor
+ *
+ * @param monitor the ComponentMonitor to use
+ */
+ public DefaultPicoContainer(ComponentMonitor monitor) {
+ this(monitor, new DefaultLifecycleStrategy(monitor), null);
+ }
+
+ /**
+ * Creates a new container with a (caching) {@link DefaultComponentAdapterFactory}
+ * and a parent container.
+ *
+ * @param parent the parent container (used for component dependency lookups).
+ */
+ public DefaultPicoContainer(PicoContainer parent) {
+ this(new DefaultComponentAdapterFactory(), parent);
+ }
+
+ /**
+ * Creates a new container with a (caching) {@link DefaultComponentAdapterFactory} and no parent container.
+ */
+ public DefaultPicoContainer() {
+ this(new DefaultComponentAdapterFactory(), null);
+ }
+
+ public Collection getComponentAdapters() {
+ return getAdapters();
+ }
+
+ public final ComponentAdapter getComponentAdapter(Object componentKey) {
+ ComponentAdapter adapter = getAdapterForKey(componentKey);
+ if (adapter == null && parent != null) {
+ adapter = parent.getComponentAdapter(componentKey);
+ }
+ return adapter;
+ }
+
+ public ComponentAdapter getComponentAdapterOfType(Class componentType) {
+ // See http://jira.codehaus.org/secure/ViewIssue.jspa?key=PICO-115
+ ComponentAdapter adapterByKey = getComponentAdapter(componentType);
+ if (adapterByKey != null) {
+ return adapterByKey;
+ }
+
+ List found = getComponentAdaptersOfType(componentType);
+
+ if (found.size() == 1) {
+ return ((ComponentAdapter) found.get(0));
+ } else if (found.size() == 0) {
+ if (parent != null) {
+ return parent.getComponentAdapterOfType(componentType);
+ } else {
+ return null;
+ }
+ } else {
+ Class[] foundClasses = new Class[found.size()];
+ for (int i = 0; i < foundClasses.length; i++) {
+ foundClasses[i] = ((ComponentAdapter) found.get(i)).getComponentImplementation();
+ }
+
+ throw new AmbiguousComponentResolutionException(componentType, foundClasses);
+ }
+ }
+
+ public List getComponentAdaptersOfType(Class componentType) {
+ if (componentType == null) {
+ return Collections.EMPTY_LIST;
+ }
+ List found = new ArrayList();
+ for (Iterator iterator = getComponentAdapters().iterator(); iterator.hasNext();) {
+ ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+
+ if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) {
+ found.add(componentAdapter);
+ }
+ }
+ return found;
+ }
+
+ /**
+ * {@inheritDoc}
+ * This method can be used to override the ComponentAdapter created by the {@link ComponentAdapterFactory}
+ * passed to the constructor of this container.
+ */
+ public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) {
+ Object componentKey = componentAdapter.getComponentKey();
+ if (getAdapterForKey(componentKey) != null) {
+ throw new DuplicateComponentKeyRegistrationException(componentKey);
+ }
+
+ registerAdapterForKey(componentKey, componentAdapter);
+ return componentAdapter;
+ }
+
+ public ComponentAdapter unregisterComponent(Object componentKey) {
+ ComponentAdapter adapter = removeAdapterForKey(componentKey);
+ return adapter;
+ }
+
+ /**
+ * {@inheritDoc}
+ * The returned ComponentAdapter will be an {@link InstanceComponentAdapter}.
+ */
+ public ComponentAdapter registerComponentInstance(Object component) {
+ return registerComponentInstance(component.getClass(), component);
+ }
+
+ /**
+ * {@inheritDoc}
+ * The returned ComponentAdapter will be an {@link InstanceComponentAdapter}.
+ */
+ public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) {
+ ComponentAdapter componentAdapter = new InstanceComponentAdapter(componentKey, componentInstance, lifecycleStrategyForInstanceRegistrations);
+ return registerComponent(componentAdapter);
+ }
+
+ /**
+ * {@inheritDoc}
+ * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
+ * passed to the container's constructor.
+ */
+ public ComponentAdapter registerComponentImplementation(Class componentImplementation) {
+ return registerComponentImplementation(componentImplementation, componentImplementation);
+ }
+
+ /**
+ * {@inheritDoc}
+ * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
+ * passed to the container's constructor.
+ */
+ public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) {
+ return registerComponentImplementation(componentKey, componentImplementation, (Parameter[]) null);
+ }
+
+ /**
+ * {@inheritDoc}
+ * The returned ComponentAdapter will be instantiated by the {@link ComponentAdapterFactory}
+ * passed to the container's constructor.
+ */
+ public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) {
+ ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters);
+ return registerComponent(componentAdapter);
+ }
+
+ /**
+ * Same as {@link #registerComponentImplementation(java.lang.Object, java.lang.Class, org.picocontainer.Parameter[])}
+ * but with parameters as a {@link List}. Makes it possible to use with Groovy arrays (which are actually Lists).
+ */
+ public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, List parameters) {
+ Parameter[] parametersAsArray = (Parameter[]) parameters.toArray(new Parameter[parameters.size()]);
+ return registerComponentImplementation(componentKey, componentImplementation, parametersAsArray);
+ }
+
+ private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) {
+ //if (!orderedComponentAdapters.contains(componentAdapter)) {
+ // orderedComponentAdapters.add(componentAdapter);
+ //}
+ }
+
+ public List getComponentInstances() throws PicoException {
+ return getComponentInstancesOfType(Object.class);
+ }
+
+ public List getComponentInstancesOfType(Class componentType) {
+ if (componentType == null) {
+ return Collections.EMPTY_LIST;
+ }
+
+ Map adapterToInstanceMap = new HashMap();
+ for (Iterator iterator = getAdapters().iterator(); iterator.hasNext();) {
+ ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+ if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) {
+ Object componentInstance = getInstance(componentAdapter);
+ adapterToInstanceMap.put(componentAdapter, componentInstance);
+
+ // This is to ensure all are added. (Indirect dependencies will be added
+ // from InstantiatingComponentAdapter).
+ addOrderedComponentAdapter(componentAdapter);
+ }
+ }
+ List result = new ArrayList();
+ for (Iterator iterator = getOrderedAdapters().iterator(); iterator.hasNext();) {
+ Object componentAdapter = iterator.next();
+ final Object componentInstance = adapterToInstanceMap.get(componentAdapter);
+ if (componentInstance != null) {
+ // may be null in the case of the "implicit" adapter
+ // representing "this".
+ result.add(componentInstance);
+ }
+ }
+ return result;
+ }
+
+ public Object getComponentInstance(Object componentKey) {
+ ComponentAdapter componentAdapter = getComponentAdapter(componentKey);
+ if (componentAdapter != null) {
+ return getInstance(componentAdapter);
+ } else {
+ return null;
+ }
+ }
+
+ public Object getComponentInstanceOfType(Class componentType) {
+ final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType);
+ return componentAdapter == null ? null : getInstance(componentAdapter);
+ }
+
+ private Object getInstance(ComponentAdapter componentAdapter) {
+ // check wether this is our adapter
+ // we need to check this to ensure up-down dependencies cannot be followed
+ final boolean isLocal = getAdapterForKey(componentAdapter.getComponentKey()) != null;
+
+ if (isLocal) {
+ PicoException firstLevelException = null;
+ Object instance = null;
+ try {
+ instance = componentAdapter.getComponentInstance(this);
+ } catch (PicoInitializationException e) {
+ firstLevelException = e;
+ } catch (PicoIntrospectionException e) {
+ firstLevelException = e;
+ }
+ if (firstLevelException != null) {
+ if (parent != null) {
+ instance = parent.getComponentInstance(componentAdapter.getComponentKey());
+ if( instance != null ) {
+ return instance;
+ }
+ }
+
+ throw firstLevelException;
+ }
+ addOrderedComponentAdapter(componentAdapter);
+
+ return instance;
+ } else if (parent != null) {
+ return parent.getComponentInstance(componentAdapter.getComponentKey());
+ }
+
+ return null;
+ }
+
+
+ public PicoContainer getParent() {
+ return parent;
+ }
+
+ public ComponentAdapter unregisterComponentByInstance(Object componentInstance) {
+ Collection componentAdapters = getComponentAdapters();
+ for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) {
+ ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+ if (getInstance(componentAdapter).equals(componentInstance)) {
+ return unregisterComponent(componentAdapter.getComponentKey());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @deprecated since 1.1 - Use "new VerifyingVisitor().traverse(this)"
+ */
+ public void verify() throws PicoVerificationException {
+ new VerifyingVisitor().traverse(this);
+ }
+
+ /**
+ * 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 LifecycleManager lifecycle manager}.
+ * The actual {@link LifecycleStrategy lifecycle strategy} supported
+ * depends on the concrete implementation of the adapter.
+ *
+ * @see LifecycleManager
+ * @see LifecycleStrategy
+ * @see #makeChildContainer()
+ * @see #addChildContainer(PicoContainer)
+ * @see #removeChildContainer(PicoContainer)
+ */
+ public void start() {
+ if (disposed) throw new IllegalStateException("Already disposed");
+ if (started) throw new IllegalStateException("Already started");
+ started = true;
+ this.lifecycleManager.start(this);
+ childrenStarted.clear();
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ PicoContainer child = (PicoContainer) iterator.next();
+ childrenStarted.add(new Integer(child.hashCode()));
+ 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 LifecycleManager lifecycle manager}.
+ * The actual {@link LifecycleStrategy lifecycle strategy} supported
+ * depends on the concrete implementation of the adapter.
+ *
+ * @see LifecycleManager
+ * @see LifecycleStrategy
+ * @see #makeChildContainer()
+ * @see #addChildContainer(PicoContainer)
+ * @see #removeChildContainer(PicoContainer)
+ */
+ public void stop() {
+ if (disposed) throw new IllegalStateException("Already disposed");
+ if (!started) throw new IllegalStateException("Not started");
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ PicoContainer child = (PicoContainer) iterator.next();
+ if ( childStarted(child) ){
+ child.stop();
+ }
+ }
+ this.lifecycleManager.stop(this);
+ started = false;
+ }
+
+ /**
+ * 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, <code>true</code> if the container is started
+ */
+ private boolean childStarted(PicoContainer child) {
+ return childrenStarted.contains(new Integer(child.hashCode()));
+ }
+
+ /**
+ * 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 LifecycleManager lifecycle manager}.
+ * The actual {@link LifecycleStrategy lifecycle strategy} supported
+ * depends on the concrete implementation of the adapter.
+ *
+ * @see LifecycleManager
+ * @see LifecycleStrategy
+ * @see #makeChildContainer()
+ * @see #addChildContainer(PicoContainer)
+ * @see #removeChildContainer(PicoContainer)
+ */
+ public void dispose() {
+ if (disposed) throw new IllegalStateException("Already disposed");
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ PicoContainer child = (PicoContainer) iterator.next();
+ child.dispose();
+ }
+ this.lifecycleManager.dispose(this);
+ disposed = true;
+ }
+
+ public MutablePicoContainer makeChildContainer() {
+ DefaultPicoContainer pc = new DefaultPicoContainer(componentAdapterFactory,
+ lifecycleStrategyForInstanceRegistrations,
+ this);
+ addChildContainer(pc);
+ return pc;
+ }
+
+ public boolean addChildContainer(PicoContainer child) {
+ if (children.add(child)) {
+ // @todo Should only be added if child container has also be started
+ if (started) {
+ childrenStarted.add(new Integer(child.hashCode()));
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean removeChildContainer(PicoContainer child) {
+ final boolean result = children.remove(child);
+ return result;
+ }
+
+ public void accept(PicoVisitor visitor) {
+ visitor.visitContainer(this);
+ final List componentAdapters = new ArrayList(getComponentAdapters());
+ for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) {
+ ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
+ componentAdapter.accept(visitor);
+ }
+ final List allChildren = new ArrayList(children);
+ for (Iterator iterator = allChildren.iterator(); iterator.hasNext();) {
+ PicoContainer child = (PicoContainer) iterator.next();
+ child.accept(visitor);
+ }
+ }
+
+ /**
+ * Changes monitor in the ComponentAdapterFactory, the component adapters
+ * and the child containers, if these support a ComponentMonitorStrategy.
+ * {@inheritDoc}
+ */
+ public void changeMonitor(ComponentMonitor monitor) {
+ // will also change monitor in lifecycleStrategyForInstanceRegistrations
+ if (componentAdapterFactory instanceof ComponentMonitorStrategy) {
+ ((ComponentMonitorStrategy) componentAdapterFactory).changeMonitor(monitor);
+ }
+ for ( Iterator i = getAdapters().iterator(); i.hasNext(); ){
+ Object adapter = i.next();
+ if ( adapter instanceof ComponentMonitorStrategy ) {
+ ((ComponentMonitorStrategy)adapter).changeMonitor(monitor);
+ }
+ }
+ for (Iterator i = children.iterator(); i.hasNext();) {
+ Object child = i.next();
+ if (child instanceof ComponentMonitorStrategy) {
+ ((ComponentMonitorStrategy) child).changeMonitor(monitor);
+ }
+ }
+ }
+
+ /**
+ * Returns the first current monitor found in the ComponentAdapterFactory, the component adapters
+ * and the child containers, if these support a ComponentMonitorStrategy.
+ * {@inheritDoc}
+ * @throws PicoIntrospectionException if no component monitor is found in container or its children
+ */
+ public ComponentMonitor currentMonitor() {
+ if (componentAdapterFactory instanceof ComponentMonitorStrategy) {
+ return ((ComponentMonitorStrategy) componentAdapterFactory).currentMonitor();
+ }
+ for ( Iterator i = getAdapters().iterator(); i.hasNext(); ){
+ Object adapter = i.next();
+ if ( adapter instanceof ComponentMonitorStrategy ) {
+ return ((ComponentMonitorStrategy)adapter).currentMonitor();
+ }
+ }
+ for (Iterator i = children.iterator(); i.hasNext();) {
+ Object child = i.next();
+ if (child instanceof ComponentMonitorStrategy) {
+ return ((ComponentMonitorStrategy) child).currentMonitor();
+ }
+ }
+ throw new PicoIntrospectionException("No component monitor found in container or its children");
+ }
+
+ public KernelController getController() {
+ return controller;
+ }
+
+ /**
+ * <p>
+ * Implementation of lifecycle manager which delegates to the container's component adapters.
+ * The component adapters will be ordered by dependency as registered in the container.
+ * This LifecycleManager will delegate calls on the lifecycle methods to the component adapters
+ * if these are themselves LifecycleManagers.
+ * </p>
+ *
+ * @author Mauro Talevi
+ * @since 1.2
+ */
+ private class OrderedComponentAdapterLifecycleManager implements LifecycleManager, Serializable {
+
+ /** List collecting the CAs which have been successfully started */
+ private List startedComponentAdapters = new ArrayList();
+
+ /**
+ * {@inheritDoc}
+ * Loops over all component adapters and invokes
+ * start(PicoContainer) method on the ones which are LifecycleManagers
+ */
+ public void start(PicoContainer node) {
+ Collection adapters = getComponentAdapters();
+ for (final Iterator iter = adapters.iterator(); iter.hasNext();) {
+ final ComponentAdapter adapter = (ComponentAdapter)iter.next();
+ if ( adapter instanceof LifecycleManager ){
+ LifecycleManager manager = (LifecycleManager)adapter;
+ if (manager.hasLifecycle()) {
+ // create an instance, it will be added to the ordered CA list
+ adapter.getComponentInstance(node);
+ addOrderedComponentAdapter(adapter);
+ }
+ }
+ }
+ adapters = getOrderedAdapters();
+ // clear list of started CAs
+ startedComponentAdapters.clear();
+ for (final Iterator iter = adapters.iterator(); iter.hasNext();) {
+ final Object adapter = iter.next();
+ if ( adapter instanceof LifecycleManager ){
+ LifecycleManager manager = (LifecycleManager)adapter;
+ manager.start(node);
+ startedComponentAdapters.add(adapter);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * Loops over started component adapters (in inverse order) and invokes
+ * stop(PicoContainer) method on the ones which are LifecycleManagers
+ */
+ public void stop(PicoContainer node) {
+ List adapters = startedComponentAdapters;
+ for (int i = adapters.size() - 1; 0 <= i; i--) {
+ Object adapter = adapters.get(i);
+ if ( adapter instanceof LifecycleManager ){
+ LifecycleManager manager = (LifecycleManager)adapter;
+ manager.stop(node);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * Loops over all component adapters (in inverse order) and invokes
+ * dispose(PicoContainer) method on the ones which are LifecycleManagers
+ */
+ public void dispose(PicoContainer node) {
+ List adapters = getOrderedAdapters();
+ for (int i = adapters.size() - 1; 0 <= i; i--) {
+ Object adapter = adapters.get(i);
+ if ( adapter instanceof LifecycleManager ){
+ LifecycleManager manager = (LifecycleManager)adapter;
+ manager.dispose(node);
+ }
+ }
+ }
+
+ public boolean hasLifecycle() {
+ throw new UnsupportedOperationException("Should not have been called");
+ }
+
+ }
+
+ private ComponentAdapter getAdapterForKey(Object key) {
+ //return (ComponentAdapter) componentKeyToAdapterCache.get(key);
+ ControllerContext entry = controller.getInstalledContext(key.toString());
+ if (entry == null)
+ return null;
+
+ return (ComponentAdapter) entry.getTarget();
+ }
+
+ private void registerAdapterForKey(Object componentKey, ComponentAdapter componentAdapter) {
+ //componentAdapters.add(componentAdapter);
+ //componentKeyToAdapterCache.put(componentKey, componentAdapter);
+
+ try {
+ BeanMetaDataBuilder bmf = BeanMetaDataBuilder.createBuilder(componentKey.toString(),
+ componentAdapter.getClass().getName());
+
+ bmf.addAnnotation(KernelControllerHelper.getAppScopeAnnotation(toString()));
+
+ BeanMetaData bmeta = bmf.getBeanMetaData();
+ AbstractKernelControllerContext ctx = new AbstractKernelControllerContext(null, bmeta, componentAdapter);
+ controller.install(ctx);
+
+ } catch (Throwable ex) {
+ throw new RuntimeException("Failed to install component with controller (key: " + componentKey
+ + ", componentAdapter: " + componentAdapter + ", controller: " + controller + ")");
+ }
+ }
+
+ private ComponentAdapter removeAdapterForKey(Object componentKey) {
+ //ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.remove(componentKey);
+ //componentAdapters.remove(adapter);
+ //orderedComponentAdapters.remove(adapter);
+ //return adapter;
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ private List getAdapters() {
+ //return Collections.unmodifiableList(componentAdapters);
+ return KernelControllerHelper.unwrapComponentAdapters(controller.getContextsByState(ControllerState.INSTALLED));
+ }
+
+ private List getOrderedAdapters() {
+ //return orderedComponentAdapters;
+ return getAdapters();
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DelegatingComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DelegatingComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DelegatingComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+
+/**
+ * <p>
+ * A {@link ComponentMonitor monitor} which delegates to another monitor.
+ * It provides a {@link DefaultComponentMonitor default ComponentMonitor},
+ * but does not allow to use <code>null</code> for the delegate.
+ * </p>
+ * <p>
+ * It also supports a {@link ComponentMonitorStrategy monitor strategy}
+ * that allows to change the delegate.
+ * </p>
+ *
+ * @author Mauro Talevi
+ * @version $Revision: $
+ * @since 1.2
+ */
+public class DelegatingComponentMonitor implements ComponentMonitor, ComponentMonitorStrategy, Serializable {
+
+ private ComponentMonitor delegate;
+
+ /**
+ * Creates a DelegatingComponentMonitor with a given delegate
+ * @param delegate the ComponentMonitor to which this monitor delegates
+ */
+ public DelegatingComponentMonitor(ComponentMonitor delegate) {
+ checkMonitor(delegate);
+ this.delegate = delegate;
+ }
+
+ /**
+ * Creates a DelegatingComponentMonitor with an instance of
+ * {@link DefaultComponentMonitor}.
+ */
+ public DelegatingComponentMonitor() {
+ this(DefaultComponentMonitor.getInstance());
+ }
+
+ public void instantiating(Constructor constructor) {
+ delegate.instantiating(constructor);
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ delegate.instantiated(constructor, duration);
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception e) {
+ delegate.instantiationFailed(constructor, e);
+ }
+
+ public void invoking(Method method, Object instance) {
+ delegate.invoking(method, instance);
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ delegate.invoked(method, instance, duration);
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception e) {
+ delegate.invocationFailed(method, instance, e);
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ delegate.lifecycleInvocationFailed(method,instance, cause);
+ }
+
+ /**
+ * 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");
+ }
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DuplicateComponentKeyRegistrationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DuplicateComponentKeyRegistrationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/DuplicateComponentKeyRegistrationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoRegistrationException;
+
+/**
+ * @author Jon Tirsén
+ * @version $Revision: 1.5 $
+ */
+public class DuplicateComponentKeyRegistrationException extends PicoRegistrationException {
+ private Object key;
+
+ public DuplicateComponentKeyRegistrationException(Object key) {
+ super("Key " + key + " duplicated");
+ this.key = key;
+ }
+
+ public Object getDuplicateKey() {
+ return key;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImmutablePicoContainerProxyFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImmutablePicoContainerProxyFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImmutablePicoContainerProxyFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * 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 Joerg Schaible *
+ *****************************************************************************/
+package org.picocontainer.defaults;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.picocontainer.Disposable;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.Startable;
+
+
+/**
+ * A factory for immutable PicoContainer proxies.
+ *
+ * @author Jörg Schaible
+ * @since 1.2
+ */
+public class ImmutablePicoContainerProxyFactory implements InvocationHandler, Serializable {
+
+ private static final Class[] interfaces = new Class[]{PicoContainer.class};
+ protected static Method startMethod = null;
+ protected static Method stopMethod = null;
+ protected static Method disposeMethod = null;
+ protected static Method equalsMethod = null;
+
+ static {
+ try {
+ startMethod = Startable.class.getMethod("start", new Class[0]);
+ stopMethod = Startable.class.getMethod("stop", new Class[0]);
+ disposeMethod = Disposable.class.getMethod("dispose", new Class[0]);
+ equalsMethod = Object.class.getMethod("equals", new Class[]{Object.class});
+ } catch (final NoSuchMethodException e) {
+ throw new InternalError(e.getMessage());
+ }
+ }
+
+ private final PicoContainer pico;
+
+ /**
+ * Construct a ImmutablePicoContainerProxyFactory.
+ *
+ * @param pico the container to hide
+ * @throws NullPointerException if <tt>pico</tt> is <code>null</code>
+ * @since 1.2
+ */
+ protected ImmutablePicoContainerProxyFactory(final PicoContainer pico) {
+ if (pico == null) {
+ throw new NullPointerException();
+ }
+ this.pico = pico;
+ }
+
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ if (method.equals(startMethod) || method.equals(stopMethod) || method.equals(disposeMethod)) {
+ throw new UnsupportedOperationException("This container is immutable, "
+ + method.getName()
+ + " is not allowed");
+ } else if (method.equals(equalsMethod)) { // necessary for JDK 1.3
+ return new Boolean(args[0] != null && args[0].equals(pico));
+ }
+ try {
+ return method.invoke(pico, args);
+ } catch (final InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+
+ /**
+ * Create a new immutable PicoContainer proxy. The proxy will completly hide the implementation of the given
+ * {@link PicoContainer} and will also prevent the invocation of any methods of the lifecycle methods from
+ * {@link Startable} or {@link Disposable}.
+ *
+ * @param pico
+ * @return the new proxy
+ * @throws NullPointerException if <tt>pico</tt> is <code>null</code>
+ * @since 1.2
+ */
+ public static PicoContainer newProxyInstance(final PicoContainer pico) {
+ return (PicoContainer)Proxy.newProxyInstance(
+ PicoContainer.class.getClassLoader(), interfaces,
+ new ImmutablePicoContainerProxyFactory(pico));
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * This component adapter makes it possible to hide the implementation
+ * of a real subject (behind a proxy) provided the key is an interface.
+ * <p/>
+ * 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.HotSwappingComponentAdapter for a more feature-rich version of this class.
+ * @since 1.2, moved from package {@link org.picocontainer.alternatives}
+ */
+public class ImplementationHidingComponentAdapter extends DecoratingComponentAdapter {
+ private final boolean strict;
+
+ /**
+ * Creates an ImplementationHidingComponentAdapter with a delegate
+ * @param delegate the component adapter to which this adapter delegates
+ * @param strict the scrict mode boolean
+ */
+ public ImplementationHidingComponentAdapter(ComponentAdapter delegate, boolean strict) {
+ super(delegate);
+ this.strict = strict;
+ }
+
+ public Object getComponentInstance(final PicoContainer container)
+ throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+
+ Object componentKey = getDelegate().getComponentKey();
+ Class[] classes = null;
+ if (componentKey instanceof Class && ((Class) getDelegate().getComponentKey()).isInterface()) {
+ classes = new Class[]{(Class) getDelegate().getComponentKey()};
+ } else if (componentKey instanceof Class[]) {
+ classes = (Class[]) componentKey;
+ } else {
+ if(strict) {
+ throw new PicoIntrospectionException("In strict mode, " + getClass().getName() + " only allows components registered with interface keys (java.lang.Class or java.lang.Class[])");
+ }
+ return getDelegate().getComponentInstance(container);
+ }
+
+ Class[] interfaces = verifyInterfacesOnly(classes);
+ return createProxy(interfaces, container, getDelegate().getComponentImplementation().getClassLoader());
+ }
+
+ private Object createProxy(Class[] interfaces, final PicoContainer container, final ClassLoader classLoader) {
+ return Proxy.newProxyInstance(classLoader,
+ interfaces, new InvocationHandler() {
+ public Object invoke(final Object proxy, final Method method,
+ final Object[] args)
+ throws Throwable {
+ Object componentInstance = getDelegate().getComponentInstance(container);
+ ComponentMonitor componentMonitor = currentMonitor();
+ try {
+ componentMonitor.invoking(method, componentInstance);
+ long startTime = System.currentTimeMillis();
+ Object object = method.invoke(componentInstance, args);
+ componentMonitor.invoked(method, componentInstance, System.currentTimeMillis() - startTime);
+ return object;
+ } catch (final InvocationTargetException ite) {
+ componentMonitor.invocationFailed(method, componentInstance, ite);
+ throw ite.getTargetException();
+ }
+ }
+ });
+ }
+
+ private Class[] verifyInterfacesOnly(Class[] classes) {
+ for (int i = 0; i < classes.length; i++) {
+ if(!classes[i].isInterface()) {
+ throw new PicoIntrospectionException("Class keys must be interfaces. " + classes[i] + " is not an interface.");
+ }
+ }
+ return classes;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ImplementationHidingComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * @author Aslak Hellesøy
+ * @see org.picocontainer.gems.HotSwappingComponentAdapterFactory for a more feature-rich version of the class
+ * @since 1.2, moved from package {@link org.picocontainer.alternatives}
+ */
+public class ImplementationHidingComponentAdapterFactory extends DecoratingComponentAdapterFactory {
+ private final boolean strict;
+
+ /**
+ * For serialisation only. Do not use this constructor explicitly.
+ */
+ public ImplementationHidingComponentAdapterFactory() {
+ this(null);
+ }
+
+ public ImplementationHidingComponentAdapterFactory(ComponentAdapterFactory delegate, boolean strict) {
+ super(delegate);
+ this.strict = strict;
+ }
+
+ public ImplementationHidingComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ this(delegate, true);
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return new ImplementationHidingComponentAdapter(super.createComponentAdapter(componentKey, componentImplementation, parameters), strict);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstanceComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstanceComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstanceComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,96 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.LifecycleManager;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+
+/**
+ * <p>
+ * Component adapter which wraps a component instance.
+ * </p>
+ * <p>
+ * This component adapter supports both a {@link LifecycleManager LifecycleManager} and a
+ * {@link LifecycleStrategy LifecycleStrategy} to control the lifecycle of the component.
+ * The lifecycle manager methods simply delegate to the lifecycle strategy methods
+ * on the component instance.
+ * </p>
+ *
+ * @author Aslak Hellesøy
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ * @version $Revision: 2823 $
+ */
+public class InstanceComponentAdapter extends AbstractComponentAdapter implements LifecycleManager, LifecycleStrategy {
+ private Object componentInstance;
+ private LifecycleStrategy lifecycleStrategy;
+
+ public InstanceComponentAdapter(Object componentKey, Object componentInstance) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ this(componentKey, componentInstance, new DefaultLifecycleStrategy(new DefaultComponentMonitor()));
+ }
+
+ public InstanceComponentAdapter(Object componentKey, Object componentInstance, LifecycleStrategy lifecycleStrategy) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, getInstanceClass(componentInstance));
+ this.componentInstance = componentInstance;
+ this.lifecycleStrategy = lifecycleStrategy;
+ }
+
+ private static Class getInstanceClass(Object componentInstance) {
+ if (componentInstance == null) {
+ throw new NullPointerException("componentInstance cannot be null");
+ }
+ return componentInstance.getClass();
+ }
+
+ public Object getComponentInstance(PicoContainer container) {
+ return componentInstance;
+ }
+
+ public void verify(PicoContainer container) {
+ }
+
+ // ~~~~~~~~ LifecylceManager ~~~~~~~~
+
+ public void start(PicoContainer container) {
+ start(componentInstance);
+ }
+
+ public void stop(PicoContainer container) {
+ stop(componentInstance);
+ }
+
+ public void dispose(PicoContainer container) {
+ dispose(componentInstance);
+ }
+
+ public boolean hasLifecycle() {
+ return hasLifecycle(componentInstance.getClass());
+ }
+
+ // ~~~~~~~~ LifecylceStrategy ~~~~~~~~
+
+ public void start(Object component) {
+ lifecycleStrategy.start(componentInstance);
+ }
+
+ public void stop(Object component) {
+ lifecycleStrategy.stop(componentInstance);
+ }
+
+ public void dispose(Object component) {
+ lifecycleStrategy.dispose(componentInstance);
+ }
+
+ public boolean hasLifecycle(Class type) {
+ return lifecycleStrategy.hasLifecycle(type);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstantiatingComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstantiatingComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/InstantiatingComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,208 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoVisitor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+
+/**
+ * This ComponentAdapter will instantiate a new object for each call to
+ * {@link org.picocontainer.ComponentAdapter#getComponentInstance(PicoContainer)}.
+ * That means that when used with a PicoContainer, getComponentInstance will
+ * return a new object each time.
+ *
+ * @author Aslak Hellesøy
+ * @author Paul Hammant
+ * @author Jörg Schaible
+ * @author Mauro Talevi
+ * @version $Revision: 2788 $
+ * @since 1.0
+ */
+public abstract class InstantiatingComponentAdapter extends AbstractComponentAdapter
+ implements LifecycleStrategy {
+ /** The cycle guard for the verification. */
+ protected transient Guard verifyingGuard;
+ /** The parameters to use for initialization. */
+ protected transient Parameter[] parameters;
+ /** Flag indicating instanciation of non-public classes. */
+ protected boolean allowNonPublicClasses;
+
+ /** The cycle guard for the verification. */
+ protected static abstract class Guard extends ThreadLocalCyclicDependencyGuard {
+ protected PicoContainer guardedContainer;
+ protected void setArguments(PicoContainer container) {
+ this.guardedContainer = container;
+ }
+ }
+
+ /** The strategy used to control the lifecycle */
+ protected LifecycleStrategy lifecycleStrategy;
+
+ /**
+ * 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 allowNonPublicClasses flag to allow instantiation of non-public classes
+ * @param monitor the component monitor used by this ComponentAdapter
+ * @param lifecycleStrategy the lifecycle strategy used by this ComponentAdapter
+ * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to
+ * @throws NotConcreteRegistrationException if the implementation is not a concrete class
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ protected InstantiatingComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses,
+ ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy) {
+ super(componentKey, componentImplementation, monitor);
+ 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;
+ this.allowNonPublicClasses = allowNonPublicClasses;
+ this.lifecycleStrategy = lifecycleStrategy;
+ }
+
+ /**
+ * 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 allowNonPublicClasses flag to allow instantiation of non-public classes
+ * @param monitor the component monitor used by this ComponentAdapter
+ * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to
+ * @throws NotConcreteRegistrationException if the implementation is not a concrete class
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ protected InstantiatingComponentAdapter(Object componentKey, Class componentImplementation,
+ Parameter[] parameters, boolean allowNonPublicClasses,
+ ComponentMonitor monitor) {
+ this(componentKey, componentImplementation, parameters, allowNonPublicClasses, monitor, new DefaultLifecycleStrategy(monitor));
+ }
+
+ /**
+ * 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 allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ protected InstantiatingComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses) {
+ this(componentKey, componentImplementation, parameters, allowNonPublicClasses, new DelegatingComponentMonitor());
+ }
+
+ 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 parameters the parameter types
+ * @return the array with the default parameters.
+ */
+ protected Parameter[] createDefaultParameters(Class[] parameters) {
+ Parameter[] componentParameters = new Parameter[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ componentParameters[i] = ComponentParameter.DEFAULT;
+ }
+ return componentParameters;
+ }
+
+ public void verify(final PicoContainer container) throws PicoIntrospectionException {
+ if (verifyingGuard == null) {
+ verifyingGuard = new Guard() {
+ public Object run() {
+ final Constructor constructor = getGreediestSatisfiableConstructor(guardedContainer);
+ final Class[] parameterTypes = constructor.getParameterTypes();
+ final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
+ for (int i = 0; i < currentParameters.length; i++) {
+ currentParameters[i].verify(container, InstantiatingComponentAdapter.this, parameterTypes[i]);
+ }
+ return null;
+ }
+ };
+ }
+ verifyingGuard.setArguments(container);
+ verifyingGuard.observe(getComponentImplementation());
+ }
+
+ public void accept(PicoVisitor visitor) {
+ super.accept(visitor);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ parameters[i].accept(visitor);
+ }
+ }
+ }
+
+ 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);
+ }
+
+ /**
+ * 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 Object newInstance(Constructor constructor, Object[] parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException {
+ if (allowNonPublicClasses) {
+ constructor.setAccessible(true);
+ }
+ return constructor.newInstance(parameters);
+ }
+
+ /**
+ * Find and return the greediest satisfiable constructor.
+ *
+ * @param container the PicoContainer to resolve dependencies.
+ * @return the found constructor.
+ * @throws PicoIntrospectionException
+ * @throws UnsatisfiableDependenciesException
+ * @throws AmbiguousComponentResolutionException
+ * @throws AssignabilityRegistrationException
+ * @throws NotConcreteRegistrationException
+ */
+ protected abstract Constructor getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException, UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException, NotConcreteRegistrationException;
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleStrategy.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleStrategy.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleStrategy.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.defaults;
+
+/**
+ * An interface which specifies the lifecyle strategy on the component instance.
+ * Lifecycle strategies are used by component adapters to delegate the lifecyle
+ * 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 <code>true</code> if the component has a lifecycle
+ */
+ boolean hasLifecycle(Class type);
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/LifecycleVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.lang.reflect.Method;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Disposable;
+import org.picocontainer.LifecycleManager;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.Startable;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+
+
+/**
+ * A PicoVisitor for the lifecycle methods of the components.
+ *
+ * @author Aslak Hellesøy
+ * @author Jörg Schaible
+ * @since 1.1
+ * @deprecated since 1.2 in favour of {@link LifecycleManager}
+ */
+public class LifecycleVisitor extends MethodCallingVisitor {
+ private static final Method START;
+ private static final Method STOP;
+ private static final Method DISPOSE;
+ static {
+ try {
+ START = Startable.class.getMethod("start", (Class[])null);
+ STOP = Startable.class.getMethod("stop", (Class[])null);
+ DISPOSE = Disposable.class.getMethod("dispose", (Class[])null);
+ } catch (NoSuchMethodException e) {
+ // /CLOVER:OFF
+ throw new InternalError(e.getMessage());
+ // /CLOVER:ON
+ }
+ }
+
+ private final ComponentMonitor componentMonitor;
+
+ /**
+ * Construct a LifecycleVisitor.
+ *
+ * @param method the method to call
+ * @param ofType the component type
+ * @param visitInInstantiationOrder flag for the visiting order
+ * @param monitor the {@link ComponentMonitor} to use
+ * @deprecated since 1.2 in favour of {@link LifecycleManager}
+ */
+ protected LifecycleVisitor(Method method, Class ofType, boolean visitInInstantiationOrder, ComponentMonitor monitor) {
+ super(method, ofType, null, visitInInstantiationOrder);
+ if (monitor == null) {
+ throw new NullPointerException();
+ }
+ this.componentMonitor = monitor;
+ }
+
+ /**
+ * Construct a LifecycleVisitor.
+ *
+ * @param method the method to call
+ * @param ofType the component type
+ * @param visitInInstantiationOrder flag for the visiting order
+ * @deprecated since 1.2 in favour of {@link org.picocontainer.LifecycleManager}
+ */
+ public LifecycleVisitor(Method method, Class ofType, boolean visitInInstantiationOrder) {
+ this(method, ofType, visitInInstantiationOrder, new DefaultComponentMonitor());
+ }
+
+ /**
+ * Invoke the standard PicoContainer lifecycle for {@link Startable#start()}.
+ *
+ * @param node The node to start the traversal.
+ * @deprecated since 1.2 in favour of {@link org.picocontainer.LifecycleManager}
+ */
+ public static void start(Object node) {
+ new LifecycleVisitor(START, Startable.class, true).traverse(node);
+ }
+
+ /**
+ * Invoke the standard PicoContainer lifecycle for {@link Startable#stop()}.
+ *
+ * @param node The node to start the traversal.
+ * @deprecated since 1.2 in favour of {@link LifecycleManager}
+ */
+ public static void stop(Object node) {
+ new LifecycleVisitor(STOP, Startable.class, false).traverse(node);
+ }
+
+ /**
+ * Invoke the standard PicoContainer lifecycle for {@link Disposable#dispose()}.
+ *
+ * @param node The node to start the traversal.
+ * @deprecated since 1.2 in favour of {@link LifecycleManager}
+ */
+ public static void dispose(Object node) {
+ new LifecycleVisitor(DISPOSE, Disposable.class, false).traverse(node);
+ }
+
+ protected Object invoke(final Object target) {
+ final Method method = getMethod();
+ try {
+ componentMonitor.invoking(method, target);
+ final long startTime = System.currentTimeMillis();
+ super.invoke(target);
+ componentMonitor.invoked(method, target, System.currentTimeMillis() - startTime);
+ } catch (final PicoIntrospectionException e) {
+ componentMonitor.invocationFailed(method, target, (Exception)e.getCause());
+ throw e;
+ }
+ return Void.TYPE;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MapFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MapFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MapFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,44 @@
+package org.picocontainer.defaults;
+
+import java.util.Map;
+
+/**
+ * A simple factory for ordered maps: use JDK1.4's java.util.LinkedHashMap if available,
+ * or commons-collection's LinkedMap, or defaults to unordered java.util.HashMap
+ *
+ * @author Gregory Joseph
+ * @version $Revision: $
+ */
+public class MapFactory {
+ private static final String JDK14 = "java.util.LinkedHashMap";
+ private static final String COMMONS = "org.apache.commons.collections.map.LinkedMap";
+ private static final String NON_ORDERED = "java.util.HashMap";
+
+ private Class clazz;
+
+ public MapFactory() {
+ try {
+ clazz = Class.forName(JDK14);
+ } catch (ClassNotFoundException e) {
+ try {
+ clazz = Class.forName(COMMONS);
+ } catch (ClassNotFoundException e1) {
+ try {
+ clazz = Class.forName(NON_ORDERED);
+ } catch (ClassNotFoundException e2) {
+ throw new IllegalStateException("What kind of JRE is this ? No " + NON_ORDERED + " class was found.");
+ }
+ }
+ }
+ }
+
+ public Map newInstance() {
+ try {
+ return (Map) clazz.newInstance();
+ } catch (InstantiationException e) {
+ throw new RuntimeException("Could not instantiate " + clazz + " : " + e.getMessage());
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Could not instantiate " + clazz + " : " + e.getMessage());
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MethodCallingVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MethodCallingVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MethodCallingVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoIntrospectionException;
+
+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.Iterator;
+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
+ * @since 1.2
+ */
+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 <code>true</code> if components are visited in instantiation order
+ * @param arguments the arguments for the method invocation (may be <code>null</code>)
+ * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
+ * @since 1.2
+ */
+ 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 <code>null</code>)
+ * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
+ * @since 1.2
+ */
+ 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 (Iterator iterator = componentInstances.iterator(); iterator.hasNext();) {
+ invoke(iterator.next());
+ }
+ } finally {
+ componentInstances.clear();
+ }
+ return Void.TYPE;
+ }
+
+ public void visitContainer(PicoContainer pico) {
+ super.visitContainer(pico);
+ componentInstances.addAll(pico.getComponentInstancesOfType(type));
+ }
+
+ protected Method getMethod() {
+ return method;
+ }
+
+ protected Object[] getArguments() {
+ return arguments;
+ }
+
+ protected void invoke(final Object[] targets) {
+ for (int i = 0; i < targets.length; i++) {
+ invoke(targets[i]);
+ }
+ }
+
+ protected Object invoke(final Object target) {
+ final Method method = getMethod();
+ try {
+ method.invoke(target, getArguments());
+ } catch (IllegalArgumentException e) {
+ throw new PicoIntrospectionException("Can't call " + method.getName() + " on " + target, e);
+ } catch (IllegalAccessException e) {
+ throw new PicoIntrospectionException("Can't call " + method.getName() + " on " + target, e);
+ } catch (InvocationTargetException e) {
+ throw new PicoIntrospectionException("Failed when calling " + method.getName() + " on " + target, e
+ .getTargetException());
+ }
+ return Void.TYPE;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.ComponentMonitor;
+
+/**
+ * Abstract {@link ComponentAdapter ComponentAdapter} supporting a
+ * {@link ComponentMonitorStrategy ComponentMonitorStrategy}.
+ * It provides a {@link DelegatingComponentMonitor default ComponentMonitor},
+ * but does not allow to use <code>null</code> for the component monitor.
+ *
+ * @author Mauro Talevi
+ * @version $Revision: $
+ * @see ComponentAdapter
+ * @see ComponentMonitorStrategy
+ * @since 1.2
+ */
+public abstract class MonitoringComponentAdapter implements ComponentAdapter, ComponentMonitorStrategy, Serializable {
+ private ComponentMonitor componentMonitor;
+
+ /**
+ * Constructs a MonitoringComponentAdapter with a custom monitor
+ * @param monitor the component monitor used by this ComponentAdapter
+ */
+ protected MonitoringComponentAdapter(ComponentMonitor monitor) {
+ if (monitor == null){
+ throw new NullPointerException("monitor");
+ }
+ this.componentMonitor = monitor;
+ }
+
+ /**
+ * Constructs a MonitoringComponentAdapter with a {@link DelegatingComponentMonitor default monitor}.
+ */
+ protected MonitoringComponentAdapter() {
+ this(new DelegatingComponentMonitor());
+ }
+
+
+ public void changeMonitor(ComponentMonitor monitor) {
+ this.componentMonitor = monitor;
+ }
+
+ /**
+ * Returns the monitor currently used
+ * @return The ComponentMonitor currently used
+ */
+ public ComponentMonitor currentMonitor(){
+ return componentMonitor;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/MonitoringComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+
+import org.picocontainer.ComponentMonitor;
+
+/**
+ * Abstract {@link ComponentAdapterFactory ComponentAdapterFactory} supporting a
+ * {@link ComponentMonitorStrategy ComponentMonitorStrategy}.
+ * It provides a {@link DelegatingComponentMonitor default ComponentMonitor},
+ * but does not allow to use <code>null</code> for the component monitor.
+ *
+ * @author Mauro Talevi
+ * @see ComponentAdapterFactory
+ * @see ComponentMonitorStrategy
+ * @since 1.2
+ */
+public abstract class MonitoringComponentAdapterFactory implements ComponentAdapterFactory, ComponentMonitorStrategy, Serializable {
+ private ComponentMonitor componentMonitor;
+
+ /**
+ * Constructs a MonitoringComponentAdapterFactory with a custom monitor
+ * @param monitor the ComponentMonitor used by the factory
+ */
+ protected MonitoringComponentAdapterFactory(ComponentMonitor monitor) {
+ if (monitor == null){
+ throw new NullPointerException("componentMonitor");
+ }
+ this.componentMonitor = monitor;
+ }
+
+ /**
+ * Constructs a MonitoringComponentAdapterFactory with a {@link DelegatingComponentMonitor default monitor}.
+ */
+ protected MonitoringComponentAdapterFactory() {
+ this(new DelegatingComponentMonitor());
+ }
+
+ public void changeMonitor(ComponentMonitor monitor) {
+ this.componentMonitor = monitor;
+ }
+
+ /**
+ * Returns the monitor currently used
+ * @return The ComponentMonitor currently used
+ */
+ public ComponentMonitor currentMonitor(){
+ return componentMonitor;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/NotConcreteRegistrationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/NotConcreteRegistrationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/NotConcreteRegistrationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoRegistrationException;
+
+/**
+ * @author Aslak Hellesoy
+ * @version $Revision: 1.6 $
+ */
+public class NotConcreteRegistrationException extends PicoRegistrationException {
+ private final Class componentImplementation;
+
+ public NotConcreteRegistrationException(Class componentImplementation) {
+ super("Bad Access: '" + componentImplementation.getName() + "' is not instantiable");
+ this.componentImplementation = componentImplementation;
+ }
+
+ public Class getComponentImplementation() {
+ return componentImplementation;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ObjectReference.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ObjectReference.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ObjectReference.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * 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.defaults;
+
+/**
+ * A way to refer to objects that are stored in "awkward" places (for example inside a
+ * <code>HttpSession</code> or {@link ThreadLocal}).
+ * <p/>
+ * This interface is typically implemented by someone integrating Pico into an existing container.
+ *
+ * @author <a href="mailto:joe at thoughtworks.net">Joe Walnes</a>
+ */
+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.
+ */
+ Object get();
+
+ /**
+ * Assign an object to the reference.
+ *
+ * @param item the object to assign to the reference. May be <code>null</code>.
+ */
+ void set(Object item);
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoInvocationTargetInitializationException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoInvocationTargetInitializationException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoInvocationTargetInitializationException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,22 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoInitializationException;
+
+public class PicoInvocationTargetInitializationException extends PicoInitializationException {
+ public PicoInvocationTargetInitializationException(Throwable cause) {
+ super("InvocationTargetException: "
+ + cause.getClass().getName()
+ + " " + cause.getMessage()
+ , cause);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoVisitorTraversalException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoVisitorTraversalException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/PicoVisitorTraversalException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004 Joerg Schaible
+ * Created on 06.10.2004 by joehni
+ */
+package org.picocontainer.defaults;
+
+import org.picocontainer.PicoException;
+import org.picocontainer.PicoVisitor;
+
+
+/**
+ * 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
+ * @since 1.1
+ */
+public 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");
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,293 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+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;
+
+/**
+ * Instantiates components using empty constructors and
+ * <a href="http://docs.codehaus.org/display/PICO/Setter+Injection">Setter Injection</a>.
+ * For easy setting of primitive properties, also see {@link BeanPropertyComponentAdapter}.
+ * <p/>
+ * <em>
+ * Note that this class doesn't cache instances. If you want caching,
+ * use a {@link CachingComponentAdapter} around this one.
+ * </em>
+ * </p>
+ *
+ * @author Aslak Hellesøy
+ * @author Jörg Schaible
+ * @author Mauro Talevi
+ * @version $Revision: 2825 $
+ */
+public class SetterInjectionComponentAdapter extends InstantiatingComponentAdapter {
+ private transient Guard instantiationGuard;
+ private transient List setters;
+ private transient List setterNames;
+ private transient Class[] setterTypes;
+
+ /**
+ * Constructs a SetterInjectionComponentAdapter
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @param monitor the component monitor used by this adapter
+ * @param lifecycleStrategy the component lifecycle strategy used by this adapter
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public SetterInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses, monitor, lifecycleStrategy);
+ }
+
+
+ /**
+ * Constructs a SetterInjectionComponentAdapter
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @param monitor the component monitor used by this adapter
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public SetterInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses, ComponentMonitor monitor) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses, monitor);
+ }
+
+ /**
+ * Constructs a SetterInjectionComponentAdapter with a {@link DelegatingComponentMonitor} as default.
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public SetterInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ super(componentKey, componentImplementation, parameters, allowNonPublicClasses);
+ }
+
+ /**
+ * Constructs a SetterInjectionComponentAdapter with key, implementation and parameters.
+ *
+ * @param componentKey the search key for this implementation
+ * @param componentImplementation the concrete implementation
+ * @param parameters the parameters to use for the initialization
+ * @throws AssignabilityRegistrationException
+ * if the key is a type and the implementation cannot be assigned to.
+ * @throws NotConcreteRegistrationException
+ * if the implementation is not a concrete class.
+ * @throws NullPointerException if one of the parameters is <code>null</code>
+ */
+ public SetterInjectionComponentAdapter(final Object componentKey, final Class componentImplementation, Parameter[] parameters) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
+ this(componentKey, componentImplementation, parameters, false);
+ }
+
+ protected Constructor getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException, UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ final Constructor constructor = getConstructor();
+ getMatchingParameterListForSetters(container);
+ return constructor;
+ }
+
+ private Constructor getConstructor() throws PicoInvocationTargetInitializationException {
+ Object retVal = AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ return getComponentImplementation().getConstructor((Class[])null);
+ } catch (NoSuchMethodException e) {
+ return new PicoInvocationTargetInitializationException(e);
+ } catch (SecurityException e) {
+ return new PicoInvocationTargetInitializationException(e);
+ }
+ }
+ });
+ if (retVal instanceof Constructor) {
+ return (Constructor) retVal;
+ } else {
+ throw (PicoInitializationException) retVal;
+ }
+ }
+
+ private Parameter[] getMatchingParameterListForSetters(PicoContainer container) throws PicoInitializationException, UnsatisfiableDependenciesException {
+ if (setters == null) {
+ initializeSetterAndTypeLists();
+ }
+
+ final List matchingParameterList = new ArrayList(Collections.nCopies(setters.size(), null));
+ final Set nonMatchingParameterPositions = new HashSet();
+ final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(setterTypes);
+ for (int i = 0; i < currentParameters.length; i++) {
+ final Parameter parameter = currentParameters[i];
+ boolean failedDependency = true;
+ for (int j = 0; j < setterTypes.length; j++) {
+ if (matchingParameterList.get(j) == null && parameter.isResolvable(container, this, setterTypes[j])) {
+ matchingParameterList.set(j, parameter);
+ failedDependency = false;
+ break;
+ }
+ }
+ if (failedDependency) {
+ nonMatchingParameterPositions.add(new Integer(i));
+ }
+ }
+
+ final Set unsatisfiableDependencyTypes = new HashSet();
+ for (int i = 0; i < matchingParameterList.size(); i++) {
+ if (matchingParameterList.get(i) == null) {
+ unsatisfiableDependencyTypes.add(setterTypes[i]);
+ }
+ }
+ if (unsatisfiableDependencyTypes.size() > 0) {
+ throw new UnsatisfiableDependenciesException(this, unsatisfiableDependencyTypes, container);
+ } else if (nonMatchingParameterPositions.size() > 0) {
+ throw new PicoInitializationException("Following parameters do not match any of the setters for " + getComponentImplementation() + ": " + nonMatchingParameterPositions.toString());
+ }
+ return (Parameter[]) matchingParameterList.toArray(new Parameter[matchingParameterList.size()]);
+ }
+
+ public Object getComponentInstance(final PicoContainer container) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ final Constructor constructor = getConstructor();
+ if (instantiationGuard == null) {
+ instantiationGuard = new Guard() {
+ public Object run() {
+ final Parameter[] matchingParameters = getMatchingParameterListForSetters(guardedContainer);
+ ComponentMonitor componentMonitor = currentMonitor();
+ Object componentInstance;
+ try {
+ long startTime = System.currentTimeMillis();
+ componentMonitor.instantiating(constructor);
+ componentInstance = newInstance(constructor, null);
+ componentMonitor.instantiated(constructor, System.currentTimeMillis() - startTime);
+ } catch (InvocationTargetException e) {
+ componentMonitor.instantiationFailed(constructor, e);
+ if (e.getTargetException() instanceof RuntimeException) {
+ throw (RuntimeException) e.getTargetException();
+ } else if (e.getTargetException() instanceof Error) {
+ throw (Error) e.getTargetException();
+ }
+ throw new PicoInvocationTargetInitializationException(e.getTargetException());
+ } catch (InstantiationException e) {
+ // can't get here because checkConcrete() will catch it earlier, but see PICO-191
+ ///CLOVER:OFF
+ componentMonitor.instantiationFailed(constructor, e);
+ throw new PicoInitializationException("Should never get here");
+ ///CLOVER:ON
+ } catch (IllegalAccessException e) {
+ // can't get here because either filtered or access mode set
+ ///CLOVER:OFF
+ componentMonitor.instantiationFailed(constructor, e);
+ throw new PicoInitializationException(e);
+ ///CLOVER:ON
+ }
+ Method setter = null;
+ try {
+ for (int i = 0; i < setters.size(); i++) {
+ setter = (Method) setters.get(i);
+ componentMonitor.invoking(setter, componentInstance);
+ long startTime = System.currentTimeMillis();
+ setter.invoke(componentInstance, new Object[]{matchingParameters[i].resolveInstance(guardedContainer, SetterInjectionComponentAdapter.this, setterTypes[i])});
+ componentMonitor.invoked(setter, componentInstance, System.currentTimeMillis() - startTime);
+ }
+ return componentInstance;
+ } catch (InvocationTargetException e) {
+ componentMonitor.invocationFailed(setter, componentInstance, e);
+ if (e.getTargetException() instanceof RuntimeException) {
+ throw (RuntimeException) e.getTargetException();
+ } else if (e.getTargetException() instanceof Error) {
+ throw (Error) e.getTargetException();
+ }
+ throw new PicoInvocationTargetInitializationException(e.getTargetException());
+ } catch (IllegalAccessException e) {
+ componentMonitor.invocationFailed(setter, componentInstance, e);
+ throw new PicoInvocationTargetInitializationException(e);
+ }
+ }
+ };
+ }
+ instantiationGuard.setArguments(container);
+ return instantiationGuard.observe(getComponentImplementation());
+ }
+
+ public void verify(final PicoContainer container) throws PicoIntrospectionException {
+ if (verifyingGuard == null) {
+ verifyingGuard = new Guard() {
+ public Object run() {
+ final Parameter[] currentParameters = getMatchingParameterListForSetters(guardedContainer);
+ for (int i = 0; i < currentParameters.length; i++) {
+ currentParameters[i].verify(container, SetterInjectionComponentAdapter.this, setterTypes[i]);
+ }
+ return null;
+ }
+ };
+ }
+ verifyingGuard.setArguments(container);
+ verifyingGuard.observe(getComponentImplementation());
+ }
+
+ private void initializeSetterAndTypeLists() {
+ setters = new ArrayList();
+ setterNames = new ArrayList();
+ final List typeList = new ArrayList();
+ final Method[] methods = getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ final Method method = methods[i];
+ final Class[] parameterTypes = method.getParameterTypes();
+ // We're only interested if there is only one parameter and the method name is bean-style.
+ if (parameterTypes.length == 1) {
+ String methodName = method.getName();
+ boolean isBeanStyle = methodName.length() >= 4 && methodName.startsWith("set") && Character.isUpperCase(methodName.charAt(3));
+ if (isBeanStyle) {
+ String attribute = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
+ setters.add(method);
+ setterNames.add(attribute);
+ typeList.add(parameterTypes[0]);
+ }
+ }
+ }
+ setterTypes = (Class[]) typeList.toArray(new Class[0]);
+ }
+
+ private Method[] getMethods() {
+ return (Method[]) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return getComponentImplementation().getMethods();
+ }
+ });
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SetterInjectionComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.monitors.DefaultComponentMonitor;
+
+
+/**
+ * A {@link ComponentAdapterFactory} for JavaBeans.
+ * The factory creates {@link SetterInjectionComponentAdapter}.
+ *
+ * @author Jörg Schaible
+ * @version $Revision: 2768 $
+ */
+public class SetterInjectionComponentAdapterFactory extends MonitoringComponentAdapterFactory {
+ private final boolean allowNonPublicClasses;
+ private LifecycleStrategy lifecycleStrategy;
+
+ public SetterInjectionComponentAdapterFactory(boolean allowNonPublicClasses,
+ LifecycleStrategy lifecycleStrategy) {
+ this.allowNonPublicClasses = allowNonPublicClasses;
+ this.lifecycleStrategy = lifecycleStrategy;
+ }
+
+ public SetterInjectionComponentAdapterFactory(boolean allowNonPublicClasses) {
+ this(allowNonPublicClasses, new DefaultLifecycleStrategy(new DefaultComponentMonitor()));
+ }
+
+ public SetterInjectionComponentAdapterFactory() {
+ this(false);
+ }
+
+ /**
+ * Create a {@link SetterInjectionComponentAdapter}.
+ *
+ * @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 SetterInjectionComponentAdapter}.
+ * @throws PicoIntrospectionException if dependencies cannot be solved
+ * @throws AssignabilityRegistrationException
+ * if the <code>componentKey</code> is a type
+ * that does not match the implementation
+ * @throws NotConcreteRegistrationException
+ * if the implementation is an interface or an
+ * abstract class.
+ */
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters)
+ throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
+ return new SetterInjectionComponentAdapter(componentKey, componentImplementation, parameters,
+ allowNonPublicClasses, currentMonitor(), lifecycleStrategy);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SimpleReference.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SimpleReference.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SimpleReference.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import java.io.Serializable;
+
+/**
+ * @author Aslak Hellesøy
+ * @version $Revision: 940 $
+ */
+public class SimpleReference implements ObjectReference, Serializable {
+ private Object instance;
+
+ public Object get() {
+ return instance;
+ }
+
+ public void set(Object item) {
+ this.instance = item;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapter.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapter.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapter.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * 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.defaults;
+
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoInitializationException;
+import org.picocontainer.PicoIntrospectionException;
+
+/**
+ * @author Aslak Hellesøy
+ * @author Manish Shah
+ * @version $Revision: 1600 $
+ */
+public class SynchronizedComponentAdapter extends DecoratingComponentAdapter {
+ public SynchronizedComponentAdapter(ComponentAdapter delegate) {
+ super(delegate);
+ }
+
+ public synchronized Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException {
+ return super.getComponentInstance(container);
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapterFactory.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapterFactory.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/SynchronizedComponentAdapterFactory.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+
+/**
+ * @author Aslak Hellesøy
+ * @version $Revision: 1272 $
+ */
+public class SynchronizedComponentAdapterFactory extends DecoratingComponentAdapterFactory {
+ public SynchronizedComponentAdapterFactory(ComponentAdapterFactory delegate) {
+ super(delegate);
+ }
+
+ public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters) {
+ return new SynchronizedComponentAdapter(super.createComponentAdapter(componentKey, componentImplementation, parameters));
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ThreadLocalCyclicDependencyGuard.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ThreadLocalCyclicDependencyGuard.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/ThreadLocalCyclicDependencyGuard.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * 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 Joerg Schaible *
+ *****************************************************************************/
+
+package org.picocontainer.defaults;
+
+/**
+ * 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 <code>Boolean.FALSE</code>.
+ *
+ * @author Jörg Schaible
+ * @since 1.1
+ */
+public abstract class ThreadLocalCyclicDependencyGuard extends ThreadLocal implements CyclicDependencyGuard {
+
+ protected Object initialValue() {
+ return Boolean.FALSE;
+ }
+
+ /**
+ * 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 <code>null</code>
+ */
+ public abstract Object run();
+
+ /**
+ * Call the observing function. The provided guard will hold the {@link Boolean} value.
+ * If the guard is already <code>Boolean.TRUE</code> a {@link CyclicDependencyException}
+ * will be thrown.
+ *
+ * @param stackFrame the current stack frame
+ * @return the result of the <code>run</code> method
+ */
+ public final Object observe(Class stackFrame) {
+ if (Boolean.TRUE.equals(get())) {
+ throw new CyclicDependencyException(stackFrame);
+ }
+ Object result = null;
+ try {
+ set(Boolean.TRUE);
+ result = run();
+ } catch (final CyclicDependencyException e) {
+ e.push(stackFrame);
+ throw e;
+ } finally {
+ set(Boolean.FALSE);
+ }
+ return result;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TooManySatisfiableConstructorsException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TooManySatisfiableConstructorsException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TooManySatisfiableConstructorsException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.PicoIntrospectionException;
+
+import java.util.Collection;
+
+public class TooManySatisfiableConstructorsException extends PicoIntrospectionException {
+
+ private Class forClass;
+ private Collection constructors;
+
+ public TooManySatisfiableConstructorsException(Class forClass, Collection constructors) {
+ super( "Too many satisfiable constructors:" + constructors.toString());
+ this.forClass = forClass;
+ this.constructors = constructors;
+ }
+
+ public Class getForImplementationClass() {
+ return forClass;
+ }
+
+ public Collection getConstructors() {
+ return constructors;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TraversalCheckingVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TraversalCheckingVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/TraversalCheckingVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+
+
+/**
+ * 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:
+ *
+ *<pre>
+ * PicoContainer container = new DefaultPicoContainer();
+ * PicoContainer child = container.makeChildContainer();
+ *
+ * final List allContainers = new ArrayList();
+ *
+ * PicoVisitor visitor = new TraversalCheckingVisitor() {
+ * public void visitContainer(PicoContainer pico) {
+ * super.visitContainer(pico); //Calls checkTraversal for us.
+ * allContainers.add(pico);
+ * }
+ * }
+ * </pre>
+ *
+ * @author Micheal Rimov
+ * @since 1.2
+ */
+public class TraversalCheckingVisitor
+ extends AbstractPicoVisitor {
+
+ public void visitContainer(PicoContainer pico) {
+ checkTraversal();
+ }
+
+ public void visitComponentAdapter(ComponentAdapter componentAdapter) {
+ checkTraversal();
+ }
+
+ public void visitParameter(Parameter parameter) {
+ checkTraversal();
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/UnsatisfiableDependenciesException.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/UnsatisfiableDependenciesException.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/UnsatisfiableDependenciesException.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.PicoIntrospectionException;
+import org.picocontainer.PicoContainer;
+
+import java.util.Set;
+
+/**
+ * Exception thrown when some of the component's dependencies are not satisfiable.
+ *
+ * @author Aslak Hellesøy
+ * @author Mauro Talevi
+ * @version $Revision: 2838 $
+ */
+public class UnsatisfiableDependenciesException extends PicoIntrospectionException {
+
+ private final ComponentAdapter instantiatingComponentAdapter;
+ private final Set unsatisfiableDependencies;
+ private final Class unsatisfiedDependencyType;
+ private final PicoContainer leafContainer;
+
+ public UnsatisfiableDependenciesException(ComponentAdapter instantiatingComponentAdapter,
+ Set unsatisfiableDependencies, PicoContainer leafContainer) {
+ super(instantiatingComponentAdapter.getComponentImplementation().getName() + " has unsatisfiable dependencies: "
+ + unsatisfiableDependencies + " where " + leafContainer
+ + " was the leaf container being asked for dependencies.");
+ this.instantiatingComponentAdapter = instantiatingComponentAdapter;
+ this.unsatisfiableDependencies = unsatisfiableDependencies;
+ this.unsatisfiedDependencyType = null;
+ this.leafContainer = leafContainer;
+ }
+
+ public UnsatisfiableDependenciesException(ComponentAdapter instantiatingComponentAdapter,
+ Class unsatisfiedDependencyType, Set unsatisfiableDependencies,
+ PicoContainer leafContainer) {
+ super(instantiatingComponentAdapter.getComponentImplementation().getName() + " has unsatisfied dependency: " + unsatisfiedDependencyType
+ +" among unsatisfiable dependencies: "+unsatisfiableDependencies + " where " + leafContainer
+ + " was the leaf container being asked for dependencies.");
+ this.instantiatingComponentAdapter = instantiatingComponentAdapter;
+ this.unsatisfiableDependencies = unsatisfiableDependencies;
+ this.unsatisfiedDependencyType = unsatisfiedDependencyType;
+ this.leafContainer = leafContainer;
+ }
+
+ public ComponentAdapter getUnsatisfiableComponentAdapter() {
+ return instantiatingComponentAdapter;
+ }
+
+ public Set getUnsatisfiableDependencies() {
+ return unsatisfiableDependencies;
+ }
+
+ public Class getUnsatisfiedDependencyType() {
+ return unsatisfiedDependencyType;
+ }
+
+ public PicoContainer getLeafContainer() {
+ return leafContainer;
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/VerifyingVisitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/VerifyingVisitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/VerifyingVisitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * 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.defaults;
+
+import org.picocontainer.ComponentAdapter;
+import org.picocontainer.Parameter;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.PicoVerificationException;
+import org.picocontainer.PicoVisitor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * Visitor to verify {@link PicoContainer} instances. The visitor walks down the logical container hierarchy.
+ *
+ * @author Jörg Schaible
+ * @since 1.1
+ */
+public class VerifyingVisitor extends TraversalCheckingVisitor {
+
+ private final List nestedVerificationExceptions;
+ private final Set verifiedComponentAdapters;
+ private final PicoVisitor componentAdapterCollector;
+ private PicoContainer currentPico;
+
+ /**
+ * Construct a VerifyingVisitor.
+ */
+ public VerifyingVisitor() {
+ nestedVerificationExceptions = new ArrayList();
+ verifiedComponentAdapters = 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 void visitContainer(PicoContainer pico) {
+ super.visitContainer(pico);
+ currentPico = pico;
+ }
+
+ 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);
+ }
+ }
+
+ private class ComponentAdapterCollector implements PicoVisitor {
+ // /CLOVER:OFF
+ public Object traverse(Object node) {
+ return null;
+ }
+
+ public void visitContainer(PicoContainer pico) {
+ }
+
+ // /CLOVER:ON
+
+ public void visitComponentAdapter(ComponentAdapter componentAdapter) {
+ verifiedComponentAdapters.add(componentAdapter);
+ }
+
+ public void visitParameter(Parameter parameter) {
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/package.html
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/package.html (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/defaults/package.html 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+</head>
+<body>
+<p>This package contains the default implementation of the {@link org.picocontainer.PicoContainer}
+API. The main class in this package is {@link org.picocontainer.defaults.DefaultPicoContainer},
+which satisfies both the {@link org.picocontainer.PicoContainer} and
+{@link org.picocontainer.MutablePicoContainer} contracts. In addition, it allows passing in of a
+{@link org.picocontainer.defaults.ComponentAdapterFactory}, which can be used to customize the type
+of {@link org.picocontainer.ComponentAdapter} that is used for components that are added to the
+container for which no component adapter is specified explicitly.</p>
+
+<p>This page contains a brief low-level overview of the default picocontainer implementation
+package. Much more documentation is available on the
+<a href="http://www.picocontainer.org/">PicoContainer website</a>.</p>
+
+<h3>Buzzwords</h3>
+
+<p>The implementation provided in this package is very extensible, embeddable and lightweight, to
+get a few buzzwords out of the way.</p>
+
+<ul>
+<li><strong>extensible</strong>. A popular way to extend the container is to not really extend
+it at all, but rather to feed the <code>DefaultPicoContainer</code> a custom-written component
+adapter factory, for example one that creates adapters that support a different kind of IoC. For
+really advanced applications you may wish to subclass <code>DefaultPicoContainer</code>.</li>
+<li><strong>embeddable</strong>. This implementation has no external dependencies aside from the
+java class libraries, is written in 100% pure java, and requires next to no set up to use. Good
+examples of how the default picocontainer package can be embedded in an application can be found
+in the <a href="http://www.nanocontainer.org/">nanocontainer project</a>.</li>
+<li><strong>lightweight</strong>. The base PicoContainer package supports various ways to do
+<a href="http://www.martinfowler.com/articles/injection.html">dependency injection</a> (including
+{@link org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory constructor
+injection},
+which is used by default, and
+{@link org.picocontainer.defaults.SetterInjectionComponentAdapterFactory setter
+injection}), nothing more. With about 3 dozen classes, the picocontainer jar file (including the
+PicoContainer API) is under a 100kb in size, small enough to use in just about any project.</li>
+</ul>
+
+<h3>Notes on Exceptions</h3>
+
+<p>Almost all exceptions thrown in this package are subclasses of
+{@link org.picocontainer.PicoException}, which is a subclass of {@link java.lang.RuntimeException}.
+Furthermore, those exceptions are usually be subclasses of the basic pico exception types specified
+in the API. As an example, {@link org.picocontainer.defaults.CyclicDependencyException} is a
+specialization of {@link org.picocontainer.PicoInitializationException}.</p>
+
+<p>It is not recommended that you catch the specific exceptions thrown in this package (except
+perhaps if you're developing your own container based on this package). Rather catch the broader
+exception classes defined as part of the core PicoContainer API, and minimize the ties your
+application has to the implementation package.</p>
+
+<h3>Notes on ComponentAdapters and ComponentAdapterFactories</h3>
+
+<p>Most of the {@link org.picocontainer.ComponentAdapter} implementations in this package are
+subclasses of either {@link org.picocontainer.defaults.AbstractComponentAdapter} or
+{@link org.picocontainer.defaults.DecoratingComponentAdapter}. Subclasses of the former can
+generally be used on their own, whereas subclasses of the latter wrap another ComponentAdapter,
+providing slightly different behaviour or additional functionality. For example,
+{@link org.picocontainer.defaults.CachingComponentAdapter} extends
+<code>DecoratingComponentAdapter</code>. It can wrap any other adapter to
+provide a singleton-like behaviour (where a single component instance is kept per container).
+Contrast this with {@link org.picocontainer.defaults.ConstructorInjectionComponentAdapter} (a
+subclass of <code>AbstractComponentAdapter</code>), which actually creates instances (using, in
+this case, constructor dependency injection).</p>
+
+<p>All component adapters in this package include a matching <code>ComponentAdapterFactory</code>.
+The classnames of those factories can always be found simply by appending "Factory" to the name of
+the component adapter class. One adapter factory deserves special mention: {@link
+org.picocontainer.defaults.DefaultComponentAdapterFactory} is the factory that is used by
+{@link org.picocontainer.defaults.DefaultPicoContainer} if none is explicitly specified.</p>
+
+<p>It is recommended that you follow similar patterns if you write your own component adapters.
+If you are not sure what type of adapter you need, it is often a good idea to start with a
+decorating component adapter, so that you can mix and match functionality from the existing
+adapters with your own. Also, always try to include a <code>ComponentAdapterFactory</code> for your
+custom adapter.</p>
+
+<h3>Notes on Parameters</h3>
+
+<p>Advanced PicoContainer users may need to have full control over what parameters are fed to
+components on instantiation, and the PicoContainer API provides this control via the
+{@link org.picocontainer.Parameter} class. The default implementation provides two commonly used
+parameter implementations: {@link org.picocontainer.defaults.ConstantParameter} for passing
+"constants" (like primitive types and strings) to components and
+{@link org.picocontainer.defaults.ConstantParameter} for passing a specific argument to the
+component by specifying the key that should be used in retrieving that argument from the
+container.</p>
+
+</body>
+</html>
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/AbstractComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/AbstractComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/AbstractComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * 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 org.picocontainer.ComponentMonitor;
+
+/**
+ * An abstract {@link ComponentMonitor} which supports all the message formats.
+ *
+ * @author Mauro Talevi
+ * @version $Revision: $
+ */
+public abstract class AbstractComponentMonitor implements ComponentMonitor {
+
+ public final static String INSTANTIATING = "PicoContainer: instantiating {0}";
+ public final static String INSTANTIATED = "PicoContainer: instantiated {0} [{1} ms]";
+ 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 static String format(String template, Object[] arguments) {
+ return MessageFormat.format(template, arguments);
+ }
+
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/ConsoleComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/ConsoleComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/ConsoleComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * 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.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.picocontainer.ComponentMonitor;
+
+/**
+ * A {@link ComponentMonitor} which writes to a {@link OutputStream}.
+ * This is typically used to write to a console.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Mauro Talevi
+ * @version $Revision: 2782 $
+ */
+public class ConsoleComponentMonitor extends AbstractComponentMonitor {
+
+ private PrintStream out;
+ private final ComponentMonitor delegate;
+
+ public ConsoleComponentMonitor(OutputStream out) {
+ this.out = new PrintStream(out);
+ delegate = new DefaultComponentMonitor();
+ }
+
+ public ConsoleComponentMonitor(OutputStream out, ComponentMonitor delegate) {
+ this.out = new PrintStream(out);
+ this.delegate = new DefaultComponentMonitor();
+ }
+
+ public void instantiating(Constructor constructor) {
+ out.println(format(INSTANTIATING, new Object[]{constructor}));
+ delegate.instantiating(constructor);
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ out.println(format(INSTANTIATED, new Object[]{constructor, new Long(duration)}));
+ delegate.instantiated(constructor, duration);
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception cause) {
+ out.println(format(INSTANTIATION_FAILED, new Object[]{constructor, cause.getMessage()}));
+ delegate.instantiationFailed(constructor, cause);
+ }
+
+ public void invoking(Method method, Object instance) {
+ out.println(format(INVOKING, new Object[]{method, instance}));
+ delegate.invoking(method, instance);
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ out.println(format(INVOKED, new Object[]{method, instance, new Long(duration)}));
+ delegate.invoked(method, instance, duration);
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception cause) {
+ out.println(format(INVOCATION_FAILED, new Object[]{method, instance, cause.getMessage()}));
+ delegate.invocationFailed(method, instance, cause);
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ out.println(format(LIFECYCLE_INVOCATION_FAILED, new Object[]{method, instance, cause.getMessage()}));
+ delegate.lifecycleInvocationFailed(method, instance, cause);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/DefaultComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/DefaultComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/DefaultComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * 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 org.picocontainer.ComponentMonitor;
+import org.picocontainer.PicoLifecycleException;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.io.Serializable;
+
+public class DefaultComponentMonitor implements ComponentMonitor, Serializable {
+
+ private static DefaultComponentMonitor instance;
+
+ public void instantiating(Constructor constructor) {
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception e) {
+ }
+
+ public void invoking(Method method, Object instance) {
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception e) {
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ throw new PicoLifecycleException(method, instance, cause);
+ }
+
+ public static synchronized DefaultComponentMonitor getInstance() {
+ if (instance == null) {
+ instance = new DefaultComponentMonitor();
+ }
+ return instance;
+ }
+
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/LifecycleComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/LifecycleComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/LifecycleComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,95 @@
+package org.picocontainer.monitors;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.picocontainer.ComponentMonitor;
+import org.picocontainer.PicoException;
+
+/**
+ * A {@link ComponentMonitor} which collects lifecycle failures
+ * and rethrows them on demand after the failures.
+ *
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class LifecycleComponentMonitor implements ComponentMonitor {
+
+ private final ComponentMonitor delegate;
+ private final List lifecycleFailures = new ArrayList();
+
+ public LifecycleComponentMonitor(ComponentMonitor delegate) {
+ this.delegate = delegate;
+ }
+
+ public LifecycleComponentMonitor() {
+ delegate = new NullComponentMonitor();
+ }
+
+ public void instantiating(Constructor constructor) {
+ delegate.instantiating(constructor);
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ delegate.instantiated(constructor, duration);
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception cause) {
+ delegate.instantiationFailed(constructor, cause);
+ }
+
+ public void invoking(Method method, Object instance) {
+ delegate.invoking(method, instance);
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ delegate.invoked(method, instance, duration);
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception cause) {
+ delegate.invocationFailed(method, instance, cause);
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ lifecycleFailures.add(cause);
+ delegate.lifecycleInvocationFailed(method, instance, cause);
+ }
+
+
+ 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 class LifecycleFailuresException extends PicoException {
+
+ private List lifecycleFailures;
+
+ public LifecycleFailuresException(List lifecycleFailures) {
+ this.lifecycleFailures = lifecycleFailures;
+ }
+
+ public String getMessage() {
+ StringBuffer message = new StringBuffer();
+ for ( Iterator i = lifecycleFailures.iterator(); i.hasNext(); ) {
+ Exception failure = (Exception) i.next();
+ message.append(failure.getMessage()).append("; ");
+ }
+ return message.toString();
+ }
+
+ public Collection getFailures() {
+ return lifecycleFailures;
+ }
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/NullComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/NullComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/NullComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * 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.Method;
+
+import org.picocontainer.ComponentMonitor;
+
+/**
+ * A {@link ComponentMonitor} which does nothing.
+ *
+ * @author Paul Hammant
+ * @author Obie Fernandez
+ * @version $Revision: 2782 $
+ */
+public class NullComponentMonitor implements ComponentMonitor, Serializable {
+
+ private static NullComponentMonitor instance;
+
+ public void instantiating(Constructor constructor) {
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception e) {
+ }
+
+ public void invoking(Method method, Object instance) {
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception e) {
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ }
+
+ public static synchronized NullComponentMonitor getInstance() {
+ if (instance == null) {
+ instance = new NullComponentMonitor();
+ }
+ return instance;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/WriterComponentMonitor.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/WriterComponentMonitor.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/monitors/WriterComponentMonitor.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * 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.io.PrintWriter;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.picocontainer.ComponentMonitor;
+
+/**
+ * A {@link ComponentMonitor} which writes to a {@link Writer}.
+ *
+ * @author Paul Hammant
+ * @author Aslak Hellesøy
+ * @author Mauro Talevi
+ * @version $Revision: 1882 $
+ */
+public class WriterComponentMonitor extends AbstractComponentMonitor {
+
+ private PrintWriter out;
+ private final ComponentMonitor delegate;
+
+ public WriterComponentMonitor(Writer out) {
+ this.out = new PrintWriter(out);
+ delegate = new DefaultComponentMonitor();
+ }
+
+ public WriterComponentMonitor(Writer out, ComponentMonitor delegate) {
+ this.out = new PrintWriter(out);
+ this.delegate = delegate;
+ }
+
+ public void instantiating(Constructor constructor) {
+ out.println(format(INSTANTIATING, new Object[]{constructor}));
+ delegate.instantiating(constructor);
+ }
+
+ public void instantiated(Constructor constructor, long duration) {
+ out.println(format(INSTANTIATED, new Object[]{constructor, new Long(duration)}));
+ delegate.instantiated(constructor, duration);
+ }
+
+ public void instantiationFailed(Constructor constructor, Exception cause) {
+ out.println(format(INSTANTIATION_FAILED, new Object[]{constructor, cause.getMessage()}));
+ delegate.instantiationFailed(constructor, cause);
+ }
+
+ public void invoking(Method method, Object instance) {
+ out.println(format(INVOKING, new Object[]{method, instance}));
+ delegate.invoking(method, instance);
+ }
+
+ public void invoked(Method method, Object instance, long duration) {
+ out.println(format(INVOKED, new Object[]{method, instance, new Long(duration)}));
+ delegate.invoked(method, instance, duration);
+ }
+
+ public void invocationFailed(Method method, Object instance, Exception cause) {
+ out.println(format(INVOCATION_FAILED, new Object[]{method, instance, cause.getMessage()}));
+ delegate.invocationFailed(method, instance, cause);
+ }
+
+ public void lifecycleInvocationFailed(Method method, Object instance, RuntimeException cause) {
+ out.println(format(LIFECYCLE_INVOCATION_FAILED, new Object[]{method, instance, cause.getMessage()}));
+ delegate.lifecycleInvocationFailed(method, instance, cause);
+ }
+
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/package.html
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/package.html (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/main/java/org/picocontainer/package.html 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+</head>
+<body>
+<p>
+This package contains the core API for PicoContainer, a compact container for working with the
+<a href="http://www.martinfowler.com/articles/injection.html">dependency injection</a> pattern.
+</p>
+<p>
+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).
+</p>
+<p>
+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.defaults.DefaultPicoContainer} class.
+</p>
+
+<p>An extensive user guide,
+a list of Frequently Asked Questions (FAQ) with answers and a lot more information is available from the
+<a href="http://www.picocontainer.org/">PicoContainer</a> website. You can also find various extensions, wrappers
+and utility libraries that are based on this core API there.</p>
+</body>
+</html>
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/KernelInstanceRefTest.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/KernelInstanceRefTest.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/KernelInstanceRefTest.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,166 @@
+package org.jboss.kernel.test;
+
+import org.jboss.kernel.plugins.bootstrap.basic.BasicBootstrap;
+import org.jboss.kernel.plugins.dependency.AbstractKernelControllerContext;
+import org.jboss.kernel.plugins.dependency.ScopeHierarchyBuilder;
+import org.jboss.kernel.plugins.dependency.AbstractKernelController;
+import org.jboss.kernel.spi.dependency.KernelController;
+import org.jboss.kernel.test.util.Singleton;
+import org.jboss.kernel.test.util.ChildSingleton;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.plugins.AbstractController;
+import org.jboss.metadata.spi.scope.ScopeKey;
+import org.jboss.metadata.spi.scope.CommonLevels;
+import org.jboss.metadata.plugins.scope.ApplicationScope;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+/**
+ * @author Marko Strukelj <mstrukel at redhat.com>
+ */
+public class KernelInstanceRefTest {
+
+ public AbstractKernelController initKernel() {
+ BasicBootstrap bootstrap = new BasicBootstrap();
+ bootstrap.run();
+ return (AbstractKernelController) bootstrap.getKernel().getController();
+ }
+
+ public void testMultiKernels() {
+ BasicBootstrap bootstrap = new BasicBootstrap();
+ bootstrap.run();
+
+ System.out.println("kernel 1: " + bootstrap.getKernel());
+ System.out.println(" controller: " + bootstrap.getKernel().getController());
+
+ BasicBootstrap bootstrap2 = new BasicBootstrap();
+ bootstrap2.run();
+
+ System.out.println("kernel 2: " + bootstrap2.getKernel());
+ System.out.println(" controller: " + bootstrap2.getKernel().getController());
+
+
+
+ }
+
+ public void testKernel() throws Throwable {
+ KernelController controller = initKernel();
+ System.out.println("Got kernel: " + controller.getKernel());
+
+ //BeanInfo binfo = new AbstractBeanInfo();
+ BeanMetaDataBuilder bmf = BeanMetaDataBuilder.createBuilder("singleton", Singleton.class.getName());
+ BeanMetaData bmeta = bmf.getBeanMetaData();
+
+ AbstractKernelControllerContext ctx = new AbstractKernelControllerContext(null, bmeta, new Singleton());
+ controller.install(ctx);
+
+ // let's do a lookup
+ ControllerContext entry = controller.getInstalledContext("singleton");
+ System.out.println("Got entry: " + entry);
+ if (entry != null)
+ System.out.println(" target: " + entry.getTarget());
+ }
+
+ public void testHierarchy() throws Throwable {
+
+ AbstractKernelController controller = initKernel();
+ System.out.println("Got kernel: " + controller.getKernel());
+
+ // create child context 1
+ AbstractController childController1 = ScopeHierarchyBuilder.buildControllerHierarchy(controller,
+ controller.getKernel().getMetaDataRepository().getMetaDataRepository(),
+ new ScopeKey(CommonLevels.APPLICATION, "child1"));
+
+ AbstractController childController2 = ScopeHierarchyBuilder.buildControllerHierarchy(controller,
+ controller.getKernel().getMetaDataRepository().getMetaDataRepository(),
+ new ScopeKey(CommonLevels.APPLICATION, "child2"));
+
+ // Register Singleton in parent controller
+ BeanMetaDataBuilder bmf = BeanMetaDataBuilder.createBuilder("singleton", Singleton.class.getName());
+ BeanMetaData bmeta = bmf.getBeanMetaData();
+ AbstractKernelControllerContext ctx = new AbstractKernelControllerContext(null, bmeta, new Singleton());
+ controller.install(ctx);
+
+ // let's do a lookup
+ doTestParentChild(controller, childController1, "singleton");
+
+ // Register ChildSingleton in child1
+ registerWithChild(childController1, "child1", "childSingleton");
+
+ // let's do a lookup
+ doTestParentChild(controller, childController1, "childSingleton");
+ doTestParentChild(controller, childController2, "childSingleton");
+
+ // Register ChildSingleton in child2
+ registerWithChild(childController2, "child2", "childSingleton");
+
+ // let's do a lookup
+ doTestParentChild(controller, childController1, "childSingleton");
+ doTestParentChild(controller, childController2, "childSingleton");
+
+ // register some additional children
+ registerWithChild(childController2, "child2", "childSingleton2");
+ registerWithChild(childController2, "child2", "childSingleton3");
+ registerWithChild(childController2, "child2", "childSingleton4");
+
+ // now let's list the components:
+ listRegisteredComponents(controller);
+ listRegisteredComponents(childController1);
+ listRegisteredComponents(childController2);
+
+ }
+
+ private void listRegisteredComponents(AbstractController controller) {
+ System.out.println("Listing components for controller: " + controller);
+ Set<ControllerContext> components = controller.getContextsByState(ControllerState.INSTALLED);
+ for (ControllerContext cc: components) {
+ System.out.println(" - " + cc);
+ System.out.println(" target: " + cc.getTarget());
+ }
+ }
+
+ private void registerWithChild(AbstractController childController, String controllerId, String componentName) throws Throwable {
+ BeanMetaDataBuilder bmf;
+ BeanMetaData bmeta;
+ AbstractKernelControllerContext ctx;
+ bmf = BeanMetaDataBuilder.createBuilder(componentName, ChildSingleton.class.getName());
+
+ // This works but only if you make no typos - it's not type-safe
+ //bmf.addAnnotation("@org.jboss.metadata.plugins.scope.ApplicationScope(\"child1\")");
+
+ // This works as well, and is also type-safe
+ bmf.addAnnotation(newAppScopeInstance(controllerId));
+
+ bmeta = bmf.getBeanMetaData();
+ ctx = new AbstractKernelControllerContext(null, bmeta, new ChildSingleton());
+ childController.install(ctx);
+ }
+
+ private void doTestParentChild(AbstractKernelController controller, AbstractController childController, String name) {
+ System.out.println("Fetching " + name);
+ ControllerContext entry = controller.getInstalledContext(name);
+ System.out.println(" Got entry from parent: " + entry);
+ if (entry != null)
+ System.out.println(" target: " + entry.getTarget());
+
+ entry = childController.getInstalledContext(name);
+ System.out.println(" Got entry from child: " + entry);
+ if (entry != null)
+ System.out.println(" target: " + entry.getTarget());
+ }
+
+ private Annotation newAppScopeInstance(final String value) {
+ return new ApplicationScope() {
+ public String value() {
+ return value;
+ }
+ public Class<? extends Annotation> annotationType() {
+ return ApplicationScope.class;
+ }
+ };
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/ChildSingleton.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/ChildSingleton.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/ChildSingleton.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,25 @@
+package org.jboss.kernel.test.util;
+
+import org.jboss.metadata.plugins.scope.ApplicationScope;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author <a href="mailto:mstrukel at redhat.com">Marko Strukelj</a>
+ */
+public class ChildSingleton
+{
+ private static AtomicInteger counter = new AtomicInteger();
+
+ private int id;
+
+ public ChildSingleton()
+ {
+ id = counter.addAndGet(1);
+ System.out.println("ChildSingleton instanciated: " + this);
+ }
+
+ public String toString() {
+ return super.toString() + " id: " + id;
+ }
+}
Added: projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/Singleton.java
===================================================================
--- projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/Singleton.java (rev 0)
+++ projects/microcontainer/branches/gatein_mc_pico/picocontainer-mc/src/test/java/org/jboss/kernel/test/util/Singleton.java 2009-09-24 14:08:11 UTC (rev 93992)
@@ -0,0 +1,16 @@
+package org.jboss.kernel.test.util;
+
+import org.jboss.metadata.plugins.scope.ApplicationScope;
+
+/**
+ * @author <a href="mailto:mstrukel at redhat.com">Marko Strukelj</a>
+ */
+
+public class Singleton
+{
+ public Singleton()
+ {
+ System.out.println("Singleton instanciated: " + this);
+ }
+
+}
More information about the jboss-cvs-commits
mailing list