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     *****************************************************************************/
009    package org.picocontainer.injectors;
010    
011    import org.picocontainer.ComponentAdapter;
012    import org.picocontainer.ComponentMonitor;
013    import org.picocontainer.Parameter;
014    
015    import java.lang.annotation.Annotation;
016    import java.util.Arrays;
017    import 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     */
025    public 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    }