1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 package org.apache.tools.ant.util;
19
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import org.apache.tools.ant.BuildException;
24 import java.lang.reflect.Field;
25
26 /**
27 * Utility class to handle reflection on java objects.
28 * The class contains static methods to call reflection
29 * methods, catch any exceptions, converting them
30 * to BuildExceptions.
31 */
32 // CheckStyle:FinalClassCheck OFF - backward compatible
33 public class ReflectUtil {
34
35 /** private constructor */
36 private ReflectUtil() {
37 }
38
39 /**
40 * Create an instance of a class using the constructor matching
41 * the given arguments.
42 * @since Ant 1.8.0
43 */
44 public static Object newInstance(Class ofClass,
45 Class[] argTypes,
46 Object[] args) {
47 try {
48 Constructor con = ofClass.getConstructor(argTypes);
49 return con.newInstance(args);
50 } catch (Exception t) {
51 throwBuildException(t);
52 return null; // NotReached
53 }
54 }
55
56 /**
57 * Call a method on the object with no parameters.
58 * @param obj the object to invoke the method on.
59 * @param methodName the name of the method to call
60 * @return the object returned by the method
61 */
62 public static Object invoke(Object obj, String methodName) {
63 try {
64 Method method;
65 method = obj.getClass().getMethod(
66 methodName, (Class[]) null);
67 return method.invoke(obj, (Object[]) null);
68 } catch (Exception t) {
69 throwBuildException(t);
70 return null; // NotReached
71 }
72 }
73
74 /**
75 * Call a method on the object with no parameters.
76 * Note: Unlike the invoke method above, this
77 * calls class or static methods, not instance methods.
78 * @param obj the object to invoke the method on.
79 * @param methodName the name of the method to call
80 * @return the object returned by the method
81 */
82 public static Object invokeStatic(Object obj, String methodName) {
83 try {
84 Method method;
85 method = ((Class) obj).getMethod(
86 methodName, (Class[]) null);
87 return method.invoke(obj, (Object[]) null);
88 } catch (Exception t) {
89 throwBuildException(t);
90 return null; // NotReached
91 }
92 }
93
94 /**
95 * Call a method on the object with one argument.
96 * @param obj the object to invoke the method on.
97 * @param methodName the name of the method to call
98 * @param argType the type of argument.
99 * @param arg the value of the argument.
100 * @return the object returned by the method
101 */
102 public static Object invoke(
103 Object obj, String methodName, Class argType, Object arg) {
104 try {
105 Method method;
106 method = obj.getClass().getMethod(
107 methodName, new Class[] {argType});
108 return method.invoke(obj, new Object[] {arg});
109 } catch (Exception t) {
110 throwBuildException(t);
111 return null; // NotReached
112 }
113 }
114
115 /**
116 * Call a method on the object with two argument.
117 * @param obj the object to invoke the method on.
118 * @param methodName the name of the method to call
119 * @param argType1 the type of the first argument.
120 * @param arg1 the value of the first argument.
121 * @param argType2 the type of the second argument.
122 * @param arg2 the value of the second argument.
123 * @return the object returned by the method
124 */
125 public static Object invoke(
126 Object obj, String methodName, Class argType1, Object arg1,
127 Class argType2, Object arg2) {
128 try {
129 Method method;
130 method = obj.getClass().getMethod(
131 methodName, new Class[] {argType1, argType2});
132 return method.invoke(obj, new Object[] {arg1, arg2});
133 } catch (Exception t) {
134 throwBuildException(t);
135 return null; // NotReached
136 }
137 }
138
139 /**
140 * Get the value of a field in an object.
141 * @param obj the object to look at.
142 * @param fieldName the name of the field in the object.
143 * @return the value of the field.
144 * @throws BuildException if there is an error.
145 */
146 public static Object getField(Object obj, String fieldName)
147 throws BuildException {
148 try {
149 Field field = obj.getClass().getDeclaredField(fieldName);
150 field.setAccessible(true);
151 return field.get(obj);
152 } catch (Exception t) {
153 throwBuildException(t);
154 return null; // NotReached
155 }
156 }
157
158 /**
159 * A method to convert an invocationTargetException to
160 * a buildexception and throw it.
161 * @param t the invocation target exception.
162 * @throws BuildException the converted exception.
163 */
164 public static void throwBuildException(Exception t)
165 throws BuildException {
166 throw toBuildException(t);
167 }
168
169 /**
170 * A method to convert an invocationTargetException to
171 * a buildexception.
172 * @param t the invocation target exception.
173 * @return the converted exception.
174 * @since ant 1.7.1
175 */
176 public static BuildException toBuildException(Exception t) {
177 if (t instanceof InvocationTargetException) {
178 Throwable t2 = ((InvocationTargetException) t)
179 .getTargetException();
180 if (t2 instanceof BuildException) {
181 return (BuildException) t2;
182 }
183 return new BuildException(t2);
184 } else {
185 return new BuildException(t);
186 }
187 }
188
189 /**
190 * A method to test if an object responds to a given
191 * message (method call)
192 * @param o the object
193 * @param methodName the method to check for
194 * @return true if the object has the method.
195 * @throws BuildException if there is a problem.
196 */
197 public static boolean respondsTo(Object o, String methodName)
198 throws BuildException {
199 try {
200 Method[] methods = o.getClass().getMethods();
201 for (int i = 0; i < methods.length; i++) {
202 if (methods[i].getName().equals(methodName)) {
203 return true;
204 }
205 }
206 return false;
207 } catch (Exception t) {
208 throw toBuildException(t);
209 }
210 }
211 }