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> adapterType) {
079            if (adapterType.isAssignableFrom(this.getClass())) {
080                return (U) this;
081            } else {
082                return delegate.findAdapterOfType(adapterType);
083            }
084        }
085    
086        public void accept(PicoVisitor visitor) {
087            visitor.visitComponentAdapter(this);
088            delegate.accept(visitor);
089        }
090    
091        /**
092         * Delegates change of monitor if the delegate supports 
093         * a component monitor strategy.
094         * {@inheritDoc}
095         */
096        public void changeMonitor(ComponentMonitor monitor) {
097            if ( delegate instanceof ComponentMonitorStrategy ){
098                ((ComponentMonitorStrategy)delegate).changeMonitor(monitor);
099            }
100        }
101    
102        /**
103         * Returns delegate's current monitor if the delegate supports 
104         * a component monitor strategy.
105         * {@inheritDoc}
106         * @throws PicoCompositionException if no component monitor is found in delegate
107         */
108        public ComponentMonitor currentMonitor() {
109            if ( delegate instanceof ComponentMonitorStrategy ){
110                return ((ComponentMonitorStrategy)delegate).currentMonitor();
111            }
112            throw new PicoCompositionException("No component monitor found in delegate");
113        }
114    
115        /**
116         * Invokes delegate start method if the delegate is a Behavior
117         * {@inheritDoc}
118         */
119        public void start(PicoContainer container) {
120            if ( delegate instanceof Behavior){
121                ((Behavior<?>)delegate).start(container);
122            }
123        }
124    
125        /**
126         * Invokes delegate stop method if the delegate is a Behavior
127         * {@inheritDoc}
128         */
129        public void stop(PicoContainer container) {
130            if ( delegate instanceof Behavior){
131                ((Behavior<?>)delegate).stop(container);
132            }
133        }
134        
135        /**
136         * Invokes delegate dispose method if the delegate is a Behavior
137         * {@inheritDoc}
138         */
139        public void dispose(PicoContainer container) {
140            if ( delegate instanceof Behavior){
141                ((Behavior<?>)delegate).dispose(container);
142            }
143        }
144    
145        /**
146         * Invokes delegate hasLifecycle method if the delegate is a Behavior
147         * {@inheritDoc}
148         */
149        public boolean componentHasLifecycle() {
150            if (delegate instanceof Behavior){
151                return ((Behavior<?>)delegate).componentHasLifecycle();
152            }
153            return false;
154        }
155    
156        public boolean isStarted() {
157            if (delegate instanceof Behavior){
158                return ((Behavior<?>)delegate).isStarted();
159            }
160            return false;
161        }
162    
163    // ~~~~~~~~ LifecycleStrategy ~~~~~~~~
164    
165        /**
166         * Invokes delegate start method if the delegate is a LifecycleStrategy
167         * {@inheritDoc}
168         */
169        public void start(Object component) {
170            if ( delegate instanceof LifecycleStrategy ){
171                ((LifecycleStrategy)delegate).start(component);
172            }
173        }
174    
175        /**
176         * Invokes delegate stop method if the delegate is a LifecycleStrategy
177         * {@inheritDoc}
178         */
179        public void stop(Object component) {
180            if ( delegate instanceof LifecycleStrategy ){
181                ((LifecycleStrategy)delegate).stop(component);
182            }
183        }
184    
185        /**
186         * Invokes delegate dispose method if the delegate is a LifecycleStrategy
187         * {@inheritDoc}
188         */
189        public void dispose(Object component) {
190            if ( delegate instanceof LifecycleStrategy ){
191                ((LifecycleStrategy)delegate).dispose(component);
192            }
193        }
194    
195        /**
196         * Invokes delegate hasLifecycle(Class) method if the delegate is a LifecycleStrategy
197         * {@inheritDoc}
198         */
199        public boolean hasLifecycle(Class<?> type) {
200            return delegate instanceof LifecycleStrategy && ((LifecycleStrategy) delegate).hasLifecycle(type);
201        }
202    
203        public String toString() {
204            return getDescriptor() + ":" + delegate.toString();
205        }
206    }
207