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 * Idea by Rachel Davies, Original code by Jon Tirsen * 009 *****************************************************************************/ 010 011 package org.picocontainer.parameters; 012 013 import org.picocontainer.ComponentAdapter; 014 import org.picocontainer.Parameter; 015 import org.picocontainer.PicoContainer; 016 import org.picocontainer.PicoException; 017 import org.picocontainer.PicoCompositionException; 018 import org.picocontainer.PicoVisitor; 019 import org.picocontainer.NameBinding; 020 021 import java.io.Serializable; 022 import java.lang.reflect.Field; 023 import java.lang.annotation.Annotation; 024 025 026 /** 027 * A ConstantParameter should be used to pass in "constant" arguments to constructors. This 028 * includes {@link String}s,{@link Integer}s or any other object that is not registered in 029 * the container. 030 * 031 * @author Jon Tirsén 032 * @author Aslak Hellesøy 033 * @author Jörg Schaible 034 * @author Thomas Heller 035 */ 036 @SuppressWarnings("serial") 037 public class ConstantParameter 038 implements Parameter, Serializable { 039 040 private final Object value; 041 042 public ConstantParameter(Object value) { 043 this.value = value; 044 } 045 046 public Object resolveInstance(PicoContainer container, 047 ComponentAdapter adapter, 048 Class expectedType, 049 NameBinding expectedNameBinding, 050 boolean useNames, Annotation binding) { 051 return value; 052 } 053 054 public boolean isResolvable(PicoContainer container, 055 ComponentAdapter adapter, 056 Class expectedType, 057 NameBinding expectedNameBinding, 058 boolean useNames, Annotation binding) { 059 try { 060 verify(container, adapter, expectedType, expectedNameBinding, useNames, binding); 061 return true; 062 } catch(final PicoCompositionException e) { 063 return false; 064 } 065 } 066 067 /** 068 * {@inheritDoc} 069 * 070 * @see Parameter#verify(PicoContainer, ComponentAdapter, Class, NameBinding ,boolean, Annotation) 071 */ 072 public void verify(PicoContainer container, 073 ComponentAdapter adapter, 074 Class expectedType, 075 NameBinding expectedNameBinding, 076 boolean useNames, Annotation binding) throws PicoException { 077 if (!checkPrimitive(expectedType) && !expectedType.isInstance(value)) { 078 throw new PicoCompositionException(expectedType.getClass().getName() + " is not assignable from " + 079 (value != null ? value.getClass().getName() : "null")); 080 } 081 } 082 083 /** 084 * Visit the current {@link Parameter}. 085 * 086 * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor) 087 */ 088 public void accept(final PicoVisitor visitor) { 089 visitor.visitParameter(this); 090 } 091 092 private boolean checkPrimitive(Class expectedType) { 093 try { 094 if (expectedType.isPrimitive()) { 095 final Field field = value.getClass().getField("TYPE"); 096 final Class type = (Class) field.get(value); 097 return expectedType.isAssignableFrom(type); 098 } 099 } catch (NoSuchFieldException e) { 100 //ignore 101 } catch (IllegalAccessException e) { 102 //ignore 103 } 104 return false; 105 } 106 107 }