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                                                          *
009     *****************************************************************************/
010    package org.picocontainer.adapters;
011    
012    import org.picocontainer.ComponentMonitor;
013    import org.picocontainer.PicoVisitor;
014    import org.picocontainer.ComponentAdapter;
015    import org.picocontainer.ComponentMonitorStrategy;
016    import org.picocontainer.monitors.AbstractComponentMonitor;
017    import org.picocontainer.monitors.NullComponentMonitor;
018    
019    import java.io.Serializable;
020    
021    /**
022     * Base class for a ComponentAdapter with general functionality.
023     * This implementation provides basic checks for a healthy implementation of a ComponentAdapter.
024     * It does not allow to use <code>null</code> for the component key or the implementation,
025     * ensures that the implementation is a concrete class and that the key is assignable from the
026     * implementation if the key represents a type.
027     *
028     * @author Paul Hammant
029     * @author Aslak Helles&oslash;y
030     * @author Jon Tirs&eacute;n
031     */
032    public abstract class AbstractAdapter implements ComponentAdapter, ComponentMonitorStrategy, Serializable {
033        private Object componentKey;
034        private Class componentImplementation;
035        private ComponentMonitor componentMonitor;
036    
037    
038        /**
039         * Constructs a new ComponentAdapter for the given key and implementation.
040         * @param componentKey the search key for this implementation
041         * @param componentImplementation the concrete implementation
042         */
043        public AbstractAdapter(Object componentKey, Class componentImplementation) {
044            this(componentKey, componentImplementation, new AbstractComponentMonitor());
045            this.componentMonitor = new NullComponentMonitor();
046        }
047    
048        /**
049         * Constructs a new ComponentAdapter for the given key and implementation.
050         * @param componentKey the search key for this implementation
051         * @param componentImplementation the concrete implementation
052         * @param monitor the component monitor used by this ComponentAdapter
053         */
054        public AbstractAdapter(Object componentKey, Class componentImplementation, ComponentMonitor monitor) {
055            if (monitor == null) {
056                throw new NullPointerException("ComponentMonitor==null");
057            }
058            this.componentMonitor = monitor;
059            if (componentImplementation == null) {
060                throw new NullPointerException("componentImplementation");
061            }
062            this.componentKey = componentKey;
063            this.componentImplementation = componentImplementation;
064            checkTypeCompatibility();
065        }
066    
067        /**
068         * {@inheritDoc}
069         * @see org.picocontainer.ComponentAdapter#getComponentKey()
070         */
071        public Object getComponentKey() {
072            if (componentKey == null) {
073                throw new NullPointerException("componentKey");
074            }
075            return componentKey;
076        }
077    
078        /**
079         * {@inheritDoc}
080         * @see org.picocontainer.ComponentAdapter#getComponentImplementation()
081         */
082        public Class getComponentImplementation() {
083            return componentImplementation;
084        }
085    
086        protected void checkTypeCompatibility() {
087            if (componentKey instanceof Class) {
088                Class componentType = (Class) componentKey;
089                if (!componentType.isAssignableFrom(componentImplementation)) {
090                    throw new ClassCastException(componentImplementation.getName() + " is not a " + componentType.getName());
091                }
092            }
093        }
094    
095        /**
096         * @return Returns the ComponentAdapter's class name and the component's key.
097         * @see java.lang.Object#toString()
098         */
099        public String toString() {
100            return "" + getComponentKey();
101        }
102    
103        public void accept(PicoVisitor visitor) {
104            visitor.visitComponentAdapter(this);
105        }
106    
107        public void changeMonitor(ComponentMonitor monitor) {
108            this.componentMonitor = monitor;
109        }
110    
111        /**
112         * Returns the monitor currently used
113         * @return The ComponentMonitor currently used
114         */
115        public ComponentMonitor currentMonitor(){
116            return componentMonitor;
117        }
118    
119        public final ComponentAdapter getDelegate() {
120            return null;
121        }
122    
123        public final ComponentAdapter findAdapterOfType(Class componentAdapterType) {
124            return null;
125        }
126    }