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