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.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 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<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