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.defaults; 011 012 import org.picocontainer.ComponentMonitor; 013 import org.picocontainer.PicoVisitor; 014 015 /** 016 * Base class for a ComponentAdapter with general functionality. 017 * This implementation provides basic checks for a healthy implementation of a ComponentAdapter. 018 * It does not allow to use <code>null</code> for the component key or the implementation, 019 * ensures that the implementation is a concrete class and that the key is assignable from the 020 * implementation if the key represents a type. 021 * 022 * @author Paul Hammant 023 * @author Aslak Hellesøy 024 * @author Jon Tirsén 025 * @version $Revision: 2654 $ 026 * @since 1.0 027 */ 028 public abstract class AbstractComponentAdapter extends MonitoringComponentAdapter { 029 private Object componentKey; 030 private Class componentImplementation; 031 032 /** 033 * Constructs a new ComponentAdapter for the given key and implementation. 034 * @param componentKey the search key for this implementation 035 * @param componentImplementation the concrete implementation 036 * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to. 037 */ 038 protected AbstractComponentAdapter(Object componentKey, Class componentImplementation) throws AssignabilityRegistrationException { 039 this(componentKey, componentImplementation, new DelegatingComponentMonitor()); 040 } 041 042 /** 043 * Constructs a new ComponentAdapter for the given key and implementation. 044 * @param componentKey the search key for this implementation 045 * @param componentImplementation the concrete implementation 046 * @param monitor the component monitor used by this ComponentAdapter 047 * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to. 048 */ 049 protected AbstractComponentAdapter(Object componentKey, Class componentImplementation, ComponentMonitor monitor) throws AssignabilityRegistrationException { 050 super(monitor); 051 if (componentImplementation == null) { 052 throw new NullPointerException("componentImplementation"); 053 } 054 this.componentKey = componentKey; 055 this.componentImplementation = componentImplementation; 056 checkTypeCompatibility(); 057 } 058 059 /** 060 * {@inheritDoc} 061 * @see org.picocontainer.ComponentAdapter#getComponentKey() 062 */ 063 public Object getComponentKey() { 064 if (componentKey == null) { 065 throw new NullPointerException("componentKey"); 066 } 067 return componentKey; 068 } 069 070 /** 071 * {@inheritDoc} 072 * @see org.picocontainer.ComponentAdapter#getComponentImplementation() 073 */ 074 public Class getComponentImplementation() { 075 return componentImplementation; 076 } 077 078 protected void checkTypeCompatibility() throws AssignabilityRegistrationException { 079 if (componentKey instanceof Class) { 080 Class componentType = (Class) componentKey; 081 if (!componentType.isAssignableFrom(componentImplementation)) { 082 throw new AssignabilityRegistrationException(componentType, componentImplementation); 083 } 084 } 085 } 086 087 /** 088 * @return Returns the ComponentAdapter's class name and the component's key. 089 * @see java.lang.Object#toString() 090 */ 091 public String toString() { 092 return getClass().getName() + "[" + getComponentKey() + "]"; 093 } 094 095 public void accept(PicoVisitor visitor) { 096 visitor.visitComponentAdapter(this); 097 } 098 099 }