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;
012    
013    import org.picocontainer.parameters.ComponentParameter;
014    import org.picocontainer.parameters.DefaultConstructorParameter;
015    
016    import java.lang.annotation.Annotation;
017    import java.lang.reflect.Type;
018    
019    /**
020     * This class provides control over the arguments that will be passed to a constructor. It can be used for finer control over
021     * what arguments are passed to a particular constructor.
022     *
023     * @author Jon Tirsén
024     * @author Aslak Hellesøy
025     * @author Thomas Heller
026     * @see MutablePicoContainer#addComponent(Object,Object,Parameter[]) a method on the
027     *      {@link MutablePicoContainer} interface which allows passing in of an array of {@linkplain Parameter Parameters}.
028     * @see org.picocontainer.parameters.ComponentParameter an implementation of this interface that allows you to specify the key
029     *      used for resolving the parameter.
030     * @see org.picocontainer.parameters.ConstantParameter an implementation of this interface that allows you to specify a constant
031     *      that will be used for resolving the parameter.
032     */
033    public interface Parameter {
034    
035            /**
036             * Zero parameter is used when you wish a component to be instantiated with its default constructor.  Ex:
037             * <div class="source">
038             *      <pre>
039             *              MutablePicoContainer mpc = new PicoBuilder().build();
040             *              mpc.addComponent(Map.class, HashMap.class, Parameter.ZERO);
041             *              mpc.addComponent(List.class, ArrayList.class, Parameter.ZERO);
042             *      </pre>
043             * </div>
044             * <p>By specifying the default constructor in this example code, you allow PicoContainer to recognize
045             * that HashMap(Collection) should <em>not</em> be used and avoid a CircularDependencyException.</p>
046             */
047        Parameter[] ZERO =  new Parameter[] {DefaultConstructorParameter.INSTANCE};
048        
049        Parameter[] DEFAULT = new Parameter[]{ ComponentParameter.DEFAULT };
050        
051        
052        /**
053         * Check if the Parameter can satisfy the expected type using the container.
054         *
055         * @param container             the container from which dependencies are resolved.
056         * @param forAdapter            the {@link org.picocontainer.ComponentAdapter} that is asking for the instance
057         * @param injecteeAdapter       the adapter to be injected into (null for N/A)
058         * @param expectedType          the required type
059         * @param expectedNameBinding Expected parameter name
060         * @param useNames              should use parameter names for disambiguation
061         * @param binding @return <code>true</code> if the component parameter can be resolved.
062         * @since 2.8.1
063         *
064         */
065        Resolver resolve(PicoContainer container, ComponentAdapter<?> forAdapter,
066                         ComponentAdapter<?> injecteeAdapter, Type expectedType, NameBinding expectedNameBinding,
067                         boolean useNames, Annotation binding);
068    
069        /**
070         * Verify that the Parameter can satisfy the expected type using the container
071         *
072         * @param container             the container from which dependencies are resolved.
073         * @param adapter               the {@link ComponentAdapter} that is asking for the verification
074         * @param expectedType          the required type
075         * @param expectedNameBinding Expected parameter name
076         *
077         * @param useNames
078         * @param binding
079         * @throws PicoCompositionException if parameter and its dependencies cannot be resolved
080         */
081        void verify(PicoContainer container, ComponentAdapter<?> adapter,
082                    Type expectedType, NameBinding expectedNameBinding,
083                    boolean useNames, Annotation binding);
084    
085        /**
086         * Accepts a visitor for this Parameter. The method is normally called by visiting a {@link ComponentAdapter}, that
087         * cascades the {@linkplain PicoVisitor visitor} also down to all its {@linkplain Parameter Parameters}.
088         *
089         * @param visitor the visitor.
090         *
091         */
092        void accept(PicoVisitor visitor);
093    
094    
095        @Deprecated
096        Object resolveInstance(PicoContainer container, ComponentAdapter<?> forAdapter,
097                               Type expectedType, NameBinding expectedNameBinding,
098                               boolean useNames, Annotation binding);
099    
100        @Deprecated
101        boolean isResolvable(PicoContainer container, ComponentAdapter<?> forAdapter,
102                             Type expectedType, NameBinding expectedNameBinding,
103                             boolean useNames, Annotation binding);
104    
105        /**
106         * Resolver is used transitarily during resolving of Parameters.
107         * isResolvable() and resolveInstance() in series do not cause resolveAdapter() twice
108         */
109        public static interface Resolver {
110    
111            /**
112             * @return can the parameter be resolved
113             */
114            public boolean isResolved();
115    
116            /**
117             * @return the instance to be used to inject as a parameter
118             */
119            public Object resolveInstance();
120    
121            /**
122             * @return the ComponentAdapter for the parameter in question
123             */
124            public ComponentAdapter<?> getComponentAdapter();
125    
126        }
127    
128        /**
129         * The Parameter cannot (ever) be resolved
130         */
131        public static class NotResolved implements Resolver {
132            public boolean isResolved() {
133                return false;
134            }
135    
136            public Object resolveInstance() {
137                return null;
138            }
139    
140            public ComponentAdapter<?> getComponentAdapter() {
141                return null;
142            }
143        }
144    
145        /**
146         * Delegate to another reolver
147         */
148        public abstract static class DelegateResolver implements Resolver {
149            private final Resolver delegate;
150    
151            public DelegateResolver(Resolver delegate) {
152                this.delegate = delegate;
153            }
154    
155            public boolean isResolved() {
156                return delegate.isResolved();
157            }
158    
159            public Object resolveInstance() {
160                return delegate.resolveInstance();
161            }
162    
163            public ComponentAdapter<?> getComponentAdapter() {
164                return delegate.getComponentAdapter();
165            }
166        }
167    
168        /**
169         * A fixed value wrapped as a Resolver
170         */
171        public static class ValueResolver implements Resolver {
172    
173            private final boolean resolvable;
174            private final Object value;
175            private final ComponentAdapter<?> adapter;
176    
177            public ValueResolver(boolean resolvable, Object value, ComponentAdapter<?> adapter) {
178                this.resolvable = resolvable;
179                this.value = value;
180                this.adapter = adapter;
181            }
182    
183            public boolean isResolved() {
184                return resolvable;
185            }
186    
187            public Object resolveInstance() {
188                return value;
189            }
190    
191            public ComponentAdapter<?> getComponentAdapter() {
192                return adapter;
193            }
194        }
195    
196    }