1 /* -------------------------------------------------------------------
2 * Java source file for the class ClassUtil
3 *
4 * Copyright (c), 2002, Masahiro Takatsuka.
5 * All Rights Researved.
6 *
7 * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8 * $Author: takatsukam $
9 *
10 * $Date: 2003/07/25 04:51:46 $
11 *
12 * $Id: ClassUtil.java,v 1.1.1.1 2003/07/25 04:51:46 takatsukam Exp $
13 *
14 * Reference: Document no:
15 * ___ ___
16 *
17 * To Do:
18 * ___
19 *
20 ------------------------------------------------------------------- */
21
22 /* --------------------------- Package ---------------------------- */
23 package net.jbeans.lang;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">color="#329900"> ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900"> ------------------ Import classes (packages) ------------------- */
26 import java.lang.reflect.*;
27
28 import net.jbeans.util.debug.*;
29
30 /*====================================================================
31 Implementation of class ClassUtil
32 ====================================================================*/
33 /***
34 * This class defines various method for examining class objcts.
35 *
36 * @version $Revision: 1.1.1.1 $
37 * @author Masahiro Takatsuka (masa@jbeans.net)
38 */
39
40 public final class ClassUtil {
41 /***
42 * debug flag
43 */
44 private static final boolean DEBUG = Debug.getDebugFlag(ClassUtil.class);
45
46 private static transient Class OBJ_CLASS = null;
47
48 /***
49 * Constructs a new ClassUtil object.
50 */
51 private ClassUtil() {
52 super();
53 }
54
55 /***
56 * Return true if class a is either equivalent to class b, or
57 * if class a is a subclass of class b.
58 * Either or both "Class" objects may be interfaces.
59 *
60 * @param class_a a "Class" object which may be subclass of "Class" b.
61 * @param class_b a "Class" object which may be superclass of "Class" a.
62 */
63 public static final boolean isSubclass(Class class_a, Class class_b) {
64 if (class_a == class_b) {
65 return true;
66 }
67 if (class_a == null || class_b == null) {
68 return false;
69 }
70 for (Class x = class_a; x != null; x = x.getSuperclass()) {
71 if (x == class_b) {
72 return true;
73 }
74 if (class_b.isInterface()) {
75 Class interfaces[] = x.getInterfaces();
76 for (int i = 0; i < interfaces.length; i++) {
77 if (interfaces[i] == class_b) {
78 return true;
79 }
80 }
81 }
82 }
83 return false;
84 }
85
86 /***
87 * Return true if class <code>c</code> implements interface
88 * <code>interfc</code>.
89 *
90 * @param clazz a "Class" object which may be implement interface interfc.
91 * @param interfc a "Interface" which may be implemented by "Class" clazz.
92 */
93 private static final boolean assignableInterface(Class clazz, Class interfc) {
94 if (clazz == interfc) {
95 return true;
96 }
97 Class impl[] = clazz.getInterfaces();
98 for (int i = 0; i < impl.length; i++) {
99 Class child = impl[i];
100 if (assignableInterface(child, interfc)) {
101 return true;
102 }
103 }
104
105 return false;
106 }
107
108 /***
109 * Return true if class <code>source</code> can be casted to
110 * class <code>target</code>.
111 *
112 * @param source a "Class" object which may be subclass of "Class" target.
113 * @param target a "Class" object which may be superclass of "Class"
114 * source.
115 */
116 public static final boolean isAssignable(Class source, Class target) {
117 if (target.isInterface()) {
118 return assignableInterface(source, target);
119 }
120 if (OBJ_CLASS == null) {
121 OBJ_CLASS = java.lang.Object.class;
122 }
123 if (target == OBJ_CLASS) {
124 return true;
125 }
126 for (Class current = source; current != null; current = current.getSuperclass()) {
127 if (current == target) {
128 return true;
129 }
130 }
131
132 return false;
133 }
134
135 /***
136 * Return true if object <code>o</code> is an array.
137 *
138 * @param o an object which may be an array.
139 */
140 public static final boolean isArray(Object o) {
141 Class clazz = o.getClass();
142 return clazz.isArray();
143 }
144
145 /***
146 * Return true if class <code>c</code> is an array.
147 *
148 * @param c a "Class" object which may be an array.
149 */
150 public static final boolean isArray(Class c) {
151 return c.isArray();
152 }
153
154 /***
155 * Return true if class <code>c</code> is a 2-D array.
156 *
157 * @param c a "Class" object which may be a 2-D array.
158 */
159 public static final boolean is2DArray(Class c) {
160 String nm = c.getName();
161 return nm.lastIndexOf("[") >= 1;
162 }
163
164 /***
165 * Return the dimensino of array if class <code>c</code> is an array.
166 *
167 * @param c a "Class" object which may be an array.
168 */
169 public static final int getDimensionOfArray(Class c) {
170 int dim = 0;
171 if (!isArray(c)) {
172 return dim;
173 }
174 String nm = c.getName();
175 int len = nm.length();
176 for (int i = 0; i < len; i ++) {
177 if (nm.charAt(i) != '[') {
178 break;
179 }
180 dim++;
181 }
182 return dim;
183 }
184
185 /***
186 * Sends the name of a method as a message to the receiver. This is
187 * equivalent to directly calling the receiver's method. For example,
188 * the following two lines do the same thing:
189 * <PRE>
190 * Example:
191 * myObject.setTitle("MyName");
192 * ClassUtil.makeObjectPerform(myObject, "setTitle", {"MyName"});
193 * </PRE>
194 *
195 * @param obj an object performing a method.
196 * @param methodname a method to be performed.
197 * @param args an array of arguments for the method.
198 * @exception java.lang.IllegalAccessException
199 * if the underlying methods is inaccessible.
200 * @exception java.lang.IllegalArgumentException
201 * if the number of actual and formal parameters differ,
202 * or if an unwrapping conversion fails.
203 * @exception java.lang.reflect.InvocationTargetException
204 * if the underlying methods throws an exception.
205 * @exception java.lang.NoSuchMethodException
206 * if a matching methods is not found.
207 */
208 public static final Object makeObjectPerform(Object obj, String methodname, Object[] args, Class[] argTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
209 Class c = obj.getClass(); // get the Class object.
210 Method m = c.getMethod(methodname, argTypes); // get the instance of the method
211
212 if (args == null) {
213 args = new Object[0]; // set up arguments.
214 }
215 return m.invoke(obj, args); // invoke the method.
216 }
217
218 /***
219 * Sends the name of a method as a message to the receiver. This is
220 * equivalent to directly calling the receiver's method. For example,
221 * the following two lines do the same thing:
222 * <PRE>
223 * Example:
224 * myObject.setTitle("MyName");
225 * ClassUtil.makeObjectPerform(myObject, "setTitle", {"MyName"});
226 * </PRE>
227 *
228 * @param obj an object performing a method.
229 * @param methodname a method to be performed.
230 * @param args an array of arguments for the method.
231 * @exception java.lang.IllegalAccessException
232 * if the underlying methods is inaccessible.
233 * @exception java.lang.IllegalArgumentException
234 * if the number of actual and formal parameters differ,
235 * or if an unwrapping conversion fails.
236 * @exception java.lang.reflect.InvocationTargetException
237 * if the underlying methods throws an exception.
238 * @exception java.lang.NoSuchMethodException
239 * if a matching methods is not found.
240 */
241 public static final Object makeObjectPerform(Object obj, String methodname, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
242 Class[] argTypes;
243 if (args == null) { // no parameter...
244 argTypes = new Class[0];
245 } else { // get fully-qualified names of parameters
246 argTypes = new Class[args.length];
247 for (int i = 0; i < args.length; i++) {
248 argTypes[i] = args[i].getClass();
249 }
250 }
251 return makeObjectPerform(obj, methodname, args, argTypes);
252 }
253
254 /***
255 * Returns true if the receiver implements or inherits a method that can
256 * respond to <code>method</code>, false otherwise. The application is
257 * responsible for determining whether a false response should be
258 * considered an error.
259 * <PRE>
260 * Example:
261 * if (ClassUtil.respondsToMethod(myObject, "setTitle", {"xxx"})) {
262 * myObject.setTitle("MyName");
263 * }
264 * </PRE>
265 *
266 * @param methodname a method to be performed.
267 * @param argTypes an array of argument types for the methods.
268 * @return true if the receiver implements or inherits the methods,
269 * otherwiise false.
270 * @see #perform(String, Object[])
271 * @see #perform(String)
272 * @see #respondsToMethod(String)
273 */
274 public static final boolean respondsToMethod(Object obj, String methodname, Class[] argTypes) {
275
276 Class c = obj.getClass(); // get the Class object.
277 try{
278 Method m = c.getMethod(methodname, argTypes); // get the instance of the method
279 }catch(NoSuchMethodException e){ // want to catch this exception in order to return false.
280 return false;
281 }
282 return true;
283 }
284
285 /***
286 * Returns true if the receiver implements or inherits a method that can
287 * respond to <code>method</code>, false otherwise. The application is
288 * responsible for determining whether a false response should be
289 * considered an error.
290 * <PRE>
291 * Example:
292 * if (ClassUtil.respondsToMethod(myObject, "setTitle", {"xxx"})) {
293 * myObject.setTitle("MyName");
294 * }
295 * </PRE>
296 *
297 * @param methodname a method to be performed.
298 * @param args an array of arguments for the methods.
299 * @return true if the receiver implements or inherits the methods,
300 * otherwiise false.
301 * @see #perform(String, Object[])
302 * @see #perform(String)
303 * @see #respondsToMethod(String)
304 */
305 public static final boolean respondsToMethod(Object obj, String methodname, Object[] args) {
306 Class[] argTypes;
307 if (args == null) { // if there is no parameter...
308 argTypes = new Class[0];
309 } else { // get fully-qualified names of parameters
310 argTypes = new Class[args.length];
311 for (int i = 0; i < args.length; i++)
312 argTypes[i] = args[i].getClass();
313 }
314 return respondsToMethod(obj, methodname, argTypes);
315 }
316
317 /***
318 * Sends a methodname message to the receiver. This is equivalent to sending
319 * a methodname message directly to the receiver. For example, the following
320 * two messages do the same thing:
321 * <PRE>
322 * Example:
323 * myObject.show();
324 * myObject.perform("show");
325 * </PRE>
326 *
327 * @param obj an object performing a method.
328 * @param methodname a method to be performed.
329 * @exception java.lang.IllegalAccessException
330 * if the underlying methods is inaccessible.
331 * @exception java.lang.IllegalArgumentException
332 * if the number of actual and formal parameters differ,
333 * or if an unwrapping conversion fails.
334 * @exception java.lang.reflect.InvocationTargetException
335 * if the underlying methods throws an exception.
336 * @exception java.lang.NoSuchMethodException
337 * if a matching methods is not found.
338 */
339 public static final Object makeObjectPerform(Object obj, String methodname) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
340 return makeObjectPerform(obj, methodname, null);
341 }
342
343 /***
344 * Returns true if the receiver implements or inherits a method that can
345 * respond to methodname messages, false otherwise. The application is
346 * responsible for determining whether a false response should be considered
347 * an error.
348 * <PRE>
349 * Example:
350 * if(ClassUtil.respondsToMethod(myObject, "show"))
351 * myObject.show();
352 * </PRE>
353 *
354 * @param obj an object performing a method.
355 * @param methodname a method to be performed.
356 * @return true if the receiver implements or inherits the methods,
357 * otherwiise false.
358 */
359 public static final boolean respondsToMethod(Object obj, String methodname) {
360 return respondsToMethod(obj, methodname, null);
361 }
362
363 /***
364 * Sends a methodname message to the receiver. This is equivalent to sending
365 * a methodname message directly to the receiver. For example, the following
366 * two messages do the same thing:
367 * <PRE>
368 * Example:
369 * myObject.setTitle("MyName");
370 * Object[] args = {String.class};
371 * Method method = myObject.getMethod("setTitle", args);
372 * ThreadGroup mygroup = new ThreadGroup(this.toString());
373 * myObject.performInThread(mygroup, method, {"MyName"}, false);
374 * Example of implementation:
375 * public synchronized void performInThread(ThreadGroup group, Method method, Object arg, boolean forced) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
376 * ThreadTask task = new ThreadTask(this, method, args);
377 * Thread newThread = new Thread(group,
378 * this,
379 * method.getName());
380 * newThread.start();
381 * }
382 * </PRE>
383 *
384 * @param group a thread group.
385 * @param method a method to be performed.
386 * @param args arguments for the method.
387 * @param forced a flag to force the specified method to be executed
388 * even if there is alread a thread executing the same method.
389 * @exception java.lang.IllegalAccessException
390 * if the underlying methods is inaccessible.
391 * @exception java.lang.IllegalArgumentException
392 * if the number of actual and formal parameters differ,
393 * or if an unwrapping conversion fails.
394 * @exception java.lang.reflect.InvocationTargetException
395 * if the underlying methods throws an exception.
396 * @exception java.lang.NoSuchMethodException
397 * if a matching methods is not found.
398 * @see com.gpz.lang.MObject#perform(String)
399 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
400 * @see com.gpz.lang.MObject#respondsToMethod(String)
401 */
402 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, Method method, Object[] args, boolean forced) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
403 // if (! respondsToMethod(object,
404 // (method != null)?method.getName():"",
405 // args) ) {
406 // throw new NoSuchMethodException();
407 // }
408 ThreadTask task = new ThreadTask(object, method, args);
409 Thread newThread = new Thread(group,
410 task,
411 method.getName());
412 newThread.start();
413 return newThread;
414 }
415
416 /***
417 * Sends a methodname message to the receiver. This is equivalent to sending
418 * a methodname message directly to the receiver.
419 *
420 * @param group a thread group.
421 * @param methodname a method to be performed.
422 * @param args arguments for the method.
423 * @exception java.lang.IllegalAccessException
424 * if the underlying methods is inaccessible.
425 * @exception java.lang.IllegalArgumentException
426 * if the number of actual and formal parameters differ,
427 * or if an unwrapping conversion fails.
428 * @exception java.lang.reflect.InvocationTargetException
429 * if the underlying methods throws an exception.
430 * @exception java.lang.NoSuchMethodException
431 * if a matching methods is not found.
432 * @see com.gpz.lang.MObject#perform(String)
433 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
434 * @see com.gpz.lang.MObject#respondsToMethod(String)
435 */
436 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
437 return makeObjectPerformInThread(group, object, method, args, false);
438 }
439
440 /***
441 * Sends a methodname message to the receiver. This is equivalent to sending
442 * a methodname message directly to the receiver.
443 *
444 * @param methodname a method to be performed.
445 * @param args arguments for the method.
446 * @exception java.lang.IllegalAccessException
447 * if the underlying methods is inaccessible.
448 * @exception java.lang.IllegalArgumentException
449 * if the number of actual and formal parameters differ,
450 * or if an unwrapping conversion fails.
451 * @exception java.lang.reflect.InvocationTargetException
452 * if the underlying methods throws an exception.
453 * @exception java.lang.NoSuchMethodException
454 * if a matching methods is not found.
455 * @see com.gpz.lang.MObject#perform(String)
456 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
457 * @see com.gpz.lang.MObject#respondsToMethod(String)
458 */
459 public static final Thread makeObjectPerformInThread(Object object, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
460 return makeObjectPerformInThread(null, object, method, args);
461 }
462
463 /***
464 * Sends a methodname message to the receiver. This is equivalent to sending
465 * a methodname message directly to the receiver.
466 *
467 * @param methodname a method to be performed.
468 * @exception java.lang.IllegalAccessException
469 * if the underlying methods is inaccessible.
470 * @exception java.lang.IllegalArgumentException
471 * if the number of actual and formal parameters differ,
472 * or if an unwrapping conversion fails.
473 * @exception java.lang.reflect.InvocationTargetException
474 * if the underlying methods throws an exception.
475 * @exception java.lang.NoSuchMethodException
476 * if a matching methods is not found.
477 * @see com.gpz.lang.MObject#perform(String)
478 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
479 * @see com.gpz.lang.MObject#respondsToMethod(String)
480 */
481 public static final Thread makeObjectPerformInThread(Object object, Method method) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
482 return makeObjectPerformInThread(null, object, method, null);
483 }
484
485 /***
486 * Sends a methodname message to the receiver. This is equivalent to sending
487 * a methodname message directly to the receiver. For example, the following
488 * two messages do the same thing:
489 * <PRE>
490 * Example:
491 * myObject.setTitle("MyName");
492 * ThreadGourp myThreadGroup = new ThreadGroup(this.toString());
493 * myObject.performInThread(myThreadGroup, "setTitle", {"MyName"}, false);
494 * </PRE>
495 *
496 * @param group a thread group.
497 * @param methodname a method to be performed.
498 * @param args arguments for the method.
499 * @param forced a flag to force the specified method to be executed
500 * even if there is alread a thread executing the same method.
501 * (This function is not implemented in this release.)
502 * @exception java.lang.IllegalAccessException
503 * if the underlying methods is inaccessible.
504 * @exception java.lang.IllegalArgumentException
505 * if the number of actual and formal parameters differ,
506 * or if an unwrapping conversion fails.
507 * @exception java.lang.reflect.InvocationTargetException
508 * if the underlying methods throws an exception.
509 * @exception java.lang.NoSuchMethodException
510 * if a matching methods is not found.
511 * @see com.gpz.lang.MObject#perform(String)
512 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
513 * @see com.gpz.lang.MObject#respondsToMethod(String)
514 */
515 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, String methodname, Object[] args, boolean forced) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
516 Class[] parameters;
517
518 if (args == null) { // no parameter...
519 parameters = new Class[0];
520 } else { // get fully-qualified names of parameters
521 parameters = new Class[args.length];
522 for (int i = 0; i < args.length; i++) {
523 parameters[i] = args[i].getClass();
524 }
525 }
526 return makeObjectPerformInThread(group, object, methodname, args, parameters, forced);
527 }
528
529 /***
530 * Sends a methodname message to the receiver. This is equivalent to sending
531 * a methodname message directly to the receiver. For example, the following
532 * two messages do the same thing:
533 * <PRE>
534 * Example:
535 * myObject.setTitle("MyName");
536 * ThreadGourp myThreadGroup = new ThreadGroup(this.toString());
537 * myObject.performInThread(myThreadGroup, "setTitle", {"MyName"}, false);
538 * </PRE>
539 *
540 * @param group a thread group.
541 * @param methodname a method to be performed.
542 * @param args arguments for the method.
543 * @param forced a flag to force the specified method to be executed
544 * even if there is alread a thread executing the same method.
545 * (This function is not implemented in this release.)
546 * @exception java.lang.IllegalAccessException
547 * if the underlying methods is inaccessible.
548 * @exception java.lang.IllegalArgumentException
549 * if the number of actual and formal parameters differ,
550 * or if an unwrapping conversion fails.
551 * @exception java.lang.reflect.InvocationTargetException
552 * if the underlying methods throws an exception.
553 * @exception java.lang.NoSuchMethodException
554 * if a matching methods is not found.
555 * @see com.gpz.lang.MObject#perform(String)
556 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
557 * @see com.gpz.lang.MObject#respondsToMethod(String)
558 */
559 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, String methodname, Object[] args, Class[] argTypes, boolean forced) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
560 Method method = object.getClass().getMethod(methodname, argTypes); // get the instance of the method
561 return makeObjectPerformInThread(group, object, method, args, forced);
562 }
563
564 /***
565 * Sends a methodname message to the receiver. This is equivalent to sending
566 * a methodname message directly to the receiver. For example, the following
567 * two messages do the same thing:
568 * <PRE>
569 * Example:
570 * myObject.setTitle("MyName");
571 * myObject.perform("setTitle", {"MyName"});
572 * </PRE>
573 *
574 * @param group a thread group.
575 * @param methodname a method to be performed.
576 * @param args arguments for the method.
577 * @exception java.lang.IllegalAccessException
578 * if the underlying methods is inaccessible.
579 * @exception java.lang.IllegalArgumentException
580 * if the number of actual and formal parameters differ,
581 * or if an unwrapping conversion fails.
582 * @exception java.lang.reflect.InvocationTargetException
583 * if the underlying methods throws an exception.
584 * @exception java.lang.NoSuchMethodException
585 * if a matching methods is not found.
586 * @see com.gpz.lang.MObject#perform(String)
587 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
588 * @see com.gpz.lang.MObject#respondsToMethod(String)
589 */
590 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, String methodname, Object[] args, Class[] argTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
591 return makeObjectPerformInThread(group, object, methodname, args, argTypes, false);
592 }
593
594 /***
595 * Sends a methodname message to the receiver. This is equivalent to sending
596 * a methodname message directly to the receiver. For example, the following
597 * two messages do the same thing:
598 * <PRE>
599 * Example:
600 * myObject.setTitle("MyName");
601 * myObject.perform("setTitle", {"MyName"});
602 * </PRE>
603 *
604 * @param group a thread group.
605 * @param methodname a method to be performed.
606 * @param args arguments for the method.
607 * @exception java.lang.IllegalAccessException
608 * if the underlying methods is inaccessible.
609 * @exception java.lang.IllegalArgumentException
610 * if the number of actual and formal parameters differ,
611 * or if an unwrapping conversion fails.
612 * @exception java.lang.reflect.InvocationTargetException
613 * if the underlying methods throws an exception.
614 * @exception java.lang.NoSuchMethodException
615 * if a matching methods is not found.
616 * @see com.gpz.lang.MObject#perform(String)
617 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
618 * @see com.gpz.lang.MObject#respondsToMethod(String)
619 */
620 public static final Thread makeObjectPerformInThread(ThreadGroup group, Object object, String methodname, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
621 return makeObjectPerformInThread(group, object, methodname, args, false);
622 }
623
624 /***
625 * Sends a methodname message to the receiver. This is equivalent to sending
626 * a methodname message directly to the receiver. For example, the following
627 * two messages do the same thing:
628 * <PRE>
629 * Example:
630 * myObject.setTitle("MyName");
631 * myObject.perform("setTitle", {"MyName"});
632 * </PRE>
633 *
634 * @param methodname a method to be performed.
635 * @param args arguments for the method.
636 * @exception java.lang.IllegalAccessException
637 * if the underlying methods is inaccessible.
638 * @exception java.lang.IllegalArgumentException
639 * if the number of actual and formal parameters differ,
640 * or if an unwrapping conversion fails.
641 * @exception java.lang.reflect.InvocationTargetException
642 * if the underlying methods throws an exception.
643 * @exception java.lang.NoSuchMethodException
644 * if a matching methods is not found.
645 * @see com.gpz.lang.MObject#perform(String)
646 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
647 * @see com.gpz.lang.MObject#respondsToMethod(String)
648 */
649 public static final Thread makeObjectPerformInThread(Object object, String methodname, Object[] args, Class[] argTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
650 return makeObjectPerformInThread(null, object, methodname, args, argTypes);
651 }
652
653 /***
654 * Sends a methodname message to the receiver. This is equivalent to sending
655 * a methodname message directly to the receiver. For example, the following
656 * two messages do the same thing:
657 * <PRE>
658 * Example:
659 * myObject.setTitle("MyName");
660 * myObject.perform("setTitle", {"MyName"});
661 * </PRE>
662 *
663 * @param methodname a method to be performed.
664 * @param args arguments for the method.
665 * @exception java.lang.IllegalAccessException
666 * if the underlying methods is inaccessible.
667 * @exception java.lang.IllegalArgumentException
668 * if the number of actual and formal parameters differ,
669 * or if an unwrapping conversion fails.
670 * @exception java.lang.reflect.InvocationTargetException
671 * if the underlying methods throws an exception.
672 * @exception java.lang.NoSuchMethodException
673 * if a matching methods is not found.
674 * @see com.gpz.lang.MObject#perform(String)
675 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
676 * @see com.gpz.lang.MObject#respondsToMethod(String)
677 */
678 public static final Thread makeObjectPerformInThread(Object object, String methodname, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
679 return makeObjectPerformInThread(null, object, methodname, args);
680 }
681
682 /***
683 * Sends a methodname message to the receiver. This is equivalent to sending
684 * a methodname message directly to the receiver. For example, the following
685 * two messages do the same thing:
686 * <PRE>
687 * Example:
688 * myObject.show();
689 * myObject.perform("show");
690 * </PRE>
691 *
692 * @param methodname a method to be performed.
693 * @exception java.lang.IllegalAccessException
694 * if the underlying methods is inaccessible.
695 * @exception java.lang.IllegalArgumentException
696 * if the number of actual and formal parameters differ,
697 * or if an unwrapping conversion fails.
698 * @exception java.lang.reflect.InvocationTargetException
699 * if the underlying methods throws an exception.
700 * @exception java.lang.NoSuchMethodException
701 * if a matching methods is not found.
702 * @see com.gpz.lang.MObject#perform(String)
703 * @see com.gpz.lang.MObject#respondsToMethod(String, Object[])
704 * @see com.gpz.lang.MObject#respondsToMethod(String)
705 */
706 public static final Thread makeObjectPerformInThread(Object object, String methodname) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
707 return makeObjectPerformInThread(null, object, methodname, null);
708 }
709
710 /***
711 * Returns a corresponding wrapper class of the specified primitive class.
712 *
713 * @param primitiveClass a class represnts a primitive (one of Boolean.TYPE,
714 * Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE,
715 * Double.TYPE).
716 */
717 public static final Class getWrapperClass(Class primitiveClass) {
718 Class wrapper = null;
719 if (primitiveClass == Boolean.TYPE) {
720 wrapper = Boolean.class;
721 } else if (primitiveClass == Character.TYPE) {
722 wrapper = Character.class;
723 } else if (primitiveClass == Byte.TYPE) {
724 wrapper = Byte.class;
725 } else if (primitiveClass == Short.TYPE) {
726 wrapper = Short.class;
727 } else if (primitiveClass == Integer.TYPE) {
728 wrapper = Integer.class;
729 } else if (primitiveClass == Long.TYPE) {
730 wrapper = Long.class;
731 } else if (primitiveClass == Float.TYPE) {
732 wrapper = Float.class;
733 } else if (primitiveClass == Double.TYPE) {
734 wrapper = Double.class;
735 }
736 return wrapper;
737 }
738
739 /***
740 * Converts Class objects representing primitive classes into
741 * corresponding wrapper classs. The original array will be over
742 * written by new classes.
743 *
744 * @param primitiveClasses an array containing classs.
745 */
746 public static final Class[] getWrapperClasses(Class[] primitiveClasses) {
747 int len = primitiveClasses.length;
748 for (int i = 0; i < len; i++) {
749 if (primitiveClasses[i].isPrimitive()) {
750 primitiveClasses[i] = ClassUtil.getWrapperClass(primitiveClasses[i]);
751 }
752 }
753 return primitiveClasses;
754 }
755
756 /***
757 * Returns a corresponding class of the specified primitive class.
758 *
759 * @param primitive a string represnts a primitive (one of "boolean", "char",
760 * "byte", "short", "int", "long", "float", "double").
761 */
762 public static final Class getPrimitiveClass(String primitive) {
763 Class clazz = null;
764 if (primitive.equals("boolean")) {
765 clazz = Boolean.TYPE;
766 } else if (primitive.equals("char")) {
767 clazz = Character.TYPE;
768 } else if (primitive.equals("byte")) {
769 clazz = Byte.TYPE;
770 } else if (primitive.equals("short")) {
771 clazz = Short.TYPE;
772 } else if (primitive.equals("int")) {
773 clazz = Integer.TYPE;
774 } else if (primitive.equals("long")) {
775 clazz = Long.TYPE;
776 } else if (primitive.equals("float")) {
777 clazz = Float.TYPE;
778 } else if (primitive.equals("double")) {
779 clazz = Double.TYPE;
780 }
781 return clazz;
782 }
783
784 public static final String[] getClassNames(Class[] classes) {
785 int len = classes.length;
786 String[] names = new String[len];
787 for (int i = 0; i < len; i++) {
788 names[i] = classes[i].getName();
789 }
790 return names;
791 }
792
793 public static final Class[] getClasses(String[] names) {
794 int len = names.length;
795 Class[] classes = new Class[len];
796 for (int i = 0; i < len; i++) {
797 try {
798 Class argclass = ClassUtil.getPrimitiveClass(names[i]);
799 if (argclass != null) {
800 classes[i] = argclass;
801 } else {
802 classes[i] = Class.forName(names[i]);
803 }
804 } catch (ClassNotFoundException e) {
805 classes[i] = null;
806 }
807 }
808 return classes;
809 }
810
811 public static final Class getClass(String name) {
812 Class clazz = null;
813 try {
814 clazz = ClassUtil.getPrimitiveClass(name);
815 if (clazz == null) {
816 clazz = Class.forName(name);
817 }
818 } catch (ClassNotFoundException e) {
819 clazz = null;
820 }
821 return clazz;
822 }
823
824 /***
825 * Returns the name of the root class from a full class path.
826 * @param fullName The full name of the class i.e, java.awt.event.ActionListener
827 * @return The root name of the class i.e., ActionListener
828 */
829 public static final String getRootName(Class clazz) {
830 return getRootName(clazz.getName());
831 }
832
833 /***
834 * Returns the name of the root class from a full class path.
835 * @param fullName The full name of the class i.e, java.awt.event.ActionListener
836 * @return The root name of the class i.e., ActionListener
837 */
838 public static final String getRootName(String fullName) {
839 String compName = getCompilableName(fullName);
840 int index = compName.lastIndexOf('.');
841 compName = compName.substring(index + 1);
842
843 return compName;
844 }
845
846 /***
847 * Returns the class name, which can be inserted in java source code,
848 * from a fully-qualified class name.
849 * @param fullName The full name of the class
850 * i.e, java.awt.event.ActionListener, [[Ljava.lang.String
851 * @return The class name that can be inserted in java source code
852 * i.e., java.awt.event.ActionListener, java.lang.String[][]
853 */
854 public static final String getCompilableName(Class clazz) {
855 return getCompilableName(clazz.getName());
856 }
857
858
859 /***
860 * Returns the class name, which can be inserted in java source code,
861 * from a fully-qualified class name.
862 * @param fullName The full name of the class
863 * i.e, java.awt.event.ActionListener, [[Ljava.lang.String
864 * @return The class name that can be inserted in java source code
865 * i.e., java.awt.event.ActionListener, java.lang.String[][]
866 */
867 public static final String[] getCompilableNames(Class[] classes) {
868 int count = classes.length;
869 String[] names = new String[count];
870 for (int i = 0; i < count; i++) {
871 names[i] = getCompilableName(classes[i].getName());
872 }
873 return names;
874 }
875
876 /***
877 * Returns the class name, which can be inserted in java source code,
878 * from a fully-qualified class name.
879 * @param fullName The full name of the class
880 * i.e, java.awt.event.ActionListener, [[Ljava.lang.String
881 * @return The class name that can be inserted in java source code
882 * i.e., java.awt.event.ActionListener, java.lang.String[][]
883 */
884 public static final String getCompilableName(String fullName) {
885 // find array dimension;
886 int dim = 0;
887 int len = fullName.length();
888 int i = 0;
889 for (i = 0; i < len; i++) { // count '['
890 if (fullName.charAt(i) != '[') {
891 break;
892 }
893 dim++;
894 }
895 String name = "";
896 if (dim > 0) { // class is an array!
897 /*
898 B byte
899 C char
900 D double
901 F float
902 I int
903 J long
904 Lclassname; class or interface
905 S short
906 Z boolean
907 */
908 char objLetter = fullName.charAt(i);
909
910 if (objLetter == 'B') {
911 name = "byte";
912 } else if (objLetter == 'C') {
913 name = "char";
914 } else if (objLetter == 'D') {
915 name = "double";
916 } else if (objLetter == 'F') {
917 name = "float";
918 } else if (objLetter == 'I') {
919 name = "int";
920 } else if (objLetter == 'J') {
921 name = "long";
922 } else if (objLetter == 'S') {
923 name = "short";
924 } else if (objLetter == 'Z') {
925 name = "boolean";
926 } else if (objLetter == 'L') {
927 // there is ';' at the end, so get rid of it!
928 name = fullName.substring(i + 1, len - 1);
929 }
930 StringBuffer sbname = new StringBuffer(name);
931 for (int j = 0; j < dim; j++) {
932 sbname.append("[]");
933 }
934 name = sbname.toString();
935 } else {
936 name = fullName;
937 }
938 return name;
939 }
940
941
942 /***
943 * Returns a string that formats the method signature for desplay
944 * @param method The method to format.
945 */
946 public static final String formatMethodSignature(Method method) {
947 StringBuffer params = new StringBuffer(formatReturnType(method));
948 params.append(method.getName());
949 params.append(formatParameters(method));
950 return params.toString();
951 }
952
953 /***
954 * Returns a string that formats the method signature for desplay
955 * @param method The method to format.
956 */
957 public static final String formatMethodSignatureWithoutReturnType(Method method) {
958 StringBuffer params = new StringBuffer(method.getName());
959 params.append(formatParameters(method));
960 return params.toString();
961 }
962
963 /***
964 * Returns a string that formats the parameters for a methods for display
965 * @param method The method to format.
966 */
967 public static final String formatParameters(Method method) {
968 StringBuffer params = new StringBuffer("( ");
969
970 Class[] paramTypes = method.getParameterTypes();
971 if (paramTypes != null) {
972 for (int i = 0; i < paramTypes.length; i++) {
973 params.append(getRootName(paramTypes[i].getName()));
974 params.append((i == paramTypes.length - 1) ? " " : ", ");
975 }
976 }
977 params.append(")");
978
979 return params.toString();
980 }
981
982 /***
983 * Returns a string that formats the parameters for a methods for display
984 * @param method The method to format.
985 */
986 public static final String formatReturnType(Method method) {
987 StringBuffer params = new StringBuffer("( ");
988
989 Class returnType = method.getReturnType();
990 if (returnType != null) {
991 params.append(getRootName(returnType.getName()));
992 }
993 params.append(" )");
994
995 return params.toString();
996 }
997
998 /***
999 * Utility method to take a string and convert it to normal Java variable
1000 * name capitalization. This normally means converting the first
1001 * character from upper case to lower case, but in the (unusual) special
1002 * case when there is more than two character and the first, second and
1003 * third characters are upper case, we leave it alone.
1004 * <p>
1005 * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
1006 * as "URL".
1007 *
1008 * @param name The string to be decapitalized.
1009 * @return The decapitalized version of the string.
1010 */
1011 public static final String decapitalize(String name) {
1012 if (name == null || name.length() == 0) {
1013 return name;
1014 }
1015 if (name.length() > 1 && Character.isUpperCase(name.charAt(2)) &&
1016 Character.isUpperCase(name.charAt(1)) &&
1017 Character.isUpperCase(name.charAt(0))){
1018 return name;
1019 }
1020 char chars[] = name.toCharArray();
1021 chars[0] = Character.toLowerCase(chars[0]);
1022 return new String(chars);
1023 }
1024
1025 /***
1026 * Utility method to take a string and convert it to normal Java variable
1027 * name capitalization. This normally means converting the first
1028 * character from upper case to lower case.
1029 * <p>
1030 * Thus "FooBah" becomes "fooBah" and "X" becomes "x", and "URL" becomes
1031 * as "uRL".
1032 *
1033 * @param name The string to be decapitalized.
1034 * @return The decapitalized version of the string.
1035 */
1036 public static final String forceDecapitalize(String name) {
1037 if (name == null || name.length() == 0) {
1038 return name;
1039 }
1040 char chars[] = name.toCharArray();
1041 chars[0] = Character.toLowerCase(chars[0]);
1042 return new String(chars);
1043 }
1044
1045 /***
1046 * Utility method to take a string and convert it to normal Java Class
1047 * name capitalization. This normally means converting the first
1048 * character from lower case to upper case.
1049 *
1050 * @param name The string to be capitalized.
1051 * @return The capitalized version of the string.
1052 */
1053 public static final String capitalize(String name) {
1054 if (name == null || name.length() == 0) {
1055 return name;
1056 }
1057 char chars[] = name.toCharArray();
1058 chars[0] = Character.toUpperCase(chars[0]);
1059 return new String(chars);
1060 }
1061
1062 /***
1063 * Returns the name of the root directory where the specified class
1064 * resides.
1065 * @param fullName The full name of the class i.e, java.awt.event.ActionListener
1066 * @return The root name of the class i.e., ActionListener
1067 */
1068 public static final String getRootDirectoryName(String fullPath, String classFileName) {
1069 int index = fullPath.lastIndexOf(classFileName);
1070 if (index >= 0) {
1071 return fullPath.substring(0, index);
1072 }
1073 return null;
1074 }
1075
1076 public static final Method getMethod(Object obj, String methodName, Class[] argTypes) {
1077 Method method = null;
1078 try {
1079 Class c = obj.getClass(); // get the Class object.
1080 method = c.getMethod(methodName, argTypes); // get the instance of the method
1081 }catch(NoSuchMethodException e) {
1082 if (DEBUG) {
1083 e.printStackTrace();
1084 }
1085 // let go as method == null.
1086 }
1087 return method;
1088 }
1089 }
This page was automatically generated by Maven