You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@composer.apache.org by ha...@apache.org on 2008/01/21 06:41:50 UTC
svn commit: r613775 [4/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...
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/AbstractBehaviorFactory.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/AbstractBehaviorFactory.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/AbstractBehaviorFactory.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/AbstractBehaviorFactory.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.ComponentFactory;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.BehaviorFactory;
+import org.apache.composer.core.injectors.AdaptingInjection;
+
+import java.io.Serializable;
+import java.util.Properties;
+import java.util.Enumeration;
+
+public class AbstractBehaviorFactory implements ComponentFactory, Serializable, BehaviorFactory {
+
+ private ComponentFactory delegate;
+
+ public ComponentFactory wrap(ComponentFactory delegate) {
+ this.delegate = delegate;
+ return this;
+ }
+
+ public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey,
+ Class<T> componentImplementation, Parameter... parameters) throws CompositionException {
+ if (delegate == null) {
+ delegate = new AdaptingInjection();
+ }
+ return delegate.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey,
+ componentImplementation, parameters);
+ }
+
+ public <T> ComponentAdapter<T> addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter<T> adapter) {
+ if (delegate != null && delegate instanceof BehaviorFactory) {
+ return ((BehaviorFactory) delegate).addComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, adapter);
+ }
+ return adapter;
+ }
+
+ public static boolean removePropertiesIfPresent(Properties current, Properties present) {
+ Enumeration<?> keys = present.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String presentValue = present.getProperty(key);
+ String currentValue = current.getProperty(key);
+ if (currentValue == null) {
+ return false;
+ }
+ if (!presentValue.equals(currentValue)) {
+ return false;
+ }
+ }
+ keys = present.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ current.remove(key);
+ }
+ return true;
+ }
+
+ protected void mergeProperties(Properties into, Properties from) {
+ Enumeration<?> e = from.propertyNames();
+ while (e.hasMoreElements()) {
+ String s = (String) e.nextElement();
+ into.setProperty(s, from.getProperty(s));
+ }
+
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/AdaptingBehavior.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/AdaptingBehavior.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/AdaptingBehavior.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/AdaptingBehavior.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,140 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.ComponentFactory;
+import org.apache.composer.core.BehaviorFactory;
+import org.apache.composer.core.annotations.Cache;
+import org.apache.composer.core.injectors.AdaptingInjection;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Properties;
+
+public class AdaptingBehavior implements BehaviorFactory, Serializable {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ Object componentKey,
+ Class componentImplementation,
+ Parameter... parameters) throws CompositionException {
+ List<BehaviorFactory> list = new ArrayList<BehaviorFactory>();
+ ComponentFactory lastFactory = makeInjectionFactory();
+ processSynchronizing(componentProperties, list);
+ processLocking(componentProperties, list);
+ processPropertyApplying(componentProperties, list);
+ processAutomatic(componentProperties, list);
+ processImplementationHiding(componentProperties, list);
+ processCaching(componentProperties, componentImplementation, list);
+
+ //Instantiate Chain of ComponentFactories
+ for (ComponentFactory componentFactory : list) {
+ if (lastFactory != null && componentFactory instanceof BehaviorFactory) {
+ ((BehaviorFactory)componentFactory).wrap(lastFactory);
+ }
+ lastFactory = componentFactory;
+ }
+
+ return lastFactory.createComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters);
+ }
+
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ List<BehaviorFactory> list = new ArrayList<BehaviorFactory>();
+ processSynchronizing(componentProperties, list);
+ processImplementationHiding(componentProperties, list);
+ processCaching(componentProperties, adapter.getComponentImplementation(), list);
+
+ //Instantiate Chain of ComponentFactories
+ BehaviorFactory lastFactory = null;
+ for (BehaviorFactory componentFactory : list) {
+ if (lastFactory != null) {
+ componentFactory.wrap(lastFactory);
+ }
+ lastFactory = componentFactory;
+ }
+
+ if (lastFactory == null) {
+ return adapter;
+ }
+
+
+ return lastFactory.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter);
+ }
+
+ protected AdaptingInjection makeInjectionFactory() {
+ return new AdaptingInjection();
+ }
+
+ protected void processSynchronizing(Properties componentProperties, List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE)) {
+ list.add(new Synchronizing());
+ }
+ }
+
+ protected void processLocking(Properties componentProperties, List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.LOCK)) {
+ list.add(new Locking());
+ }
+ }
+
+ protected void processCaching(Properties componentProperties,
+ Class componentImplementation,
+ List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE) ||
+ componentImplementation.getAnnotation(Cache.class) != null) {
+ list.add(new Caching());
+ }
+ AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE);
+ }
+
+ protected void processImplementationHiding(Properties componentProperties,
+ List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL)) {
+ list.add(new ImplementationHiding());
+ }
+ AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL);
+ }
+
+ protected void processPropertyApplying(Properties componentProperties,
+ List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING)) {
+ list.add(new PropertyApplying());
+ }
+ }
+
+ protected void processAutomatic(Properties componentProperties,
+ List<BehaviorFactory> list) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC)) {
+ list.add(new Automating());
+ }
+ }
+
+
+ public ComponentFactory wrap(ComponentFactory delegate) {
+ throw new UnsupportedOperationException();
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automated.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automated.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automated.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automated.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Original code by *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.Behavior;
+import org.apache.composer.core.ComponentAdapter;
+
+import java.io.Serializable;
+
+public class Automated<T> extends AbstractBehavior<T> implements Behavior<T>, Serializable {
+
+ /**
+ * Serialization UUID.
+ */
+ private static final long serialVersionUID = 36709276463500305L;
+
+ public Automated(ComponentAdapter<T> delegate) {
+ super(delegate);
+ }
+
+ public boolean hasLifecycle(Class<?> type) {
+ return true;
+ }
+
+ public String getDescriptor() {
+ return "Automated";
+ }
+}
\ No newline at end of file
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automating.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automating.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automating.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Automating.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Original code by *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Characteristics;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+public class Automating extends AbstractBehaviorFactory implements Serializable {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ Object componentKey,
+ Class componentImplementation,
+ Parameter... parameters) throws CompositionException {
+ removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC);
+ return new Automated(super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters));
+ }
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ removePropertiesIfPresent(componentProperties, Characteristics.AUTOMATIC);
+ return new Automated(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter));
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Behaviors.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Behaviors.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Behaviors.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Behaviors.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Original code by *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.BehaviorFactory;
+
+/**
+ * Static collection of factory methods for different BehaviourFactory implementations.
+ *
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class Behaviors {
+
+ /**
+ * Prevents instantiation
+ */
+ private Behaviors(){
+ // no-op
+ }
+
+ public static BehaviorFactory implementationHiding() {
+ return new ImplementationHiding();
+ }
+
+ public static BehaviorFactory caching() {
+ return new Caching();
+ }
+
+ public static BehaviorFactory synchronizing() {
+ return new Synchronizing();
+ }
+
+ public static BehaviorFactory locking() {
+ return new Locking();
+ }
+
+ public static BehaviorFactory propertyApplying() {
+ return new PropertyApplying();
+ }
+
+ public static BehaviorFactory automatic() {
+ return new Automating();
+ }
+
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Cached.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Cached.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Cached.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Cached.java Sun Jan 20 22:41:26 2008
@@ -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.apache.composer.core.behaviors;
+
+import java.io.Serializable;
+
+import org.apache.composer.core.Behavior;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ObjectReference;
+import org.apache.composer.core.references.SimpleReference;
+
+/**
+ * <p>
+ * {@link ComponentAdapter} implementation that caches the component instance.
+ * </p>
+ * <p>
+ * This adapter supports components with a lifecycle, as it is a
+ * {@link Behavior lifecycle manager} which will apply the delegate's
+ * {@link org.apache.composer.core.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
+ */
+public class Cached<T> extends Stored<T> {
+
+ public Cached(ComponentAdapter delegate) {
+ this(delegate, new SimpleReference());
+ }
+
+ public Cached(ComponentAdapter delegate, ObjectReference instanceReference) {
+ super(delegate, instanceReference);
+ }
+
+ public String getDescriptor() {
+ return "Cached";
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Caching.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Caching.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Caching.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Caching.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * 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.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+import org.apache.composer.core.references.SimpleReference;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.ObjectReference;
+
+import java.util.Properties;
+
+/**
+ * factory class creating cached behaviours
+ * @author Aslak Hellesøy
+ * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
+ * @author Konstantin Pribluda
+ */
+public class Caching extends AbstractBehaviorFactory {
+
+ public <T> ComponentAdapter<T> createComponentAdapter(
+ ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties, Object componentKey,
+ Class<T> componentImplementation, Parameter... parameters)
+ throws CompositionException {
+ if (removePropertiesIfPresent(componentProperties,
+ Characteristics.NO_CACHE)) {
+ return super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy, componentProperties, componentKey,
+ componentImplementation, parameters);
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.CACHE);
+ return new Cached<T>(super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy, componentProperties, componentKey,
+ componentImplementation, parameters), newObjectReference());
+
+ }
+
+ public <T> ComponentAdapter<T> addComponentAdapter(
+ ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties, ComponentAdapter<T> adapter) {
+ if (removePropertiesIfPresent(componentProperties,
+ Characteristics.NO_CACHE)) {
+ return super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy, componentProperties, adapter);
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.CACHE);
+ return new Cached<T>(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy, componentProperties, adapter),
+ newObjectReference());
+ }
+
+ protected <T> ObjectReference<T> newObjectReference() {
+ return new SimpleReference<T>();
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/HiddenImplementation.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/HiddenImplementation.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/HiddenImplementation.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/HiddenImplementation.java Sun Jan 20 22:41:26 2008
@@ -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.apache.composer.core.behaviors;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.behaviors.AbstractBehavior;
+
+/**
+ * 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.apache.composer.core.gems.adapters.HotSwappingComponentAdapter for a more feature-rich version of this class.
+ */
+public class HiddenImplementation<T> extends AbstractBehavior<T> {
+
+ /**
+ * Serialization UUID.
+ */
+ private static final long serialVersionUID = -9025725365839103497L;
+
+ /**
+ * Creates an ImplementationHidingComponentAdapter with a delegate
+ * @param delegate the component adapter to which this adapter delegates
+ */
+ public HiddenImplementation(ComponentAdapter<T> delegate) {
+ super(delegate);
+ }
+
+ public T getComponentInstance(final Container container) throws CompositionException {
+
+ ComponentAdapter<T> delegate = getDelegate();
+ Object componentKey = delegate.getComponentKey();
+ Class<?>[] classes;
+ if (componentKey instanceof Class && ((Class<?>) delegate.getComponentKey()).isInterface()) {
+ classes = new Class[]{(Class<?>) delegate.getComponentKey()};
+ } else if (componentKey instanceof Class[]) {
+ classes = (Class[]) componentKey;
+ } else {
+ return delegate.getComponentInstance(container);
+ }
+
+ Class<?>[] interfaces = verifyInterfacesOnly(classes);
+ return createProxy(interfaces, container, delegate.getComponentImplementation().getClassLoader());
+ }
+
+ public String getDescriptor() {
+ return "Hidden";
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private T createProxy(Class[] interfaces, final Container container, final ClassLoader classLoader) {
+ return (T) Proxy.newProxyInstance(classLoader,
+ interfaces, new InvocationHandler() {
+ public Object invoke(final Object proxy, final Method method,
+ final Object[] args)
+ throws Throwable {
+ return invokeMethod(method, args, container);
+ }
+ });
+ }
+
+ protected Object invokeMethod(Method method, Object[] args, Container container) throws Throwable {
+ Object componentInstance = getDelegate().getComponentInstance(container);
+ ComponentMonitor componentMonitor = currentMonitor();
+ try {
+ componentMonitor.invoking(container, this, method, componentInstance);
+ long startTime = System.currentTimeMillis();
+ Object object = method.invoke(componentInstance, args);
+ componentMonitor.invoked(container,
+ this,
+ 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 (Class<?> clazz : classes) {
+ if (!clazz.isInterface()) {
+ throw new CompositionException(
+ "Class keys must be interfaces. " + clazz + " is not an interface.");
+ }
+ }
+ return classes;
+ }
+
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/ImplementationHiding.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/ImplementationHiding.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/ImplementationHiding.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/ImplementationHiding.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Original code by *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+
+import java.util.Properties;
+
+/**
+ * @author Aslak Hellesøy
+ * @see org.apache.composer.core.gems.adapters.HotSwappingComponentFactory for a more feature-rich version of the class
+ */
+public class ImplementationHiding extends AbstractBehaviorFactory {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws CompositionException {
+ ComponentAdapter componentAdapter = super.createComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, componentKey, componentImplementation, parameters);
+ if (removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL)) {
+ return componentAdapter;
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL);
+ return new HiddenImplementation(componentAdapter);
+
+ }
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ if (removePropertiesIfPresent(componentProperties, Characteristics.NO_HIDE_IMPL)) {
+ return adapter;
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.HIDE_IMPL);
+ return new HiddenImplementation(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter));
+
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepted.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepted.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepted.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepted.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Container;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.io.Serializable;
+
+/** @author Paul Hammant */
+public class Intercepted<T> extends HiddenImplementation {
+
+ private final Map<Class, Object> pres = new HashMap<Class, Object>();
+ private final Map<Class, Object> posts = new HashMap<Class, Object>();
+ private Controller controller = new ControllerWrapper(new InterceptorThreadLocal());
+
+ public Intercepted(ComponentAdapter delegate) {
+ super(delegate);
+ }
+
+ public void addPreInvocation(Class type, Object interceptor) {
+ pres.put(type, interceptor);
+ }
+
+ public void addPostInvocation(Class type, Object interceptor) {
+ posts.put(type, interceptor);
+ }
+
+ protected Object invokeMethod(Method method, Object[] args, Container container) throws Throwable {
+ Object componentInstance = getDelegate().getComponentInstance(container);
+ try {
+ controller.clear();
+ controller.instance(componentInstance);
+ Object pre = pres.get(method.getDeclaringClass());
+ if (pre != null) {
+ Object rv = method.invoke(pre, args);
+ if (controller.isVetoed()) {
+ return rv;
+ }
+ }
+ Object result = method.invoke(componentInstance, args);
+ controller.setOriginalRetVal(result);
+ Object post = posts.get(method.getDeclaringClass());
+ if (post != null) {
+ Object rv = method.invoke(post, args);
+ if (controller.isOverridden()) {
+ return rv;
+ }
+ }
+ return result;
+ } catch (final InvocationTargetException ite) {
+ throw ite.getTargetException();
+ }
+ }
+
+ public Controller getController() {
+ return controller;
+ }
+
+ public static class InterceptorThreadLocal extends ThreadLocal implements Serializable {
+ protected Object initialValue() {
+ return new ControllerImpl();
+ }
+ }
+
+ public interface Controller {
+ void veto();
+
+ void clear();
+
+ boolean isVetoed();
+
+ void setOriginalRetVal(Object retVal);
+
+ boolean isOverridden();
+
+ void instance(Object instance);
+
+ Object getOriginalRetVal();
+
+ void override();
+ }
+
+ public static class ControllerImpl implements Controller {
+ private boolean vetoed;
+ private Object retVal;
+ private boolean overridden;
+ private Object instance;
+
+ public void veto() {
+ vetoed = true;
+ }
+
+ public void clear() {
+ vetoed = false;
+ overridden = false;
+ retVal = null;
+ instance = null;
+ }
+
+ public boolean isVetoed() {
+ return vetoed;
+ }
+ public void setOriginalRetVal(Object retVal) {
+ this.retVal = retVal;
+ }
+
+ public Object getOriginalRetVal() {
+ return retVal;
+ }
+
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ public void instance(Object instance) {
+ this.instance = instance;
+ }
+
+ public void override() {
+ overridden = true;
+ }
+ }
+
+ public class ControllerWrapper implements Controller {
+ private final ThreadLocal threadLocal;
+
+ public ControllerWrapper(ThreadLocal threadLocal) {
+ this.threadLocal = threadLocal;
+ }
+
+ public void veto() {
+ ((Controller) threadLocal.get()).veto();
+ }
+
+ public void clear() {
+ ((Controller) threadLocal.get()).clear();
+ }
+
+ public boolean isVetoed() {
+ return ((Controller) threadLocal.get()).isVetoed();
+ }
+
+ public void setOriginalRetVal(Object retVal) {
+ ((Controller) threadLocal.get()).setOriginalRetVal(retVal);
+ }
+
+ public Object getOriginalRetVal() {
+ return ((Controller) threadLocal.get()).getOriginalRetVal();
+ }
+
+ public boolean isOverridden() {
+ return ((Controller) threadLocal.get()).isOverridden();
+ }
+
+ public void instance(Object instance) {
+ ((Controller) threadLocal.get()).instance(instance);
+
+ }
+
+ public void override() {
+ ((Controller) threadLocal.get()).override();
+ }
+ }
+
+ public String getDescriptor() {
+ return "Intercepted";
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepting.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepting.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepting.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Intercepting.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.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+
+import java.util.Properties;
+
+
+/** @author Paul Hammant */
+public class Intercepting extends AbstractBehaviorFactory {
+
+ public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ Object componentKey,
+ Class<T> componentImplementation,
+ Parameter... parameters) throws CompositionException {
+ return new Intercepted(super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy, componentProperties, componentKey,
+ componentImplementation, parameters));
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locked.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locked.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locked.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locked.java Sun Jan 20 22:41:26 2008
@@ -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 *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author Paul Hammant
+ */
+public class Locked<T> extends AbstractBehavior<T> {
+ /**
+ * Serialization UUID.
+ */
+ private static final long serialVersionUID = 2355716085957171021L;
+
+ /**
+ * Reentrant lock.
+ */
+ private Lock lock = new ReentrantLock();
+
+ public Locked(ComponentAdapter<T> delegate) {
+ super(delegate);
+ }
+
+ public T getComponentInstance(Container container) throws CompositionException {
+ T retVal = null;
+ lock.lock();
+ try {
+ retVal = super.getComponentInstance(container);
+ }
+ finally {
+ lock.unlock();
+ }
+ return retVal;
+ }
+
+ public String getDescriptor() {
+ return "Locked";
+ }
+
+}
\ No newline at end of file
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locking.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locking.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locking.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Locking.java Sun Jan 20 22:41:26 2008
@@ -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 *
+ *****************************************************************************/
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+
+import java.util.Properties;
+
+/**
+ * @author Aslak Hellesøy
+ */
+public class Locking extends AbstractBehaviorFactory {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ Object componentKey,
+ Class componentImplementation,
+ Parameter... parameters) {
+ removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE);
+ return new Locked(super.createComponentAdapter(
+ componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters));
+ }
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE);
+ return new Synchronized(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter));
+ }
+}
\ No newline at end of file
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/OptInCaching.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/OptInCaching.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/OptInCaching.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/OptInCaching.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant *
+ *****************************************************************************/
+
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.behaviors.Cached;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+import org.apache.composer.core.LifecycleStrategy;
+
+import java.util.Properties;
+
+/**
+ * @author Aslak Hellesøy
+ * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
+ */
+public class OptInCaching extends AbstractBehaviorFactory {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters)
+ throws CompositionException {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE)) {
+ return new Cached(super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters));
+ }
+ AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE);
+ return super.createComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, componentKey, componentImplementation, parameters);
+ }
+
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CACHE)) {
+ return new Cached(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter));
+ }
+ AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE);
+ return super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter);
+ }
+}
\ No newline at end of file
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplicator.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplicator.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplicator.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplicator.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,301 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+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.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ClassNotFoundException;
+import org.apache.composer.core.injectors.SetterInjector;
+import org.apache.composer.core.behaviors.AbstractBehavior;
+import org.apache.composer.core.behaviors.Cached;
+
+/**
+ * Decorating component adapter that can be used to set additional properties
+ * on a component in a bean style. These properties must be managed manually
+ * by the user of the API, and will not be managed by PicoContainer. This class
+ * is therefore <em>not</em> the same as {@link SetterInjector},
+ * 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 Cached} around this one.
+ * </em>
+ *
+ * @author Aslak Hellesøy
+ * @author Mauro Talevi
+ */
+public class PropertyApplicator<T> extends AbstractBehavior<T> {
+ private Map<String, String> properties;
+ private transient Map<String, Method> setters = null;
+
+ /**
+ * Construct a PropertyApplicator.
+ *
+ * @param delegate the wrapped {@link ComponentAdapter}
+ * @throws org.apache.composer.core.CompositionException {@inheritDoc}
+ */
+ public PropertyApplicator(ComponentAdapter<T> delegate) throws CompositionException {
+ super(delegate);
+ }
+
+ /**
+ * Get a component instance and set given property values.
+ *
+ * @return the component instance with any properties of the properties map set.
+ * @throws org.apache.composer.core.CompositionException {@inheritDoc}
+ * @throws org.apache.composer.core.CompositionException {@inheritDoc}
+ * @throws org.apache.composer.core.CompositionException
+ * {@inheritDoc}
+ * @see #setProperties(Map)
+ */
+ public T getComponentInstance(Container container) throws CompositionException {
+ final T componentInstance = super.getComponentInstance(container);
+ if (setters == null) {
+ setters = getSetters(getComponentImplementation());
+ }
+
+ if (properties != null) {
+ ComponentMonitor componentMonitor = currentMonitor();
+ Set<String> propertyNames = properties.keySet();
+ for (String propertyName : propertyNames) {
+ final Object propertyValue = properties.get(propertyName);
+ Method setter = setters.get(propertyName);
+
+ Object valueToInvoke = this.getSetterParameter(propertyName, propertyValue, componentInstance, container);
+
+ try {
+ componentMonitor.invoking(container, PropertyApplicator.this, setter, componentInstance);
+ long startTime = System.currentTimeMillis();
+ setter.invoke(componentInstance, valueToInvoke);
+ componentMonitor.invoked(container,
+ PropertyApplicator.this,
+ setter, componentInstance, System.currentTimeMillis() - startTime);
+ } catch (final Exception e) {
+ componentMonitor.invocationFailed(setter, componentInstance, e);
+ throw new CompositionException("Failed to set property " + propertyName + " to " + propertyValue + ": " + e.getMessage(), e);
+ }
+ }
+ }
+ return componentInstance;
+ }
+
+ public String getDescriptor() {
+ return "PropertyApplied";
+ }
+
+ private Map<String, Method> getSetters(Class<?> clazz) {
+ Map<String, Method> result = new HashMap<String, Method>();
+ Method[] methods = getMethods(clazz);
+ for (Method method : methods) {
+ if (isSetter(method)) {
+ result.put(getPropertyName(method), method);
+ }
+ }
+ return result;
+ }
+
+ private Method[] getMethods(final Class<?> clazz) {
+ return (Method[]) AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ 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(Container container, Method setter, String propertyValue) {
+ if (propertyValue == null) {
+ return null;
+ }
+ Class<?> type = setter.getParameterTypes()[0];
+ String typeName = type.getName();
+
+ Object result = convert(typeName, propertyValue, Thread.currentThread().getContextClassLoader());
+
+ if (result == null) {
+
+ // check if the propertyValue is a key of a component in the container
+ // if so, the typeName of the component and the setters parameter typeName
+ // have to be compatible
+
+ // TODO: null check only because of test-case, otherwise null is impossible
+ if (container != null) {
+ Object component = container.getComponent(propertyValue);
+ if (component != null && type.isAssignableFrom(component.getClass())) {
+ return component;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Converts a String value of a named type to an object.
+ * Works with primitive wrappers, String, File, URL types, or any type that has
+ * an appropriate {@link PropertyEditor}.
+ *
+ * @param typeName name of the type
+ * @param value its value
+ * @param classLoader used to load a class if typeName is "class" or "java.lang.Class" (ignored otherwise)
+ * @return instantiated object or null if the type was unknown/unsupported
+ */
+ public static Object convert(String typeName, String value, ClassLoader classLoader) {
+ if (typeName.equals(Boolean.class.getName()) || typeName.equals(boolean.class.getName())) {
+ return Boolean.valueOf(value);
+ } else if (typeName.equals(Byte.class.getName()) || typeName.equals(byte.class.getName())) {
+ return Byte.valueOf(value);
+ } else if (typeName.equals(Short.class.getName()) || typeName.equals(short.class.getName())) {
+ return Short.valueOf(value);
+ } else if (typeName.equals(Integer.class.getName()) || typeName.equals(int.class.getName())) {
+ return Integer.valueOf(value);
+ } else if (typeName.equals(Long.class.getName()) || typeName.equals(long.class.getName())) {
+ return Long.valueOf(value);
+ } else if (typeName.equals(Float.class.getName()) || typeName.equals(float.class.getName())) {
+ return Float.valueOf(value);
+ } else if (typeName.equals(Double.class.getName()) || typeName.equals(double.class.getName())) {
+ return Double.valueOf(value);
+ } else if (typeName.equals(Character.class.getName()) || typeName.equals(char.class.getName())) {
+ return value.toCharArray()[0];
+ } else if (typeName.equals(String.class.getName()) || typeName.equals("string")) {
+ return value;
+ } else if (typeName.equals(File.class.getName()) || typeName.equals("file")) {
+ return new File(value);
+ } else if (typeName.equals(URL.class.getName()) || typeName.equals("url")) {
+ try {
+ return new URL(value);
+ } catch (MalformedURLException e) {
+ throw new CompositionException(e);
+ }
+ } else if (typeName.equals(Class.class.getName()) || typeName.equals("class")) {
+ return loadClass(classLoader, value);
+ } else {
+ final Class<?> clazz = loadClass(classLoader, typeName);
+ final PropertyEditor editor = PropertyEditorManager.findEditor(clazz);
+ if (editor != null) {
+ editor.setAsText(value);
+ return editor.getValue();
+ }
+ }
+ return null;
+ }
+
+ private static Class<?> loadClass(ClassLoader classLoader, String typeName) {
+ try {
+ return classLoader.loadClass(typeName);
+ } catch (java.lang.ClassNotFoundException e) {
+ throw new ClassNotFoundException(typeName, e);
+ }
+ }
+
+
+ /**
+ * Sets the bean property values that should be set upon creation.
+ *
+ * @param properties bean properties
+ */
+ public void setProperties(Map<String, String> properties) {
+ this.properties = properties;
+ }
+
+ /**
+ * Converts and validates the given property value to an appropriate object
+ * for calling the bean's setter.
+ * @param propertyName String the property name on the component that
+ * we will be setting the value to.
+ * @param propertyValue Object the property value that we've been given. It
+ * may need conversion to be formed into the value we need for the
+ * component instance setter.
+ * @param componentInstance the component that we're looking to provide
+ * the setter to.
+ * @return Object: the final converted object that can
+ * be used in the setter.
+ * @param container
+ */
+ private Object getSetterParameter(final String propertyName, final Object propertyValue,
+ final Object componentInstance, Container container) {
+
+ if (propertyValue == null) {
+ return null;
+ }
+
+ Method setter = setters.get(propertyName);
+
+ //We can assume that there is only one object (as per typical setters)
+ //because the Setter introspector does that job for us earlier.
+ Class<?> setterParameter = setter.getParameterTypes()[0];
+
+ Object convertedValue;
+
+ Class<? extends Object> givenParameterClass = propertyValue.getClass();
+
+ //
+ //If property value is a string or a true primative then convert it to whatever
+ //we need. (String will convert to string).
+ //
+ convertedValue = convertType(container, setter, propertyValue.toString());
+
+ //Otherwise, check the parameter type to make sure we can
+ //assign it properly.
+ if (convertedValue == null) {
+ if (setterParameter.isAssignableFrom(givenParameterClass)) {
+ convertedValue = propertyValue;
+ } else {
+ throw new ClassCastException("Setter: " + setter.getName() + " for addComponent: "
+ + componentInstance.toString() + " can only take objects of: " + setterParameter.getName()
+ + " instead got: " + givenParameterClass.getName());
+ }
+ }
+ return convertedValue;
+ }
+
+ public void setProperty(String name, String value) {
+ if (properties == null) {
+ properties = new HashMap<String, String>();
+ }
+ properties.put(name, value);
+ }
+
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplying.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplying.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplying.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/PropertyApplying.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+import org.apache.composer.core.behaviors.PropertyApplicator;
+
+import java.util.Properties;
+
+/**
+ * A {@link org.apache.composer.core.ComponentFactory} that creates
+ * {@link PropertyApplicator} instances.
+ *
+ * @author Aslak Hellesøy
+ */
+public final class PropertyApplying extends AbstractBehaviorFactory {
+
+ public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey,
+ Class<T> componentImplementation, Parameter... parameters) throws CompositionException {
+ ComponentAdapter<?> decoratedAdapter = super.createComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, componentKey, componentImplementation, parameters);
+ removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING);
+ return new PropertyApplicator(decoratedAdapter);
+ }
+
+ public <T> ComponentAdapter<T> addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy, Properties componentProperties, ComponentAdapter<T> adapter) {
+ removePropertiesIfPresent(componentProperties, Characteristics.PROPERTY_APPLYING);
+ return new PropertyApplicator(super.addComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, adapter));
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Stored.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Stored.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Stored.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Stored.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,119 @@
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.ObjectReference;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Container;
+
+/**
+ * behaviour for all behaviours wishing to store
+ * their component in "awkward places" ( object references )
+ * @author Konstantin Pribluda
+ *
+ * @param <T>
+ */
+public class Stored<T> extends AbstractBehavior<T> {
+
+
+ /**
+ * Serialization UUID.
+ */
+ private static final long serialVersionUID = -155678172730744032L;
+
+ protected final boolean delegateHasLifecylce;
+ protected boolean disposed;
+ protected final ObjectReference<T> instanceReference;
+
+ protected boolean started;
+
+ public Stored(ComponentAdapter<T> delegate, ObjectReference<T> reference) {
+ super(delegate);
+ instanceReference = reference;
+ this.disposed = false;
+ this.started = false;
+ this.delegateHasLifecylce = delegate instanceof LifecycleStrategy
+ && ((LifecycleStrategy) delegate).hasLifecycle(delegate.getComponentImplementation());
+
+ }
+
+ public boolean componentHasLifecycle() {
+ return delegateHasLifecylce;
+ }
+
+ /**
+ * Disposes the cached component instance
+ * {@inheritDoc}
+ */
+ public void dispose(Container container) {
+ if ( delegateHasLifecylce ){
+ if (disposed) throw new IllegalStateException("Already disposed");
+ dispose(getComponentInstance(container));
+ disposed = true;
+ }
+ }
+
+ /**
+ * Retrieves the stored reference. May be null if it has
+ * never been set, or possibly if the reference has been
+ * flushed.
+ * @return the stored object or null.
+ */
+ public T getStoredObject() {
+ return instanceReference.get();
+ }
+
+ /**
+ * 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);
+ }
+
+ public T getComponentInstance(Container container) throws CompositionException {
+ T instance = instanceReference.get();
+ if (instance == null) {
+ instance = super.getComponentInstance(container);
+ instanceReference.set(instance);
+ }
+ return instance;
+ }
+
+ public String getDescriptor() {
+ return "Stored";
+ }
+
+ /**
+ * Starts the cached component instance
+ * {@inheritDoc}
+ */
+ public void start(Container 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(Container container) {
+ if ( delegateHasLifecylce ){
+ if (disposed) throw new IllegalStateException("Already disposed");
+ if (!started) throw new IllegalStateException("Not started");
+ stop(getComponentInstance(container));
+ started = false;
+ }
+ }
+
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Storing.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Storing.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Storing.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Storing.java Sun Jan 20 22:41:26 2008
@@ -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. *
+ * *
+ * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant *
+ *****************************************************************************/
+
+package org.apache.composer.core.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.references.ThreadLocalMapObjectReference;
+
+import java.io.Serializable;
+import java.util.Properties;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * @author Paul Hammant
+ */
+public class Storing extends AbstractBehaviorFactory {
+
+ private final StoreThreadLocal mapThreadLocalObjectReference = new StoreThreadLocal();
+
+ public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, final Object componentKey, Class<T> componentImplementation, Parameter... parameters)
+
+ throws CompositionException {
+ if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) {
+ return super.createComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters);
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.CACHE);
+ return new Stored<T>(super.createComponentAdapter(componentMonitor, lifecycleStrategy,
+ componentProperties, componentKey, componentImplementation, parameters),
+ new ThreadLocalMapObjectReference(mapThreadLocalObjectReference, componentKey));
+
+ }
+
+ public <T> ComponentAdapter<T> addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ final ComponentAdapter<T> adapter) {
+ if (removePropertiesIfPresent(componentProperties, Characteristics.NO_CACHE)) {
+ return super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter);
+ }
+ removePropertiesIfPresent(componentProperties, Characteristics.CACHE);
+
+ return new Stored<T>(super.addComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, adapter),
+ new ThreadLocalMapObjectReference(mapThreadLocalObjectReference, adapter.getComponentKey()));
+ }
+
+ public StoreWrapper getCacheForThread() {
+ StoreWrapper wrappedMap = new StoreWrapper();
+ wrappedMap.wrapped = (Map)mapThreadLocalObjectReference.get();
+ return wrappedMap;
+ }
+
+ public void putCacheForThread(StoreWrapper wrappedMap) {
+ mapThreadLocalObjectReference.set(wrappedMap.wrapped);
+ }
+
+ public Map resetCacheForThread() {
+ HashMap map = new HashMap();
+ mapThreadLocalObjectReference.set(map);
+ return map;
+ }
+
+ public void invalidateCacheForThread() {
+ mapThreadLocalObjectReference.set(Collections.unmodifiableMap(Collections.emptyMap()));
+ }
+
+ public static class StoreThreadLocal extends ThreadLocal {
+ protected Object initialValue() {
+ return new HashMap();
+ }
+ }
+ public static class StoreWrapper implements Serializable {
+ private Map wrapped;
+ }
+
+}
\ No newline at end of file
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronized.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronized.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronized.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronized.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.behaviors.AbstractBehavior;
+
+/**
+ * Component Adapter that uses java synchronized around getComponentInstance().
+ * @author Aslak Hellesøy
+ * @author Manish Shah
+ */
+public class Synchronized<T> extends AbstractBehavior<T> {
+ /**
+ * Serialization UUID.
+ */
+ private static final long serialVersionUID = -3984071461712339652L;
+
+ public Synchronized(ComponentAdapter<T> delegate) {
+ super(delegate);
+ }
+
+ public synchronized T getComponentInstance(Container container) throws CompositionException {
+ return super.getComponentInstance(container);
+ }
+
+ public String getDescriptor() {
+ return "Synchronized";
+ }
+
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronizing.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronizing.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronizing.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/Synchronizing.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * 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.behaviors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.LifecycleStrategy;
+import org.apache.composer.core.Characteristics;
+import org.apache.composer.core.behaviors.AbstractBehaviorFactory;
+
+import java.util.Properties;
+
+/**
+ * @author Aslak Hellesøy
+ */
+public class Synchronizing extends AbstractBehaviorFactory {
+
+ public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) {
+ removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE);
+ return new Synchronized(super.createComponentAdapter(
+ componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ componentKey,
+ componentImplementation,
+ parameters));
+ }
+
+ public ComponentAdapter addComponentAdapter(ComponentMonitor componentMonitor,
+ LifecycleStrategy lifecycleStrategy,
+ Properties componentProperties,
+ ComponentAdapter adapter) {
+ removePropertiesIfPresent(componentProperties, Characteristics.SYNCHRONIZE);
+ return new Synchronized(super.addComponentAdapter(componentMonitor,
+ lifecycleStrategy,
+ componentProperties,
+ adapter));
+ }
+}
Added: incubator/composer/core/src/java/org/apache/composer/core/behaviors/ThreadCached.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/behaviors/ThreadCached.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/behaviors/ThreadCached.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/behaviors/ThreadCached.java Sun Jan 20 22:41:26 2008
@@ -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.apache.composer.core.behaviors;
+
+import java.io.Serializable;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.references.ThreadLocalReference;
+
+/**
+ * <p>
+ * This behavior supports caches values per thread.
+ * </p>
+ *
+ * @author Paul Hammant
+ */
+public final class ThreadCached<T> extends Stored<T>{
+
+ public ThreadCached(ComponentAdapter<T> delegate) {
+ super(delegate, new ThreadLocalReference<T>());
+ }
+
+ public String getDescriptor() {
+ return "ThreadCached";
+ }
+}
\ No newline at end of file