KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > util > ConstructorUtils


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.util;
16
17 import java.lang.reflect.Constructor JavaDoc;
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Modifier JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.hivemind.ApplicationRuntimeException;
26
27 /**
28  * Static methods for invoking constructors.
29  *
30  * @author Howard Lewis Ship
31  */

32 public class ConstructorUtils
33 {
34
35     /**
36      * Map from primitive type to wrapper type.
37      */

38     private static final Map JavaDoc _primitiveMap = new HashMap JavaDoc();
39
40     static
41     {
42         _primitiveMap.put(boolean.class, Boolean JavaDoc.class);
43         _primitiveMap.put(byte.class, Byte JavaDoc.class);
44         _primitiveMap.put(char.class, Character JavaDoc.class);
45         _primitiveMap.put(short.class, Short JavaDoc.class);
46         _primitiveMap.put(int.class, Integer JavaDoc.class);
47         _primitiveMap.put(long.class, Long JavaDoc.class);
48         _primitiveMap.put(float.class, Float JavaDoc.class);
49         _primitiveMap.put(double.class, Double JavaDoc.class);
50     }
51
52     // Prevent instantiation
53

54     private ConstructorUtils()
55     {
56     }
57
58     /**
59      * Searches for a constructor matching against the provided arguments.
60      *
61      * @param targetClass
62      * the class to be instantiated
63      * @param parameters
64      * the parameters to pass to the constructor (may be null or empty)
65      * @return the new instance
66      * @throws ApplicationRuntimeException
67      * on any failure
68      */

69     public static Object JavaDoc invokeConstructor(Class JavaDoc targetClass, Object JavaDoc[] parameters)
70     {
71         if (parameters == null)
72             parameters = new Object JavaDoc[0];
73
74         Class JavaDoc[] parameterTypes = new Class JavaDoc[parameters.length];
75
76         for (int i = 0; i < parameters.length; i++)
77             parameterTypes[i] = parameters[i] == null ? null : parameters[i].getClass();
78
79         return invokeMatchingConstructor(targetClass, parameterTypes, parameters);
80     }
81
82     private static Object JavaDoc invokeMatchingConstructor(Class JavaDoc targetClass, Class JavaDoc[] parameterTypes,
83             Object JavaDoc[] parameters)
84     {
85         Constructor JavaDoc[] constructors = targetClass.getConstructors();
86
87         for (int i = 0; i < constructors.length; i++)
88         {
89             Constructor JavaDoc c = constructors[i];
90
91             if (isMatch(c, parameterTypes))
92                 return invoke(c, parameters);
93         }
94
95         throw new ApplicationRuntimeException(UtilMessages.noMatchingConstructor(targetClass), null);
96     }
97
98     private static boolean isMatch(Constructor JavaDoc c, Class JavaDoc[] types)
99     {
100         Class JavaDoc[] actualTypes = c.getParameterTypes();
101
102         if (actualTypes.length != types.length)
103             return false;
104
105         for (int i = 0; i < types.length; i++)
106         {
107             if (types[i] == null && !actualTypes[i].isPrimitive())
108                 continue;
109
110             if (!isCompatible(actualTypes[i], types[i]))
111                 return false;
112         }
113
114         return true;
115     }
116
117     public static boolean isCompatible(Class JavaDoc actualType, Class JavaDoc parameterType)
118     {
119         if (actualType.isAssignableFrom(parameterType))
120             return true;
121
122         // Reflection fudges the assignment of a wrapper class to a primitive
123
// type ... we check for that the hard way.
124

125         if (actualType.isPrimitive())
126         {
127             Class JavaDoc wrapperClass = (Class JavaDoc) _primitiveMap.get(actualType);
128
129             return wrapperClass.isAssignableFrom(parameterType);
130         }
131
132         return false;
133     }
134
135     public static Object JavaDoc invoke(Constructor JavaDoc c, Object JavaDoc[] parameters)
136     {
137         try
138         {
139             return c.newInstance(parameters);
140         }
141         catch (InvocationTargetException JavaDoc ex)
142         {
143             Throwable JavaDoc cause = ex.getTargetException();
144
145             throw new ApplicationRuntimeException(UtilMessages.invokeFailed(c, cause), null, cause);
146         }
147         catch (Exception JavaDoc ex)
148         {
149             throw new ApplicationRuntimeException(UtilMessages.invokeFailed(c, ex), null, ex);
150         }
151     }
152
153     public static List JavaDoc getConstructorsOfLength(final Class JavaDoc clazz, final int length)
154     {
155         List JavaDoc fixedLengthConstructors = new ArrayList JavaDoc(1);
156     
157         Constructor JavaDoc[] constructors = clazz.getDeclaredConstructors();
158     
159         for (int i = 0; i < constructors.length; i++)
160         {
161             if (!Modifier.isPublic(constructors[i].getModifiers()))
162                 continue;
163     
164             Class JavaDoc[] parameterTypes = constructors[i].getParameterTypes();
165     
166             if (parameterTypes.length == length)
167                 fixedLengthConstructors.add(constructors[i]);
168         }
169     
170         return fixedLengthConstructors;
171     }
172 }
Popular Tags