1
17 package org.apache.tomcat.util;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.Hashtable;
24
25 import org.apache.juli.logging.Log;
26 import org.apache.juli.logging.LogFactory;
27 import org.apache.tomcat.util.res.StringManager;
28 import org.apache.tomcat.util.security.PermissionCheck;
29
30
33 public final class IntrospectionUtils {
34
35 private static final Log log = LogFactory.getLog(IntrospectionUtils.class);
36 private static final StringManager sm = StringManager.getManager(IntrospectionUtils.class);
37
38
47 public static boolean setProperty(Object o, String name, String value) {
48 return setProperty(o,name,value,true);
49 }
50
51 @SuppressWarnings("null")
52 public static boolean setProperty(Object o, String name, String value,
53 boolean invokeSetProperty) {
54 if (log.isDebugEnabled())
55 log.debug("IntrospectionUtils: setProperty(" +
56 o.getClass() + " " + name + "=" + value + ")");
57
58 String setter = "set" + capitalize(name);
59
60 try {
61 Method methods[] = findMethods(o.getClass());
62 Method setPropertyMethodVoid = null;
63 Method setPropertyMethodBool = null;
64
65
66 for (int i = 0; i < methods.length; i++) {
67 Class<?> paramT[] = methods[i].getParameterTypes();
68 if (setter.equals(methods[i].getName()) && paramT.length == 1
69 && "java.lang.String".equals(paramT[0].getName())) {
70
71 methods[i].invoke(o, new Object[] { value });
72 return true;
73 }
74 }
75
76
77 for (int i = 0; i < methods.length; i++) {
78 boolean ok = true;
79 if (setter.equals(methods[i].getName())
80 && methods[i].getParameterTypes().length == 1) {
81
82
83 Class<?> paramType = methods[i].getParameterTypes()[0];
84 Object params[] = new Object[1];
85
86
87 if ("java.lang.Integer".equals(paramType.getName())
88 || "int".equals(paramType.getName())) {
89 try {
90 params[0] = Integer.valueOf(value);
91 } catch (NumberFormatException ex) {
92 ok = false;
93 }
94
95 }else if ("java.lang.Long".equals(paramType.getName())
96 || "long".equals(paramType.getName())) {
97 try {
98 params[0] = Long.valueOf(value);
99 } catch (NumberFormatException ex) {
100 ok = false;
101 }
102
103
104 } else if ("java.lang.Boolean".equals(paramType.getName())
105 || "boolean".equals(paramType.getName())) {
106 params[0] = Boolean.valueOf(value);
107
108
109 } else if ("java.net.InetAddress".equals(paramType
110 .getName())) {
111 try {
112 params[0] = InetAddress.getByName(value);
113 } catch (UnknownHostException exc) {
114 if (log.isDebugEnabled())
115 log.debug("IntrospectionUtils: Unable to resolve host name:" + value);
116 ok = false;
117 }
118
119
120 } else {
121 if (log.isDebugEnabled())
122 log.debug("IntrospectionUtils: Unknown type " +
123 paramType.getName());
124 }
125
126 if (ok) {
127 methods[i].invoke(o, params);
128 return true;
129 }
130 }
131
132
133 if ("setProperty".equals(methods[i].getName())) {
134 if (methods[i].getReturnType()==Boolean.TYPE){
135 setPropertyMethodBool = methods[i];
136 }else {
137 setPropertyMethodVoid = methods[i];
138 }
139
140 }
141 }
142
143
144 if (invokeSetProperty && (setPropertyMethodBool != null ||
145 setPropertyMethodVoid != null)) {
146 Object params[] = new Object[2];
147 params[0] = name;
148 params[1] = value;
149 if (setPropertyMethodBool != null) {
150 try {
151 return ((Boolean) setPropertyMethodBool.invoke(o,
152 params)).booleanValue();
153 }catch (IllegalArgumentException biae) {
154
155
156 if (setPropertyMethodVoid!=null) {
157 setPropertyMethodVoid.invoke(o, params);
158 return true;
159 }else {
160 throw biae;
161 }
162 }
163 } else {
164 setPropertyMethodVoid.invoke(o, params);
165 return true;
166 }
167 }
168
169 } catch (IllegalArgumentException | SecurityException | IllegalAccessException e) {
170 log.warn(sm.getString("introspectionUtils.setPropertyError", name, value, o.getClass()), e);
171 } catch (InvocationTargetException e) {
172 ExceptionUtils.handleThrowable(e.getCause());
173 log.warn(sm.getString("introspectionUtils.setPropertyError", name, value, o.getClass()), e);
174 }
175 return false;
176 }
177
178 public static Object getProperty(Object o, String name) {
179 String getter = "get" + capitalize(name);
180 String isGetter = "is" + capitalize(name);
181
182 try {
183 Method methods[] = findMethods(o.getClass());
184 Method getPropertyMethod = null;
185
186
187 for (int i = 0; i < methods.length; i++) {
188 Class<?> paramT[] = methods[i].getParameterTypes();
189 if (getter.equals(methods[i].getName()) && paramT.length == 0) {
190 return methods[i].invoke(o, (Object[]) null);
191 }
192 if (isGetter.equals(methods[i].getName()) && paramT.length == 0) {
193 return methods[i].invoke(o, (Object[]) null);
194 }
195
196 if ("getProperty".equals(methods[i].getName())) {
197 getPropertyMethod = methods[i];
198 }
199 }
200
201
202 if (getPropertyMethod != null) {
203 Object params[] = new Object[1];
204 params[0] = name;
205 return getPropertyMethod.invoke(o, params);
206 }
207
208 } catch (IllegalArgumentException | SecurityException | IllegalAccessException e) {
209 log.warn(sm.getString("introspectionUtils.getPropertyError", name, o.getClass()), e);
210 } catch (InvocationTargetException e) {
211 if (e.getCause() instanceof NullPointerException) {
212
213 return null;
214 }
215 ExceptionUtils.handleThrowable(e.getCause());
216 log.warn(sm.getString("introspectionUtils.getPropertyError", name, o.getClass()), e);
217 }
218 return null;
219 }
220
221
229 @Deprecated
230 public static String replaceProperties(String value,
231 Hashtable<Object,Object> staticProp, PropertySource dynamicProp[]) {
232 return replaceProperties(value, staticProp, dynamicProp, null);
233 }
234
235
244 public static String replaceProperties(String value,
245 Hashtable<Object,Object> staticProp, PropertySource dynamicProp[],
246 ClassLoader classLoader) {
247
248 if (value.indexOf('$') < 0) {
249 return value;
250 }
251 StringBuilder sb = new StringBuilder();
252 int prev = 0;
253
254 int pos;
255 while ((pos = value.indexOf('$', prev)) >= 0) {
256 if (pos > 0) {
257 sb.append(value.substring(prev, pos));
258 }
259 if (pos == (value.length() - 1)) {
260 sb.append('$');
261 prev = pos + 1;
262 } else if (value.charAt(pos + 1) != '{') {
263 sb.append('$');
264 prev = pos + 1;
265 } else {
266 int endName = value.indexOf('}', pos);
267 if (endName < 0) {
268 sb.append(value.substring(pos));
269 prev = value.length();
270 continue;
271 }
272 String n = value.substring(pos + 2, endName);
273 String v = null;
274 if (staticProp != null) {
275 v = (String) staticProp.get(n);
276 }
277 if (v == null && dynamicProp != null) {
278 for (PropertySource propertySource : dynamicProp) {
279 if (propertySource instanceof SecurePropertySource) {
280 v = ((SecurePropertySource) propertySource).getProperty(n, classLoader);
281 } else {
282 v = propertySource.getProperty(n);
283 }
284 if (v != null) {
285 break;
286 }
287 }
288 }
289 if (v == null)
290 v = "${" + n + "}";
291
292 sb.append(v);
293 prev = endName + 1;
294 }
295 }
296 if (prev < value.length())
297 sb.append(value.substring(prev));
298 return sb.toString();
299 }
300
301
306 public static String capitalize(String name) {
307 if (name == null || name.length() == 0) {
308 return name;
309 }
310 char chars[] = name.toCharArray();
311 chars[0] = Character.toUpperCase(chars[0]);
312 return new String(chars);
313 }
314
315
316 public static void clear() {
317 objectMethods.clear();
318 }
319
320 private static final Hashtable<Class<?>,Method[]> objectMethods = new Hashtable<>();
321
322 public static Method[] findMethods(Class<?> c) {
323 Method methods[] = objectMethods.get(c);
324 if (methods != null)
325 return methods;
326
327 methods = c.getMethods();
328 objectMethods.put(c, methods);
329 return methods;
330 }
331
332 @SuppressWarnings("null")
333 public static Method findMethod(Class<?> c, String name,
334 Class<?> params[]) {
335 Method methods[] = findMethods(c);
336 for (int i = 0; i < methods.length; i++) {
337 if (methods[i].getName().equals(name)) {
338 Class<?> methodParams[] = methods[i].getParameterTypes();
339 if (params == null && methodParams.length == 0) {
340 return methods[i];
341 }
342 if (params.length != methodParams.length) {
343 continue;
344 }
345 boolean found = true;
346 for (int j = 0; j < params.length; j++) {
347 if (params[j] != methodParams[j]) {
348 found = false;
349 break;
350 }
351 }
352 if (found) {
353 return methods[i];
354 }
355 }
356 }
357 return null;
358 }
359
360 public static Object callMethod1(Object target, String methodN,
361 Object param1, String typeParam1, ClassLoader cl) throws Exception {
362 if (target == null || methodN == null || param1 == null) {
363 throw new IllegalArgumentException(sm.getString("introspectionUtils.nullParameter"));
364 }
365 if (log.isDebugEnabled())
366 log.debug("IntrospectionUtils: callMethod1 " +
367 target.getClass().getName() + " " +
368 param1.getClass().getName() + " " + typeParam1);
369
370 Class<?> params[] = new Class[1];
371 if (typeParam1 == null)
372 params[0] = param1.getClass();
373 else
374 params[0] = cl.loadClass(typeParam1);
375 Method m = findMethod(target.getClass(), methodN, params);
376 if (m == null)
377 throw new NoSuchMethodException(target.getClass().getName() + " "
378 + methodN);
379 try {
380 return m.invoke(target, new Object[] { param1 });
381 } catch (InvocationTargetException ie) {
382 ExceptionUtils.handleThrowable(ie.getCause());
383 throw ie;
384 }
385 }
386
387 public static Object callMethodN(Object target, String methodN,
388 Object params[], Class<?> typeParams[]) throws Exception {
389 Method m = null;
390 m = findMethod(target.getClass(), methodN, typeParams);
391 if (m == null) {
392 if (log.isDebugEnabled())
393 log.debug("IntrospectionUtils: Can't find method " + methodN +
394 " in " + target + " CLASS " + target.getClass());
395 return null;
396 }
397 try {
398 Object o = m.invoke(target, params);
399
400 if (log.isDebugEnabled()) {
401
402 StringBuilder sb = new StringBuilder();
403 sb.append(target.getClass().getName()).append('.')
404 .append(methodN).append("( ");
405 for (int i = 0; i < params.length; i++) {
406 if (i > 0)
407 sb.append(", ");
408 sb.append(params[i]);
409 }
410 sb.append(")");
411 log.debug("IntrospectionUtils:" + sb.toString());
412 }
413 return o;
414 } catch (InvocationTargetException ie) {
415 ExceptionUtils.handleThrowable(ie.getCause());
416 throw ie;
417 }
418 }
419
420 public static Object convert(String object, Class<?> paramType) {
421 Object result = null;
422 if ("java.lang.String".equals(paramType.getName())) {
423 result = object;
424 } else if ("java.lang.Integer".equals(paramType.getName())
425 || "int".equals(paramType.getName())) {
426 try {
427 result = Integer.valueOf(object);
428 } catch (NumberFormatException ex) {
429 }
430
431 } else if ("java.lang.Boolean".equals(paramType.getName())
432 || "boolean".equals(paramType.getName())) {
433 result = Boolean.valueOf(object);
434
435
436 } else if ("java.net.InetAddress".equals(paramType
437 .getName())) {
438 try {
439 result = InetAddress.getByName(object);
440 } catch (UnknownHostException exc) {
441 if (log.isDebugEnabled())
442 log.debug("IntrospectionUtils: Unable to resolve host name:" +
443 object);
444 }
445
446
447 } else {
448 if (log.isDebugEnabled())
449 log.debug("IntrospectionUtils: Unknown type " +
450 paramType.getName());
451 }
452 if (result == null) {
453 throw new IllegalArgumentException(sm.getString("introspectionUtils.conversionError", object, paramType.getName()));
454 }
455 return result;
456 }
457
458
459
476 public static boolean isInstance(Class<?> clazz, String type) {
477 if (type.equals(clazz.getName())) {
478 return true;
479 }
480
481 Class<?>[] ifaces = clazz.getInterfaces();
482 for (Class<?> iface : ifaces) {
483 if (isInstance(iface, type)) {
484 return true;
485 }
486 }
487
488 Class<?> superClazz = clazz.getSuperclass();
489 if (superClazz == null) {
490 return false;
491 } else {
492 return isInstance(superClazz, type);
493 }
494 }
495
496
497
498
499
500 public static interface PropertySource {
501 public String getProperty(String key);
502 }
503
504
505 public static interface SecurePropertySource extends PropertySource {
506
507
522 public String getProperty(String key, ClassLoader classLoader);
523 }
524 }
525