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    
015    import org.picocontainer.ComponentAdapter;
016    import org.picocontainer.ComponentMonitor;
017    import org.picocontainer.Behavior;
018    import org.picocontainer.PicoContainer;
019    import org.picocontainer.PicoCompositionException;
020    import org.picocontainer.PicoVisitor;
021    import org.picocontainer.ComponentMonitorStrategy;
022    import org.picocontainer.LifecycleStrategy;
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     */
042    public abstract class AbstractBehavior<T> implements 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<T> getComponentImplementation() {
056            return delegate.getComponentImplementation();
057        }
058    
059        public T getComponentInstance(PicoContainer container) throws PicoCompositionException {
060            return (T) delegate.getComponentInstance(container);
061        }
062    
063        public void verify(PicoContainer container) throws PicoCompositionException {
064            delegate.verify(container);
065        }
066    
067        public final ComponentAdapter<T> getDelegate() {
068            return delegate;
069        }
070    
071        public final <U extends ComponentAdapter> U findAdapterOfType(Class<U> componentAdapterType) {
072            if (componentAdapterType.isAssignableFrom(this.getClass())) {
073                return (U) this;
074            } else if (componentAdapterType.isAssignableFrom(delegate.getClass())) {
075                return (U) delegate;
076            } else {
077                return delegate.findAdapterOfType(componentAdapterType);
078            }
079        }
080    
081        public void accept(PicoVisitor visitor) {
082            visitor.visitComponentAdapter(this);
083            delegate.accept(visitor);
084        }
085    
086        /**
087         * Delegates change of monitor if the delegate supports 
088         * a component monitor strategy.
089         * {@inheritDoc}
090         */
091        public void changeMonitor(ComponentMonitor monitor) {
092            if ( delegate instanceof ComponentMonitorStrategy ){
093                ((ComponentMonitorStrategy)delegate).changeMonitor(monitor);
094            }
095        }
096    
097        /**
098         * Returns delegate's current monitor if the delegate supports 
099         * a component monitor strategy.
100         * {@inheritDoc}
101         * @throws PicoCompositionException if no component monitor is found in delegate
102         */
103        public ComponentMonitor currentMonitor() {
104            if ( delegate instanceof ComponentMonitorStrategy ){
105                return ((ComponentMonitorStrategy)delegate).currentMonitor();
106            }
107            throw new PicoCompositionException("No component monitor found in delegate");
108        }
109    
110        /**
111         * Invokes delegate start method if the delegate is a Behavior
112         * {@inheritDoc}
113         */
114        public void start(PicoContainer container) {
115            if ( delegate instanceof Behavior){
116                ((Behavior<?>)delegate).start(container);
117            }
118        }
119    
120        /**
121         * Invokes delegate stop method if the delegate is a Behavior
122         * {@inheritDoc}
123         */
124        public void stop(PicoContainer container) {
125            if ( delegate instanceof Behavior){
126                ((Behavior<?>)delegate).stop(container);
127            }
128        }
129        
130        /**
131         * Invokes delegate dispose method if the delegate is a Behavior
132         * {@inheritDoc}
133         */
134        public void dispose(PicoContainer container) {
135            if ( delegate instanceof Behavior){
136                ((Behavior<?>)delegate).dispose(container);
137            }
138        }
139    
140        /**
141         * Invokes delegate hasLifecycle method if the delegate is a Behavior
142         * {@inheritDoc}
143         */
144        public boolean componentHasLifecycle() {
145            if (delegate instanceof Behavior){
146                return ((Behavior<?>)delegate).componentHasLifecycle();
147            }
148            return false;
149        }
150    
151        // ~~~~~~~~ LifecycleStrategy ~~~~~~~~
152    
153        /**
154         * Invokes delegate start method if the delegate is a LifecycleStrategy
155         * {@inheritDoc}
156         */
157        public void start(Object component) {
158            if ( delegate instanceof LifecycleStrategy ){
159                ((LifecycleStrategy)delegate).start(component);
160            }
161        }
162    
163        /**
164         * Invokes delegate stop method if the delegate is a LifecycleStrategy
165         * {@inheritDoc}
166         */
167        public void stop(Object component) {
168            if ( delegate instanceof LifecycleStrategy ){
169                ((LifecycleStrategy)delegate).stop(component);
170            }
171        }
172    
173        /**
174         * Invokes delegate dispose method if the delegate is a LifecycleStrategy
175         * {@inheritDoc}
176         */
177        public void dispose(Object component) {
178            if ( delegate instanceof LifecycleStrategy ){
179                ((LifecycleStrategy)delegate).dispose(component);
180            }
181        }
182    
183        /**
184         * Invokes delegate hasLifecycle(Class) method if the delegate is a LifecycleStrategy
185         * {@inheritDoc}
186         */
187        public boolean hasLifecycle(Class type) {
188            return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).hasLifecycle(type);
189        }
190    
191        public String toString() {
192            return delegate.toString();
193        }
194    }
195