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: *****************************************************************************/package org.picocontainer.adapters;
010:
011: import org.picocontainer.ComponentMonitor;
012: import org.picocontainer.PicoVisitor;
013: import org.picocontainer.ComponentAdapter;
014: import org.picocontainer.ComponentMonitorStrategy;
015: import org.picocontainer.monitors.AbstractComponentMonitor;
016: import org.picocontainer.monitors.NullComponentMonitor;
017:
018: import java.io.Serializable;
019:
020: /**
021: * Base class for a ComponentAdapter with general functionality.
022: * This implementation provides basic checks for a healthy implementation of a ComponentAdapter.
023: * It does not allow to use <code>null</code> for the component key or the implementation,
024: * ensures that the implementation is a concrete class and that the key is assignable from the
025: * implementation if the key represents a type.
026: *
027: * @author Paul Hammant
028: * @author Aslak Hellesøy
029: * @author Jon Tirsén
030: */
031: public abstract class AbstractAdapter<T> implements
032: ComponentAdapter<T>, ComponentMonitorStrategy, Serializable {
033: private Object componentKey;
034: private Class<T> componentImplementation;
035: private ComponentMonitor componentMonitor;
036:
037: /**
038: * Constructs a new ComponentAdapter for the given key and implementation.
039: * @param componentKey the search key for this implementation
040: * @param componentImplementation the concrete implementation
041: */
042: public AbstractAdapter(Object componentKey,
043: Class componentImplementation) {
044: this (componentKey, componentImplementation,
045: new AbstractComponentMonitor());
046: this .componentMonitor = new NullComponentMonitor();
047: }
048:
049: /**
050: * Constructs a new ComponentAdapter for the given key and implementation.
051: * @param componentKey the search key for this implementation
052: * @param componentImplementation the concrete implementation
053: * @param monitor the component monitor used by this ComponentAdapter
054: */
055: public AbstractAdapter(Object componentKey,
056: 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
092: .isAssignableFrom(componentImplementation)) {
093: throw new ClassCastException(componentImplementation
094: .getName()
095: + " is not a " + componentType.getName());
096: }
097: }
098: }
099:
100: /**
101: * @return Returns the ComponentAdapter's class name and the component's key.
102: * @see java.lang.Object#toString()
103: */
104: public String toString() {
105: return getDescriptor() + getComponentKey();
106: }
107:
108: public void accept(PicoVisitor visitor) {
109: visitor.visitComponentAdapter(this );
110: }
111:
112: public void changeMonitor(ComponentMonitor monitor) {
113: this .componentMonitor = monitor;
114: }
115:
116: /**
117: * Returns the monitor currently used
118: * @return The ComponentMonitor currently used
119: */
120: public ComponentMonitor currentMonitor() {
121: return componentMonitor;
122: }
123:
124: public final ComponentAdapter<T> getDelegate() {
125: return null;
126: }
127:
128: public final <U extends ComponentAdapter> U findAdapterOfType(
129: Class<U> componentAdapterType) {
130: return null;
131: }
132:
133: }
|