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