1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.di.impl;
17
18 import net.sf.jguiraffe.di.Dependency;
19 import net.sf.jguiraffe.di.DependencyProvider;
20
21 /**
22 * <p>
23 * A class that represents a constructor invocation.
24 * </p>
25 * <p>
26 * Instances of this class can be used for creating objects by invoking
27 * constructors on their classes. For this purpose the parameters to be passed
28 * to the constructor must be specified, which is done in form of an array of
29 * {@link Dependency} objects. These dependencies can either refer to other
30 * beans (they will then be resolved by the dependency injection framework), or
31 * can contain constant values that will be directly passed to the constructor.
32 * If the constructor's signature is known, the types of its arguments can be
33 * defined. If this is not the case, the parameter types will be derived from
34 * the current parameter values. The
35 * {@link net.sf.jguiraffe.di.InvocationHelper InvocationHelper} class is used
36 * to find the correct constructor to be invoked.
37 * </p>
38 * <p>
39 * Objects of this class cannot be changed after they have been created. So they
40 * can be shared between multiple clients.
41 * </p>
42 *
43 * @author Oliver Heger
44 * @version $Id: ConstructorInvocation.java 205 2012-01-29 18:29:57Z oheger $
45 */
46 public class ConstructorInvocation extends Invocation implements Invokable
47 {
48 /**
49 * Constant for the constructor name, which is added to the string
50 * representation.
51 */
52 static final String CONSTR_NAME = ".<init>";
53
54 /**
55 * Creates a new instance of <code>ConstructorInvocation</code> and
56 * initializes it. Refer to the base class for a detailed explanation of the
57 * arguments.
58 *
59 * @param targetClass the class, on which the method is to be invoked (must
60 * not be <b>null</b>)
61 * @param paramTypes an array with the parameter types
62 * @param paramValues the current parameter values (defined as
63 * <code>Dependency</code> objects); this array must not contain <b>null</b>
64 * elements
65 * @throws IllegalArgumentException if the length of the parameter types
66 * array does not match the length of the parameter values array, or if the
67 * values array contains <b>null</b> elements, of if the target class is
68 * <b>null</b>
69 * @see Invocation#Invocation(Class, Class[], Dependency...)
70 */
71 public ConstructorInvocation(ClassDescription targetClass,
72 ClassDescription[] paramTypes, Dependency... paramValues)
73 {
74 super(targetClass, paramTypes, paramValues);
75 if (targetClass == null)
76 {
77 throw new IllegalArgumentException("Target class must not be null!");
78 }
79 }
80
81 /**
82 * Invokes the corresponding constructor on the specified target class and
83 * returns the newly created instance. The required dependencies are
84 * resolved using the given <code>DependencyProvider</code>.
85 *
86 * @param depProvider the dependency provider (must not be <b>null</b>)
87 * @return the newly created instance of the target class
88 * @throws net.sf.jguiraffe.di.InjectionException if an error occurs
89 * @throws IllegalArgumentException if the dependency provider is <b>null</b>
90 */
91 public Object invoke(DependencyProvider depProvider)
92 {
93 Object[] values = getResolvedParameters(depProvider);
94 return depProvider.getInvocationHelper().invokeConstructor(
95 getTargetClass().getTargetClass(depProvider),
96 getParameterClasses(depProvider), values);
97 }
98
99 /**
100 * Performs the invocation. This method is required by the {@link Invokable}
101 * interface. It delegates to the method with the same name, ignoring the
102 * <code>target</code> parameter (which is not needed for a constructor
103 * invocation).
104 *
105 * @param depProvider the dependency provider (must not be <b>null</b>)
106 * @param target the target of the invocation
107 * @return the result of the invocation
108 * @throws net.sf.jguiraffe.di.InjectionException if an error occurs
109 * @throws IllegalArgumentException if the dependency provider is
110 * <b>null</b>
111 */
112 public Object invoke(DependencyProvider depProvider, Object target)
113 {
114 return invoke(depProvider);
115 }
116
117 /**
118 * Adds additional information about this invocation to the string buffer.
119 * This implementation adds a name for the constructor.
120 *
121 * @param buf the target buffer
122 */
123 @Override
124 protected void invocationInfoToString(StringBuilder buf)
125 {
126 super.invocationInfoToString(buf);
127 buf.append(CONSTR_NAME);
128 }
129 }