incubator-composer-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hamm...@apache.org
Subject svn commit: r613775 [7/15] - in /incubator/composer: ./ core/ core/src/ core/src/java/ core/src/java/org/ core/src/java/org/apache/ core/src/java/org/apache/composer/ core/src/java/org/apache/composer/core/ core/src/java/org/apache/composer/core/adapte...
Date Mon, 21 Jan 2008 06:41:50 GMT
Added: incubator/composer/core/src/java/org/apache/composer/core/monitors/AbstractComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/AbstractComponentMonitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/AbstractComponentMonitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/AbstractComponentMonitor.java Sun Jan 20 22:41:26 2008
@@ -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 Mauro Talevi                                             *
+ *****************************************************************************/
+
+package org.apache.composer.core.monitors;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.ComponentMonitorStrategy;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.monitors.NullComponentMonitor;
+
+/**
+ * <p>
+ * A {@link ComponentMonitor monitor} which delegates to another monitor.
+ * It provides a {@link NullComponentMonitor default ComponentMonitor},
+ * but does not allow to use <code>null</code> for the delegate.
+ * </p>
+ * <p>
+ * It also supports a {@link org.apache.composer.core.ComponentMonitorStrategy monitor strategy}
+ * that allows to change the delegate.
+ * </p>
+ * 
+ * @author Mauro Talevi
+ */
+public class AbstractComponentMonitor implements ComponentMonitor, ComponentMonitorStrategy, Serializable {
+
+    /**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = 4978870257460414077L;
+	
+	/**
+	 * Delegate monitor to allow for component monitor chaining.
+	 */
+	private  ComponentMonitor delegate;
+    
+    /**
+     * Creates a AbstractComponentMonitor with a given delegate
+     * @param delegate the ComponentMonitor to which this monitor delegates
+     */
+    public AbstractComponentMonitor(ComponentMonitor delegate) {
+        checkMonitor(delegate);
+        this.delegate = delegate;
+    }
+
+    /**
+     * Creates a AbstractComponentMonitor with an instance of
+     * {@link NullComponentMonitor}.
+     */
+    public AbstractComponentMonitor() {
+        this(new NullComponentMonitor());
+    }
+    
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor
+    ) {
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] injected,
+                             long duration) {
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, injected, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception e) {
+        delegate.instantiationFailed(container, componentAdapter, constructor, e);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        delegate.invoked(container, componentAdapter, method, instance, duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception e) {
+        delegate.invocationFailed(member, instance, e);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        delegate.lifecycleInvocationFailed(container, componentAdapter, method,instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        return delegate.noComponentFound(container, componentKey);
+    }
+
+    /**
+     * 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: incubator/composer/core/src/java/org/apache/composer/core/monitors/ComponentMonitorHelper.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/ComponentMonitorHelper.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/ComponentMonitorHelper.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/ComponentMonitorHelper.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * 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.apache.composer.core.monitors;
+
+import java.text.MessageFormat;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+
+import org.apache.composer.core.ComponentMonitor;
+
+/**
+ * An abstract {@link ComponentMonitor} which supports all the message formats.
+ * 
+ * @author Mauro Talevi
+ */
+public final class ComponentMonitorHelper  {
+
+    public final static String INSTANTIATING = "PicoContainer: instantiating {0}";
+    public final static String INSTANTIATED = "PicoContainer: instantiated {0} [{1} ms], component {2}, injected [{3}]";
+    public final static String INSTANTIATION_FAILED = "PicoContainer: instantiation failed: {0}, reason: {1}";
+    public final static String INVOKING = "PicoContainer: invoking {0} on {1}";
+    public final static String INVOKED = "PicoContainer: invoked {0} on {1} [{2} ms]";
+    public final static String INVOCATION_FAILED = "PicoContainer: invocation failed: {0} on {1}, reason: {2}";
+    public final static String LIFECYCLE_INVOCATION_FAILED = "PicoContainer: lifecycle invocation failed: {0} on {1}, reason: {2}";
+    public final static String NO_COMPONENT = "PicoContainer: No component for key: {0}";
+
+    public static String format(String template, Object... arguments) {
+        return MessageFormat.format(template, arguments);
+    }
+
+    public static String parmsToString(Object[] injected) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < injected.length; i++) {
+            String s = injected[i].getClass().getName();
+            sb.append(s);
+            if (i < injected.length-1) {
+                sb.append(", ");
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String ctorToString(Constructor constructor) {
+        Class[] params = constructor.getParameterTypes();
+        StringBuffer sb = new StringBuffer(constructor.getName());
+        sb.append("(");
+        for (int i = 0; i < params.length; i++) {
+            String s = params[i].getName();
+            sb.append(s);
+            if (i < params.length-1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    public static String methodToString(Method method) {
+        Class[] params = method.getParameterTypes();
+        StringBuffer sb = new StringBuffer(method.getName());
+        sb.append("(");
+        for (int i = 0; i < params.length; i++) {
+            String s = params[i].getName();
+            sb.append(s);
+            if (i < params.length-1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    public static String memberToString(Member m) {
+        if (m instanceof Field) {
+            return toString((Field) m);
+        } else {
+            return methodToString((Method) m);
+        }
+    }
+
+    public static String toString(Field field) {
+        StringBuffer sb = new StringBuffer(field.getName());
+        sb.append("(").append(field.getName()).append(")");
+        return sb.toString();
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/monitors/ConsoleComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/ConsoleComponentMonitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/ConsoleComponentMonitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/ConsoleComponentMonitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * 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.apache.composer.core.monitors;
+
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.methodToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.memberToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.ctorToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.parmsToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.format;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.Container;
+
+/**
+ * A {@link ComponentMonitor} which writes to a {@link OutputStream}. 
+ * This is typically used to write to a console.
+ * 
+ * @author Paul Hammant
+ * @author Aslak Helles&oslash;y
+ * @author Mauro Talevi
+ * @todo  After serialization, the output printstream is null.  
+ */
+public final class ConsoleComponentMonitor implements ComponentMonitor, Serializable {
+
+	/**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = -2541584067664868659L;
+
+	/**
+	 * The outgoing print stream.
+	 */
+    private final transient PrintStream out;
+    
+    /**
+     * Delegate component monitor (for component monitor chains).
+     */
+    private final ComponentMonitor delegate;
+
+    /**
+     * Constructs a console component monitor that sends output to <tt>System.out</tt>.
+     */
+    public ConsoleComponentMonitor() {
+        this(System.out);
+    }
+
+    /**
+     * Constructs a console component monitor that sends output to the specified output stream.
+     * 
+     * @param out  the designated output stream.  Options include System.out, Socket streams, File streams,
+     * etc.
+     */
+    public ConsoleComponentMonitor(OutputStream out) {
+        this(out, new NullComponentMonitor());
+    }
+
+    /**
+     * Constructs a console component monitor chain that sends output to the specified output stream
+     * and then sends all events to the delegate component monitor.
+     * @param out the output stream of choice.
+     * @param delegate the next monitor in the component monitor chain to receive event information.
+     */
+    public ConsoleComponentMonitor(OutputStream out, ComponentMonitor delegate) {
+        this.out = new PrintStream(out);
+        this.delegate = delegate;
+    }
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor
+    ) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] parameters,
+                             long duration) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(parameters)));
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception cause) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage()));
+        delegate.instantiationFailed(container, componentAdapter, constructor, cause);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        out.println(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance));
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        out.println(format(ComponentMonitorHelper.INVOKED, methodToString(method), instance, duration));
+        delegate.invoked(container, componentAdapter, method, instance, duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception cause) {
+        out.println(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage()));
+        delegate.invocationFailed(member, instance, cause);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        out.println(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage()));
+        delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        out.println(format(ComponentMonitorHelper.NO_COMPONENT, componentKey));
+        return delegate.noComponentFound(container, componentKey);
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/monitors/LifecycleComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/LifecycleComponentMonitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/LifecycleComponentMonitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/LifecycleComponentMonitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * 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.apache.composer.core.monitors;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.ComposerException;
+import org.apache.composer.core.LifecycleException;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.Container;
+
+/**
+ * A {@link ComponentMonitor} which collects lifecycle failures
+ * and rethrows them on demand after the failures.
+ * 
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public final class LifecycleComponentMonitor implements ComponentMonitor {
+
+	/**
+	 * Delegate for chained component monitors.
+	 */
+    private final ComponentMonitor delegate;
+    
+    private final List<RuntimeException> lifecycleFailures = new ArrayList<RuntimeException>();
+
+    public LifecycleComponentMonitor(ComponentMonitor delegate) {
+        this.delegate = delegate;
+    }
+
+    public LifecycleComponentMonitor() {
+        this(new NullComponentMonitor());
+    }
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor) {
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] parameters,
+                             long duration) {
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception cause) {
+        delegate.instantiationFailed(container, componentAdapter, constructor, cause);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        delegate.invoked(container, componentAdapter, method, instance, duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception cause) {
+        delegate.invocationFailed(member, instance, cause);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        lifecycleFailures.add(cause);
+        try {
+            delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
+        } catch (LifecycleException e) {
+            // do nothing, exception already logged for later rethrow.
+        }
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        return delegate.noComponentFound(container, componentKey);
+    }
+
+
+    public void rethrowLifecycleFailuresException() {
+        throw new LifecycleFailuresException(lifecycleFailures);
+    }
+
+    /**
+     * Subclass of {@link org.apache.composer.core.ComposerException} that is thrown when the collected
+     * lifecycle failures need to be be collectively rethrown.
+     * 
+     * @author Paul Hammant
+     * @author Mauro Talevi
+     */
+    public final class LifecycleFailuresException extends ComposerException {
+
+        /**
+		 * Serialization UUID. 
+		 */
+		private static final long serialVersionUID = -5627971463694211121L;
+		
+		private final List<RuntimeException> lifecycleFailures;
+
+        public LifecycleFailuresException(List<RuntimeException> lifecycleFailures) {
+            this.lifecycleFailures = lifecycleFailures;
+        }
+
+        public String getMessage() {
+            StringBuffer message = new StringBuffer();
+            for (Object lifecycleFailure : lifecycleFailures) {
+                Exception failure = (Exception)lifecycleFailure;
+                message.append(failure.getMessage()).append(";  ");
+            }
+            return message.toString();
+        }
+
+        public Collection<RuntimeException> getFailures() {
+            return lifecycleFailures;
+        }
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/monitors/NullComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/NullComponentMonitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/NullComponentMonitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/NullComponentMonitor.java Sun Jan 20 22:41:26 2008
@@ -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 Hammant & Obie Fernandez & Aslak Helles&oslash;y    *
+ *****************************************************************************/
+
+package org.apache.composer.core.monitors;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleException;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.Container;
+
+/**
+ * A {@link ComponentMonitor} which does nothing. 
+ * 
+ * @author Paul Hammant
+ * @author Obie Fernandez
+ */
+@SuppressWarnings("serial")
+public class NullComponentMonitor implements ComponentMonitor, Serializable {
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor) {
+        return constructor;
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception e) {
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T>  componentAdapter,
+                             Constructor<T>  constructor,
+                             Object instantiated,
+                             Object[] injected,
+                             long duration) {
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception e) {
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        throw new LifecycleException(method, instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        return null;
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/monitors/WriterComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/monitors/WriterComponentMonitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/monitors/WriterComponentMonitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/monitors/WriterComponentMonitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * 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.apache.composer.core.monitors;
+
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.methodToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.memberToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.ctorToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.parmsToString;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.format;
+
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.Container;
+
+/**
+ * A {@link ComponentMonitor} which writes to a {@link Writer}. 
+ * 
+ * @author Paul Hammant
+ * @author Aslak Helles&oslash;y
+ * @author Mauro Talevi
+ */
+public class WriterComponentMonitor implements ComponentMonitor {
+
+    private final PrintWriter out;
+    private final ComponentMonitor delegate;
+
+    public WriterComponentMonitor(Writer out) {
+        this(out, new NullComponentMonitor());
+    }
+
+    public WriterComponentMonitor(Writer out, ComponentMonitor delegate) {
+        this.out = new PrintWriter(out);
+        this.delegate = delegate;
+    }
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] injected,
+                             long duration) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(injected)));
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, injected, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception cause) {
+        out.println(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage()));
+        delegate.instantiationFailed(container, null, constructor, cause);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        out.println(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance));
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        out.println(format(ComponentMonitorHelper.INVOKED, methodToString(method), instance, duration));
+        delegate.invoked(container, componentAdapter, method, instance, duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception cause) {
+        out.println(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage()));
+        delegate.invocationFailed(member, instance, cause);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        out.println(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage()));
+        delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        out.println(format(ComponentMonitorHelper.NO_COMPONENT, componentKey));
+        return delegate.noComponentFound(container, componentKey);
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/package.html
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/package.html?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/package.html (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/package.html Sun Jan 20 22:41:26 2008
@@ -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.apache.composer.core.MutablePicoContainer},
+register classes (and possibly
+{@link org.apache.composer.core.ComponentAdapter}s and component instances created through other means).
+</p>
+<p>
+Object instances can then be accessed through the {@link org.apache.composer.core.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.apache.composer.core.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: incubator/composer/core/src/java/org/apache/composer/core/parameters/BasicComponentParameter.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/parameters/BasicComponentParameter.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/parameters/BasicComponentParameter.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/parameters/BasicComponentParameter.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,280 @@
+/*****************************************************************************
+ * 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.apache.composer.core.parameters;
+
+import java.io.File;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.NameBinding;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.injectors.AbstractInjector;
+
+/**
+ * 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&eacute;n
+ * @author Aslak Helles&oslash;y
+ * @author J&ouml;rg Schaible
+ * @author Thomas Heller
+ */
+public class BasicComponentParameter implements Parameter, Serializable {
+
+    private static interface Converter {
+        Object convert(String paramValue);
+    }
+    private static class ValueOfConverter implements Converter {
+        private Method m;
+        private ValueOfConverter(Class clazz) {
+            try {
+                m = clazz.getMethod("valueOf", String.class);
+            } catch (NoSuchMethodException e) {
+            }
+        }
+
+        public Object convert(String paramValue) {
+            try {
+                return m.invoke(null, paramValue);
+            } catch (IllegalAccessException e) {
+            } catch (InvocationTargetException e) {
+            }
+            return null;
+
+        }
+    }
+    private static class NewInstanceConverter implements Converter {
+        private Constructor c;
+
+        private NewInstanceConverter(Class clazz) {
+            try {
+                c = clazz.getConstructor(String.class);
+            } catch (NoSuchMethodException e) {
+            }
+        }
+
+        public Object convert(String paramValue) {
+            try {
+                return c.newInstance(paramValue);
+            } catch (IllegalAccessException e) {
+            } catch (InvocationTargetException e) {
+            } catch (InstantiationException e) {
+            }
+            return null;
+        }
+    }
+
+    /** <code>BASIC_DEFAULT</code> is an instance of BasicComponentParameter using the default constructor. */
+    public static final BasicComponentParameter BASIC_DEFAULT = new BasicComponentParameter();
+
+    private Object componentKey;
+
+
+    private static final Map<Class, Converter> stringConverters = new HashMap<Class, Converter>();
+    static {
+        stringConverters.put(Integer.class, new ValueOfConverter(Integer.class));
+        stringConverters.put(Double.class, new ValueOfConverter(Double.class));
+        stringConverters.put(Boolean.class, new ValueOfConverter(Boolean.class));
+        stringConverters.put(Long.class, new ValueOfConverter(Long.class));
+        stringConverters.put(Float.class, new ValueOfConverter(Float.class));
+        stringConverters.put(Character.class, new ValueOfConverter(Character.class));
+        stringConverters.put(Byte.class, new ValueOfConverter(Byte.class));
+        stringConverters.put(Byte.class, new ValueOfConverter(Short.class));
+        stringConverters.put(File.class, new NewInstanceConverter(File.class));
+
+    }
+
+
+    /**
+     * Expect a parameter matching a component of a specific key.
+     *
+     * @param componentKey the key of the desired addComponent
+     */
+    public BasicComponentParameter(Object componentKey) {
+        this.componentKey = componentKey;
+    }
+
+    /** Expect any 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.apache.composer.core.CompositionException
+     *          {@inheritDoc}
+     * @see Parameter#isResolvable(org.apache.composer.core.Container , ComponentAdapter, Class, NameBinding ,boolean, Annotation)
+     */
+    public boolean isResolvable(Container container,
+                                ComponentAdapter adapter,
+                                Class expectedType,
+                                NameBinding expectedNameBinding, boolean useNames, Annotation binding) {
+        return resolveAdapter(container, adapter, (Class<?>)expectedType, expectedNameBinding, useNames, binding) != null;
+    }
+
+    public <T> T resolveInstance(Container container,
+                                 ComponentAdapter adapter,
+                                 Class<T> expectedType,
+                                 NameBinding expectedNameBinding, boolean useNames, Annotation binding) {
+        final ComponentAdapter componentAdapter =
+            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedNameBinding, useNames, binding);
+        if (componentAdapter != null) {
+            Object o = container.getComponent(componentAdapter.getComponentKey());
+            if (o instanceof String && expectedType != String.class) {
+                Converter converter = stringConverters.get(expectedType);
+                return (T) converter.convert((String) o);
+            }
+            return (T) o;
+        }
+        return null;
+    }
+
+    public void verify(Container container,
+                       ComponentAdapter adapter,
+                       Class expectedType,
+                       NameBinding expectedNameBinding, boolean useNames, Annotation binding) {
+        final ComponentAdapter componentAdapter =
+            resolveAdapter(container, adapter, (Class<?>)expectedType, expectedNameBinding, useNames, binding);
+        if (componentAdapter == null) {
+            final Set<Class> set = new HashSet<Class>();
+            set.add(expectedType);
+            throw new AbstractInjector.UnsatisfiableDependenciesException(adapter, null, set, container);
+        }
+        componentAdapter.verify(container);
+    }
+
+    /**
+     * Visit the current {@link Parameter}.
+     *
+     * @see org.apache.composer.core.Parameter#accept(org.apache.composer.core.ContainerVisitor)
+     */
+    public void accept(final ContainerVisitor visitor) {
+        visitor.visitParameter(this);
+    }
+
+    private <T> ComponentAdapter<T> resolveAdapter(Container container,
+                                                   ComponentAdapter adapter,
+                                                   Class<T> expectedType,
+                                                   NameBinding expectedNameBinding, boolean useNames, Annotation binding) {
+        Class type = expectedType;
+        if (type.isPrimitive()) {
+            String expectedTypeName = expectedType.getName();
+            if (expectedTypeName == "int") {
+                type = Integer.class;
+            } else if (expectedTypeName == "long") {
+                type = Long.class;
+            } else if (expectedTypeName == "float") {
+                type = Float.class;
+            } else if (expectedTypeName == "double") {
+                type = Double.class;
+            } else if (expectedTypeName == "boolean") {
+                type = Boolean.class;
+            } else if (expectedTypeName == "char") {
+                type = Character.class;
+            } else if (expectedTypeName == "short") {
+                type = Short.class;
+            } else if (expectedTypeName == "byte") {
+                type = Byte.class;
+            }
+        }
+
+        final ComponentAdapter<T> result = getTargetAdapter(container, type, expectedNameBinding, adapter, useNames,
+                                                            binding);
+        if (result == null) {
+            return null;
+        }
+
+        if (!type.isAssignableFrom(result.getComponentImplementation())) {
+            if (!(result.getComponentImplementation() == String.class && stringConverters.containsKey(type))) {
+                return null;
+            }
+        }
+        return result;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private static <T> ComponentAdapter<T> typeComponentAdapter(ComponentAdapter<?> componentAdapter) {
+        return (ComponentAdapter<T>)componentAdapter;
+    }
+
+    private <T> ComponentAdapter<T> getTargetAdapter(Container container,
+                                                     Class<T> expectedType,
+                                                     NameBinding expectedNameBinding,
+                                                     ComponentAdapter excludeAdapter, boolean useNames, Annotation binding) {
+        if (componentKey != null) {
+            // key tells us where to look so we follow
+            return typeComponentAdapter(container.getComponentAdapter(componentKey));
+        } else if (excludeAdapter == null) {
+            return container.getComponentAdapter(expectedType, (NameBinding) null);
+        } else {
+
+            Object excludeKey = excludeAdapter.getComponentKey();
+            ComponentAdapter byKey = container.getComponentAdapter((Object)expectedType);
+            if (byKey != null && !excludeKey.equals(byKey.getComponentKey())) {
+                return typeComponentAdapter(byKey);
+            }
+            if (useNames) {
+                ComponentAdapter found = container.getComponentAdapter(expectedNameBinding.getName());
+                if ((found != null)
+                    && areCompatible(expectedType, found)
+                    && found != excludeAdapter) {
+                    return (ComponentAdapter<T>) found;                    
+                }
+            }
+            List<ComponentAdapter<T>> found = binding == null ? container.getComponentAdapters(expectedType) :
+                                              container.getComponentAdapters(expectedType, binding.annotationType());
+            ComponentAdapter exclude = null;
+            for (ComponentAdapter work : found) {
+                if (work.getComponentKey().equals(excludeKey)) {
+                    exclude = work;
+                }
+            }
+            found.remove(exclude);
+            if (found.size() == 0) {
+                if (container.getParent() != null) {
+                    return container.getParent().getComponentAdapter(expectedType, expectedNameBinding);
+                } else {
+                    return null;
+                }
+            } else if (found.size() == 1) {
+                return found.get(0);
+            } else {
+                Class[] foundClasses = new Class[found.size()];
+                for (int i = 0; i < foundClasses.length; i++) {
+                    foundClasses[i] = found.get(i).getComponentImplementation();
+                }
+                throw new AbstractInjector.AmbiguousComponentResolutionException(expectedType, foundClasses);
+            }
+        }
+    }
+
+    private <T> boolean areCompatible(Class<T> expectedType, ComponentAdapter found) {
+        Class foundImpl = found.getComponentImplementation();
+        return expectedType.isAssignableFrom(foundImpl) ||
+               (foundImpl == String.class && stringConverters.containsKey(expectedType))  ;
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/parameters/CollectionComponentParameter.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/parameters/CollectionComponentParameter.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/parameters/CollectionComponentParameter.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/parameters/CollectionComponentParameter.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,383 @@
+/*****************************************************************************
+ * 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.apache.composer.core.parameters;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.NameBinding;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ContainerVisitor;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+
+/**
+ * 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&oslash;y
+ * @author J&ouml;rg Schaible
+ */
+@SuppressWarnings("serial")
+public class CollectionComponentParameter
+    implements Parameter, Serializable
+{
+
+    /** 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}
+     * @param expectedNameBinding {@inheritDoc}
+     *
+     * @param useNames
+     * @param binding
+     * @return the instance of the collection type or <code>null</code>
+     *
+     * @throws org.apache.composer.core.CompositionException {@inheritDoc}
+     */
+    @SuppressWarnings({ "unchecked" })
+    public Object resolveInstance(Container container,
+                                  ComponentAdapter adapter,
+                                  Class expectedType,
+                                  NameBinding expectedNameBinding, boolean useNames, Annotation binding)
+    {
+        // type check is done in isResolvable
+        Object result = null;
+        final Class collectionType = getCollectionType(expectedType);
+        if (collectionType != null) {
+            final Map<Object, ComponentAdapter<?>> 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, (Class<? extends Collection>)expectedType, adapterMap);
+            } else {
+                throw new CompositionException(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}
+     * @param expectedNameBinding {@inheritDoc}
+     *
+     * @param useNames
+     * @param binding
+     * @return <code>true</code> if matching components were found or an empty collective type
+     *         is allowed
+     */
+    public boolean isResolvable(Container container,
+                                ComponentAdapter adapter,
+                                Class expectedType,
+                                NameBinding expectedNameBinding, boolean useNames, Annotation binding) {
+        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}
+     * @param expectedNameBinding {@inheritDoc}
+     *
+     * @param useNames
+     * @param binding
+     * @throws org.apache.composer.core.CompositionException {@inheritDoc}
+     */
+    public void verify(Container container,
+                       ComponentAdapter adapter,
+                       Class expectedType,
+                       NameBinding expectedNameBinding, boolean useNames, Annotation binding)
+    {
+        final Class collectionType = getCollectionType(expectedType);
+        if (collectionType != null) {
+            final Class valueType = getValueType(expectedType);
+            final Collection componentAdapters =
+                getMatchingComponentAdapters(container, adapter, componentKeyType, valueType).values();
+            if (componentAdapters.isEmpty()) {
+                if (!emptyCollection) {
+                    throw new CompositionException(expectedType.getName()
+                                                         + " not resolvable, no components of type "
+                                                         + getValueType(expectedType).getName()
+                                                         + " available");
+                }
+            } else {
+                for (Object componentAdapter1 : componentAdapters) {
+                    final ComponentAdapter componentAdapter = (ComponentAdapter)componentAdapter1;
+                    componentAdapter.verify(container);
+                }
+            }
+        } else {
+            throw new CompositionException(expectedType.getName() + " is not a collective type");
+        }
+    }
+
+    /**
+     * Visit the current {@link Parameter}.
+     *
+     * @see org.apache.composer.core.Parameter#accept(org.apache.composer.core.ContainerVisitor)
+     */
+    public void accept(final ContainerVisitor 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 addComponent
+     *
+     * @return a {@link Map} with the ComponentAdapter instances and their component keys as map key.
+     */
+    @SuppressWarnings({ "unchecked" })
+    protected Map<Object, ComponentAdapter<?>> getMatchingComponentAdapters(Container container,
+                                                                            ComponentAdapter adapter,
+                                                                            Class keyType,
+                                                                            Class valueType)
+    {
+        final Map<Object, ComponentAdapter<?>> adapterMap = new LinkedHashMap<Object, ComponentAdapter<?>>();
+        final Container parent = container.getParent();
+        if (parent != null) {
+            adapterMap.putAll(getMatchingComponentAdapters(parent, adapter, keyType, valueType));
+        }
+        final Collection<ComponentAdapter<?>> allAdapters = container.getComponentAdapters();
+        for (ComponentAdapter componentAdapter : allAdapters) {
+            adapterMap.remove(componentAdapter.getComponentKey());
+        }
+        final List<ComponentAdapter> adapterList = container.getComponentAdapters(valueType);
+        for (ComponentAdapter componentAdapter : adapterList) {
+            final Object key = componentAdapter.getComponentKey();
+            if (adapter != null && key.equals(adapter.getComponentKey())) {
+                continue;
+            }
+            if (keyType.isAssignableFrom(key.getClass()) && evaluate(componentAdapter)) {
+                adapterMap.put(key, componentAdapter);
+            }
+        }
+        return adapterMap;
+    }
+
+    private Class getCollectionType(final Class collectionType) {
+        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 Container container,
+                                      final Class expectedType,
+                                      final Map<Object, ComponentAdapter<?>> adapterList)
+    {
+        final Object[] result = (Object[])Array.newInstance(expectedType.getComponentType(), adapterList.size());
+        int i = 0;
+        for (ComponentAdapter componentAdapter : adapterList.values()) {
+            result[i] = container.getComponent(componentAdapter.getComponentKey());
+            i++;
+        }
+        return result;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private Collection getCollectionInstance(final Container container,
+                                             final Class<? extends Collection> expectedType,
+                                             final Map<Object, ComponentAdapter<?>> adapterList)
+    {
+        Class<? extends Collection> collectionType = expectedType;
+        if (collectionType.isInterface()) {
+            // The order of tests are significant. The least generic types last.
+            if (List.class.isAssignableFrom(collectionType)) {
+                collectionType = ArrayList.class;
+//            } else if (BlockingQueue.class.isAssignableFrom(collectionType)) {
+//                collectionType = ArrayBlockingQueue.class;
+//            } else if (Queue.class.isAssignableFrom(collectionType)) {
+//                collectionType = LinkedList.class;
+            } else if (SortedSet.class.isAssignableFrom(collectionType)) {
+                collectionType = TreeSet.class;
+            } else if (Set.class.isAssignableFrom(collectionType)) {
+                collectionType = HashSet.class;
+            } else if (Collection.class.isAssignableFrom(collectionType)) {
+                collectionType = ArrayList.class;
+            }
+        }
+        try {
+            Collection result = collectionType.newInstance();
+            for (ComponentAdapter componentAdapter : adapterList.values()) {
+                result.add(container.getComponent(componentAdapter.getComponentKey()));
+            }
+            return result;
+        } catch (InstantiationException e) {
+            ///CLOVER:OFF
+            throw new CompositionException(e);
+            ///CLOVER:ON
+        } catch (IllegalAccessException e) {
+            ///CLOVER:OFF
+            throw new CompositionException(e);
+            ///CLOVER:ON
+        }
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private Map getMapInstance(final Container container,
+                               final Class<? extends Map> expectedType,
+                               final Map<Object, ComponentAdapter<?>> adapterList)
+    {
+        Class<? extends Map> collectionType = expectedType;
+        if (collectionType.isInterface()) {
+            // The order of tests are significant. The least generic types last.
+            if (SortedMap.class.isAssignableFrom(collectionType)) {
+                collectionType = TreeMap.class;
+//            } else if (ConcurrentMap.class.isAssignableFrom(collectionType)) {
+//                collectionType = ConcurrentHashMap.class;
+            } else if (Map.class.isAssignableFrom(collectionType)) {
+                collectionType = HashMap.class;
+            }
+        }
+        try {
+            Map result = collectionType.newInstance();
+            for (Map.Entry<Object, ComponentAdapter<?>> entry : adapterList.entrySet()) {
+                final Object key = entry.getKey();
+                result.put(key, container.getComponent(key));
+            }
+            return result;
+        } catch (InstantiationException e) {
+            ///CLOVER:OFF
+            throw new CompositionException(e);
+            ///CLOVER:ON
+        } catch (IllegalAccessException e) {
+            ///CLOVER:OFF
+            throw new CompositionException(e);
+            ///CLOVER:ON
+        }
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/parameters/ComponentParameter.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/parameters/ComponentParameter.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/parameters/ComponentParameter.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/parameters/ComponentParameter.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,170 @@
+/*****************************************************************************
+ * 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.apache.composer.core.parameters;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.NameBinding;
+import org.apache.composer.core.injectors.AbstractInjector;
+
+import java.lang.annotation.Annotation;
+
+
+/**
+ * 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&eacute;n
+ * @author Aslak Helles&oslash;y
+ * @author J&ouml;rg Schaible
+ * @author Thomas Heller
+ */
+@SuppressWarnings("serial")
+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 addComponent
+     */
+    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
+     */
+    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
+     */
+    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
+     */
+    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  <T> T resolveInstance(Container container,
+                                  ComponentAdapter adapter,
+                                  Class<T> expectedType,
+                                  NameBinding expectedNameBinding,
+                                  boolean useNames, Annotation binding) {
+        // type check is done in isResolvable
+        T result = super.resolveInstance(container, adapter, expectedType, expectedNameBinding, useNames, binding);
+        if (result == null && collectionParameter != null) {
+            result = collectionParameter.resolveInstance(container, adapter, expectedType, expectedNameBinding,
+                                                         useNames, binding);
+        }
+        return result;
+    }
+
+    public boolean isResolvable(Container container,
+                                ComponentAdapter adapter,
+                                Class expectedType,
+                                NameBinding expectedNameBinding,
+                                boolean useNames, Annotation binding) {
+        if (!super.isResolvable(container, adapter, expectedType, expectedNameBinding, useNames, binding)) {
+            if (collectionParameter != null) {
+                return collectionParameter.isResolvable(container, adapter, expectedType, expectedNameBinding,
+                                                        useNames, binding);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public void verify(Container container,
+                       ComponentAdapter adapter,
+                       Class expectedType,
+                       NameBinding expectedNameBinding,
+                       boolean useNames, Annotation binding) {
+        try {
+            super.verify(container, adapter, expectedType, expectedNameBinding, useNames, binding);
+        } catch (AbstractInjector.UnsatisfiableDependenciesException e) {
+            if (collectionParameter != null) {
+                collectionParameter.verify(container, adapter, expectedType, expectedNameBinding, useNames, binding);
+                return;
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Accept the visitor for the current {@link Parameter}. If internally a
+     * {@link CollectionComponentParameter}is used, it is visited also.
+     * 
+     * @see BasicComponentParameter#accept(org.apache.composer.core.ContainerVisitor)
+     */
+    public void accept(ContainerVisitor visitor) {
+        super.accept(visitor);
+        if (collectionParameter != null) {
+            collectionParameter.accept(visitor);
+        }
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/parameters/ConstantParameter.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/parameters/ConstantParameter.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/parameters/ConstantParameter.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/parameters/ConstantParameter.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * 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.apache.composer.core.parameters;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.ComposerException;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.NameBinding;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.annotation.Annotation;
+
+
+/**
+ * A ConstantParameter should be used to pass in "constant" arguments to constructors. This
+ * includes {@link String}s,{@link Integer}s or any other object that is not registered in
+ * the container.
+ *
+ * @author Jon Tirs&eacute;n
+ * @author Aslak Helles&oslash;y
+ * @author J&ouml;rg Schaible
+ * @author Thomas Heller
+ */
+public class ConstantParameter
+        implements Parameter, Serializable {
+
+    private final Object value;
+
+    public ConstantParameter(Object value) {
+        this.value = value;
+    }
+
+    public Object resolveInstance(Container container,
+                                  ComponentAdapter adapter,
+                                  Class expectedType,
+                                  NameBinding expectedNameBinding,
+                                  boolean useNames, Annotation binding) {
+        return value;
+    }
+
+    public boolean isResolvable(Container container,
+                                ComponentAdapter adapter,
+                                Class expectedType,
+                                NameBinding expectedNameBinding,
+                                boolean useNames, Annotation binding) {
+        try {
+            verify(container, adapter, expectedType, expectedNameBinding, useNames, binding);
+            return true;
+        } catch(final CompositionException e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see Parameter#verify(org.apache.composer.core.Container , ComponentAdapter, Class, NameBinding ,boolean, Annotation)
+     */
+    public void verify(Container container,
+                       ComponentAdapter adapter,
+                       Class expectedType,
+                       NameBinding expectedNameBinding,
+                       boolean useNames, Annotation binding) throws ComposerException {
+        if (!checkPrimitive(expectedType) && !expectedType.isInstance(value)) {
+            throw new CompositionException(expectedType.getClass().getName() + " is not assignable from " +
+                                                 (value != null ? value.getClass().getName() : "null"));
+        }
+    }
+
+    /**
+     * Visit the current {@link Parameter}.
+     *
+     * @see org.apache.composer.core.Parameter#accept(org.apache.composer.core.ContainerVisitor)
+     */
+    public void accept(final ContainerVisitor visitor) {
+        visitor.visitParameter(this);
+    }
+
+    private boolean checkPrimitive(Class expectedType) {
+        try {
+            if (expectedType.isPrimitive()) {
+                final Field field = value.getClass().getField("TYPE");
+                final Class type = (Class) field.get(value);
+                return expectedType.isAssignableFrom(type);
+            }
+        } catch (NoSuchFieldException e) {
+            //ignore
+        } catch (IllegalAccessException e) {
+            //ignore
+        }
+        return false;
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/references/SimpleReference.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/references/SimpleReference.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/references/SimpleReference.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/references/SimpleReference.java Sun Jan 20 22:41:26 2008
@@ -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.apache.composer.core.references;
+
+import java.io.Serializable;
+
+import org.apache.composer.core.ObjectReference;
+
+/**
+ * Simple instance implementation of ObjectReference. 
+ * 
+ * @author Aslak Helles&oslash;y
+ * @author Konstantin Pribluda
+ */
+@SuppressWarnings("serial")
+public class SimpleReference<T> implements ObjectReference<T>,
+		Serializable {
+	private T instance;
+
+	public SimpleReference() {
+	    // no-op
+	}
+
+	public T get() {
+		return instance;
+	}
+
+	public void set(T item) {
+		this.instance = item;
+	}
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalMapObjectReference.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalMapObjectReference.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalMapObjectReference.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalMapObjectReference.java Sun Jan 20 22:41:26 2008
@@ -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.                                                     *
+ *                                                                           *
+ *****************************************************************************/
+package org.apache.composer.core.references;
+
+import org.apache.composer.core.ObjectReference;
+
+import java.util.Map;
+
+/** @author Paul Hammant */
+public  class ThreadLocalMapObjectReference implements ObjectReference {
+    private final ThreadLocal threadLocal;
+    private final Object componentKey;
+
+    public ThreadLocalMapObjectReference(ThreadLocal threadLocal, Object componentKey) {
+        this.threadLocal = threadLocal;
+        this.componentKey = componentKey;
+    }
+
+    public Object get() {
+        return ((Map)threadLocal.get()).get(componentKey) ;
+    }
+
+    public void set(Object item) {
+        ((Map)threadLocal.get()).put(componentKey, item) ;
+
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalReference.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalReference.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalReference.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/references/ThreadLocalReference.java Sun Jan 20 22:41:26 2008
@@ -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.                                                     *
+ *                                                                           *
+ *****************************************************************************/
+package org.apache.composer.core.references;
+
+import org.apache.composer.core.ObjectReference;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+
+/** @author Paul Hammant */
+public class ThreadLocalReference<T> extends ThreadLocal<T> implements ObjectReference<T>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private void writeObject(final ObjectOutputStream out) {
+        if(out != null); // eliminate warning because of unused parameter
+    }
+
+    private void readObject(final ObjectInputStream in) {
+        if(in != null); // eliminate warning because of unused parameter
+    }
+
+}



Mime
View raw message