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