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 *****************************************************************************/
009package org.picocontainer.injectors;
010
011import org.picocontainer.ComponentAdapter;
012import org.picocontainer.ComponentMonitor;
013import org.picocontainer.Parameter;
014
015import java.lang.annotation.Annotation;
016import java.util.Arrays;
017import java.util.HashSet;
018
019/**
020 * convenience class providing static methods to conveniently create injectors
021 * ( like org.junit.Assert )
022 *
023 * @author Konstantin Pribluda
024 */
025public class Injector {
026    /**
027     * Constructor injector that uses no monitor and no lifecycle adapter.  This is a more
028     * convenient constructor for use when instantiating a constructor injector directly.
029     *
030     * @param componentKey            the search key for this implementation
031     * @param componentImplementation the concrete implementation
032     * @param parameters              the parameters used for initialization
033     */
034
035    public static ComponentAdapter constructor(final Object componentKey, final Class<?> componentImplementation, Parameter... parameters) {
036        return new ConstructorInjector(componentKey, componentImplementation, parameters);
037    }
038
039    /**
040     * Creates a ConstructorInjector
041     *
042     * @param componentKey            the search key for this implementation
043     * @param componentImplementation the concrete implementation
044     * @param parameters              the parameters to use for the initialization
045     * @param monitor                 the component monitor used by this addAdapter
046     * @param useNames                use argument names when looking up dependencies
047     * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException
048     *                              if the implementation is not a concrete class.
049     * @throws NullPointerException if one of the parameters is <code>null</code>
050     */
051    public static ComponentAdapter constructor(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor,
052                                               boolean useNames) throws AbstractInjector.NotConcreteRegistrationException {
053        return new ConstructorInjector(componentKey, componentImplementation, parameters, monitor, useNames);
054    }
055
056    /**
057     * Creates a ConstructorInjector
058     *
059     * @param componentKey            the search key for this implementation
060     * @param componentImplementation the concrete implementation
061     * @param parameters              the parameters to use for the initialization
062     * @param monitor                 the component monitor used by this addAdapter
063     * @param useNames                use argument names when looking up dependencies
064     * @param rememberChosenCtor      remember the chosen constructor (to speed up second/subsequent calls)
065     * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException
066     *                              if the implementation is not a concrete class.
067     * @throws NullPointerException if one of the parameters is <code>null</code>
068     */
069    public static ComponentAdapter constructor(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor,
070                                              boolean useNames, boolean rememberChosenCtor) throws AbstractInjector.NotConcreteRegistrationException {
071        return new ConstructorInjector(componentKey, componentImplementation, parameters, monitor,
072                useNames, rememberChosenCtor);
073    }
074
075    /**
076     * Convenience method to create annotated field injector
077     *
078     * @param key
079     * @param impl
080     * @param parameters
081     * @param componentMonitor
082     * @param injectionAnnotation
083     * @param useNames
084     * @return annotated field injector instance.
085     */
086    public static ComponentAdapter annotatedField(Object key,
087                                                  Class<?> impl,
088                                                  Parameter[] parameters,
089                                                  ComponentMonitor componentMonitor,
090                                                  Class<? extends Annotation> injectionAnnotation, boolean useNames) {
091        return componentMonitor.newInjector(new AnnotatedFieldInjector(key, impl, parameters, componentMonitor, injectionAnnotation, useNames));
092    }
093
094    /**
095     * convenience method to create annotated method injector
096     *
097     * @param key
098     * @param impl
099     * @param parameters
100     * @param monitor
101     * @param injectionAnnotation
102     * @param useNames
103     * @return method injector instance.
104     */
105    public static ComponentAdapter annotatedMethod(Object key,
106                                                   Class<?> impl,
107                                                   Parameter[] parameters,
108                                                   ComponentMonitor monitor,
109                                                   Class<? extends Annotation> injectionAnnotation, boolean useNames) {
110        return monitor.newInjector(new AnnotatedMethodInjector(key, impl, parameters, monitor, injectionAnnotation, useNames));
111
112    }
113
114
115    /**
116     * creates composite injector
117     *
118     * @param componentKey
119     * @param componentImplementation
120     * @param parameters
121     * @param monitor
122     * @param useNames
123     * @param injectors
124     * @return composite injector instance.
125     */
126    public static ComponentAdapter composite(Object componentKey, Class<?> componentImplementation, Parameter[] parameters, ComponentMonitor monitor,
127                                             boolean useNames, org.picocontainer.Injector... injectors) {
128        return monitor.newInjector(new CompositeInjector(componentKey, componentImplementation, parameters, monitor, useNames, injectors));
129    }
130
131
132    /**
133     * convenience method to create method injector
134     *
135     * @param componentKey
136     * @param componentImplementation
137     * @param parameters
138     * @param monitor
139     * @param methodName
140     * @param useNames
141     * @return method injector instance.
142     * @throws AbstractInjector.NotConcreteRegistrationException
143     *
144     */
145    public static ComponentAdapter method(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor,
146                                          String methodName, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException {
147        return monitor.newInjector(new MethodInjector.ByMethodName(componentKey, componentImplementation, parameters, monitor, new HashSet<String>(Arrays.asList(methodName)), useNames));
148    }
149
150    /**
151     * convenience method to create multi component adapter
152     *
153     * @param componentKey
154     * @param componentImplementation
155     * @param parameters
156     * @param componentMonitor
157     * @param setterPrefix
158     * @param useNames
159     * @return MultiInjector component adapter instance.
160     */
161
162    public static ComponentAdapter multi(Object componentKey,
163                                         Class componentImplementation,
164                                         Parameter[] parameters,
165                                         ComponentMonitor componentMonitor, String setterPrefix, boolean useNames) {
166        return componentMonitor.newInjector(new MultiInjector(componentKey, componentImplementation, parameters, componentMonitor, setterPrefix, useNames));
167    }
168
169    /**
170     * convenience method to create named field injector
171     *
172     * @param key
173     * @param impl
174     * @param parameters
175     * @param componentMonitor
176     * @param fieldNames
177     * @return named field component injector instance.
178     */
179    public static ComponentAdapter namedField(Object key,
180                                              Class<?> impl,
181                                              Parameter[] parameters,
182                                              ComponentMonitor componentMonitor,
183                                              String fieldNames) {
184        return componentMonitor.newInjector(new NamedFieldInjector(key, impl, parameters, componentMonitor, fieldNames));
185    }
186
187    /**
188     * convenience method to create setter injector
189     *
190     * @param componentKey
191     * @param componentImplementation
192     * @param parameters
193     * @param monitor
194     * @param prefix
195     * @param useNames
196     * @return setter injector instance.
197     * @throws AbstractInjector.NotConcreteRegistrationException
198     *
199     */
200    public static ComponentAdapter setter(final Object componentKey,
201                                          final Class componentImplementation,
202                                          Parameter[] parameters,
203                                          ComponentMonitor monitor,
204                                          String prefix, boolean useNames) throws AbstractInjector.NotConcreteRegistrationException {
205        return monitor.newInjector(new SetterInjector(componentKey, componentImplementation, parameters, monitor, prefix, "", false, useNames));
206    }
207
208    /**
209     * conveniently create typed field injector
210     *
211     * @param key
212     * @param impl
213     * @param parameters
214     * @param componentMonitor
215     * @param classNames
216     * @return typed field injector instance.
217     */
218    public static ComponentAdapter typedField(Object key,
219                                              Class<?> impl,
220                                              Parameter[] parameters,
221                                              ComponentMonitor componentMonitor,
222                                              String classNames) {
223        return componentMonitor.newInjector(new TypedFieldInjector(key, impl, parameters, componentMonitor, classNames));
224    }
225}