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