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øy
032 * @author Jon Tirsé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 }