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