001/*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.            *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD      *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file.                                                     *
007 *                                                                           *
008 * Original code by Jon Tirsen                                               *
009 *****************************************************************************/
010
011package org.picocontainer.behaviors;
012
013import org.picocontainer.ComponentAdapter;
014import org.picocontainer.ComponentMonitor;
015import org.picocontainer.ComponentMonitorStrategy;
016import org.picocontainer.LifecycleStrategy;
017import org.picocontainer.PicoCompositionException;
018import org.picocontainer.PicoContainer;
019import org.picocontainer.PicoVisitor;
020
021import java.io.Serializable;
022import java.lang.reflect.Type;
023
024/**
025 * <p>
026 * Component adapter which decorates another adapter.
027 * </p>
028 * <p>
029 * This adapter supports a {@link org.picocontainer.ComponentMonitorStrategy component monitor strategy}
030 * and will propagate change of monitor to the delegate if the delegate itself
031 * support the monitor strategy.
032 * </p>
033 * <p>
034 * This adapter also supports a {@link Behavior lifecycle manager} and a
035 * {@link org.picocontainer.LifecycleStrategy lifecycle strategy} if the delegate does.
036 * </p>
037 * 
038 * @author Jon Tirsen
039 * @author Aslak Hellesoy
040 * @author Mauro Talevi
041 */
042public abstract class AbstractBehavior<T> implements org.picocontainer.Behavior<T>, ComponentMonitorStrategy,
043                                                  LifecycleStrategy, Serializable {
044
045    protected final ComponentAdapter<T> delegate;
046
047    public AbstractBehavior(ComponentAdapter<T> delegate) {
048        this.delegate = delegate;
049    }
050    
051    public Object getComponentKey() {
052        return delegate.getComponentKey();
053    }
054
055    public Class<? extends T> getComponentImplementation() {
056        return delegate.getComponentImplementation();
057    }
058
059    public T getComponentInstance(PicoContainer container) throws PicoCompositionException {
060        return getComponentInstance(container, NOTHING.class);
061    }
062
063    public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException {
064        return (T) delegate.getComponentInstance(container, into);
065    }
066
067    public void verify(PicoContainer container) throws PicoCompositionException {
068        delegate.verify(container);
069    }
070
071    public final ComponentAdapter<T> getDelegate() {
072        return delegate;
073    }
074
075    @SuppressWarnings("unchecked")
076    public final <U extends ComponentAdapter> U findAdapterOfType(Class<U> adapterType) {
077        if (adapterType.isAssignableFrom(this.getClass())) {
078            return (U) this;
079        } else {
080            return delegate.findAdapterOfType(adapterType);
081        }
082    }
083
084    public void accept(PicoVisitor visitor) {
085        visitor.visitComponentAdapter(this);
086        delegate.accept(visitor);
087    }
088
089    /**
090     * Delegates change of monitor if the delegate supports 
091     * a component monitor strategy.
092     * {@inheritDoc}
093     */
094    public void changeMonitor(ComponentMonitor monitor) {
095        if (delegate instanceof ComponentMonitorStrategy ) {
096            ((ComponentMonitorStrategy)delegate).changeMonitor(monitor);
097        }
098    }
099
100    /**
101     * Returns delegate's current monitor if the delegate supports 
102     * a component monitor strategy.
103     * {@inheritDoc}
104     * @throws PicoCompositionException if no component monitor is found in delegate
105     */
106    public ComponentMonitor currentMonitor() {
107        if (delegate instanceof ComponentMonitorStrategy ) {
108            return ((ComponentMonitorStrategy)delegate).currentMonitor();
109        }
110        throw new PicoCompositionException("No component monitor found in delegate");
111    }
112
113    /**
114     * Invokes delegate start method if the delegate is a Behavior
115     * {@inheritDoc}
116     */
117    public void start(PicoContainer container) {
118        if (delegate instanceof org.picocontainer.Behavior) {
119            ((org.picocontainer.Behavior<?>)delegate).start(container);
120        }
121    }
122
123    /**
124     * Invokes delegate stop method if the delegate is a Behavior
125     * {@inheritDoc}
126     */
127    public void stop(PicoContainer container) {
128        if (delegate instanceof org.picocontainer.Behavior) {
129            ((org.picocontainer.Behavior<?>)delegate).stop(container);
130        }
131    }
132    
133    /**
134     * Invokes delegate dispose method if the delegate is a Behavior
135     * {@inheritDoc}
136     */
137    public void dispose(PicoContainer container) {
138        if (delegate instanceof org.picocontainer.Behavior) {
139            ((org.picocontainer.Behavior<?>)delegate).dispose(container);
140        }
141    }
142
143    /**
144     * Invokes delegate hasLifecycle method if the delegate is a Behavior
145     * {@inheritDoc}
146     */
147    public boolean componentHasLifecycle() {
148        if (delegate instanceof org.picocontainer.Behavior) {
149            return ((org.picocontainer.Behavior<?>)delegate).componentHasLifecycle();
150        }
151        return false;
152    }
153
154    public boolean isStarted() {
155        if (delegate instanceof org.picocontainer.Behavior) {
156            return ((org.picocontainer.Behavior<?>)delegate).isStarted();
157        }
158        return false;
159    }
160
161// ~~~~~~~~ LifecycleStrategy ~~~~~~~~
162
163    /**
164     * Invokes delegate start method if the delegate is a LifecycleStrategy
165     * {@inheritDoc}
166     */
167    public void start(Object component) {
168        if (delegate instanceof LifecycleStrategy ) {
169            ((LifecycleStrategy)delegate).start(component);
170        }
171    }
172
173    /**
174     * Invokes delegate stop method if the delegate is a LifecycleStrategy
175     * {@inheritDoc}
176     */
177    public void stop(Object component) {
178        if (delegate instanceof LifecycleStrategy ) {
179            ((LifecycleStrategy)delegate).stop(component);
180        }
181    }
182
183    /**
184     * Invokes delegate dispose method if the delegate is a LifecycleStrategy
185     * {@inheritDoc}
186     */
187    public void dispose(Object component) {
188        if (delegate instanceof LifecycleStrategy ) {
189            ((LifecycleStrategy)delegate).dispose(component);
190        }
191    }
192
193    /**
194     * Invokes delegate hasLifecycle(Class) method if the delegate is a LifecycleStrategy
195     * {@inheritDoc}
196     */
197    public boolean hasLifecycle(Class<?> type) {
198        return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).hasLifecycle(type);
199    }
200
201    public boolean isLazy(ComponentAdapter<?> adapter) {
202        return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).isLazy(adapter);
203    }
204
205    public String toString() {
206        return getDescriptor() + ":" + delegate.toString();
207    }
208}
209