KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > modeler > util > IntrospectionUtils


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
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
17
18 package org.apache.commons.modeler.util;
19
20 import java.io.File JavaDoc;
21 import java.io.FilenameFilter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.net.InetAddress JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.net.UnknownHostException JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 // Depends:
34
// JDK1.1
35

36 /**
37  * Utils for introspection and reflection
38  *
39  * Source: jakarta-tomcat-connector/util
40  */

41 public final class IntrospectionUtils {
42     static final Class JavaDoc NO_PARAMS[]=new Class JavaDoc[0];
43     static final Class JavaDoc STRING_OBJ_PARAM[]=new Class JavaDoc[] {
44         String JavaDoc.class, Object JavaDoc.class };
45     static final Class JavaDoc STRING_PARAM[]=new Class JavaDoc[] {
46         String JavaDoc.class };
47
48     /** Execute a no-param method.
49      */

50     public static void execute( Object JavaDoc proxy, String JavaDoc method )
51     throws Exception JavaDoc
52     {
53     Method JavaDoc executeM=null;
54     Class JavaDoc c=proxy.getClass();
55     executeM=findMethod( c, method, NO_PARAMS );
56     if( executeM == null ) {
57         throw new RuntimeException JavaDoc("No method " + method + " in " +
58                     proxy.getClass() );
59     }
60     executeM.invoke(proxy, null );
61     }
62
63     /**
64      * Call void setAttribute( String ,Object )
65      */

66     public static void setAttribute( Object JavaDoc proxy, String JavaDoc n, Object JavaDoc v)
67     throws Exception JavaDoc
68     {
69     if( proxy instanceof AttributeHolder ) {
70         ((AttributeHolder)proxy).setAttribute( n, v );
71         return;
72     }
73
74     Method JavaDoc executeM=null;
75     Class JavaDoc c=proxy.getClass();
76     executeM=findMethod( c, "setAttribute", STRING_OBJ_PARAM );
77
78     if( executeM == null ) {
79         System.out.println("No setAttribute in " + proxy.getClass() );
80         return;
81     }
82     executeM.invoke(proxy, new Object JavaDoc[] { n, v });
83     return;
84     }
85
86
87     /**
88      * Call void getAttribute( String )
89      */

90     public static Object JavaDoc getAttribute( Object JavaDoc proxy, String JavaDoc n)
91     throws Exception JavaDoc
92     {
93     Method JavaDoc executeM=null;
94     Class JavaDoc c=proxy.getClass();
95     executeM=findMethod( c, "getAttribute", STRING_PARAM);
96     if( executeM == null ) {
97         System.out.println("No getAttribute in " + proxy.getClass() );
98         return null;
99     }
100     return executeM.invoke(proxy, new Object JavaDoc[] { n });
101     }
102
103
104     /** Construct a URLClassLoader. Will compile and work in JDK1.1 too.
105      */

106     public static ClassLoader JavaDoc getURLClassLoader( URL JavaDoc urls[],
107                          ClassLoader JavaDoc parent )
108     {
109     try {
110         Class JavaDoc urlCL=Class.forName( "java.net.URLClassLoader");
111         Class JavaDoc paramT[]=new Class JavaDoc[2];
112         paramT[0]= urls.getClass();
113         paramT[1]=ClassLoader JavaDoc.class;
114         Method JavaDoc m=findMethod( urlCL, "newInstance", paramT);
115         if( m==null ) return null;
116
117         ClassLoader JavaDoc cl=(ClassLoader JavaDoc)m.invoke( urlCL,
118                           new Object JavaDoc[] { urls,
119                                  parent } );
120         return cl;
121     } catch(ClassNotFoundException JavaDoc ex ) {
122         // jdk1.1
123
return null;
124     } catch(Exception JavaDoc ex ) {
125         ex.printStackTrace();
126         return null;
127     }
128     }
129
130
131     public static String JavaDoc guessInstall(String JavaDoc installSysProp,
132         String JavaDoc homeSysProp, String JavaDoc jarName) {
133     return guessInstall( installSysProp, homeSysProp, jarName, null);
134     }
135
136     /** Guess a product install/home by analyzing the class path.
137      * It works for product using the pattern: lib/executable.jar
138      * or if executable.jar is included in classpath by a shell
139      * script. ( java -jar also works )
140      *
141      * Insures both "install" and "home" System properties are set.
142      * If either or both System properties are unset, "install" and
143      * "home" will be set to the same value. This value will be
144      * the other System property that is set, or the guessed value
145      * if neither is set.
146      */

147     public static String JavaDoc guessInstall(String JavaDoc installSysProp, String JavaDoc homeSysProp,
148             String JavaDoc jarName, String JavaDoc classFile) {
149     String JavaDoc install=null;
150     String JavaDoc home=null;
151
152     if ( installSysProp != null )
153         install=System.getProperty( installSysProp );
154
155     if( homeSysProp != null )
156         home=System.getProperty( homeSysProp );
157
158     if ( install != null ) {
159         if ( home == null )
160         System.getProperties().put( homeSysProp, install );
161         return install;
162     }
163
164     // Find the directory where jarName.jar is located
165

166     String JavaDoc cpath=System.getProperty( "java.class.path");
167     String JavaDoc pathSep=System.getProperty( "path.separator");
168     StringTokenizer JavaDoc st=new StringTokenizer JavaDoc( cpath, pathSep );
169     while( st.hasMoreTokens() ) {
170         String JavaDoc path=st.nextToken();
171         // log( "path " + path );
172
if( path.endsWith( jarName ) ) {
173         home=path.substring( 0, path.length() - jarName.length() );
174         try {
175                     if( "".equals(home) ) {
176                         home=new File JavaDoc("./").getCanonicalPath();
177                     } else if( home.endsWith(File.separator) ) {
178             home = home.substring(0,home.length()-1);
179             }
180                     File JavaDoc f=new File JavaDoc( home );
181             String JavaDoc parentDir = f.getParent();
182             if(parentDir == null)
183             parentDir = home; // unix style
184
File JavaDoc f1=new File JavaDoc ( parentDir );
185             install = f1.getCanonicalPath();
186             if( installSysProp != null )
187             System.getProperties().put( installSysProp, install );
188             if( home == null && homeSysProp != null )
189             System.getProperties().put( homeSysProp, install );
190             return install;
191         } catch( Exception JavaDoc ex ) {
192             ex.printStackTrace();
193         }
194         } else {
195         String JavaDoc fname=path + ( path.endsWith("/") ?"":"/" ) + classFile;
196         if( new File JavaDoc( fname ).exists()) {
197             try {
198             File JavaDoc f=new File JavaDoc( path );
199             String JavaDoc parentDir = f.getParent();
200             if( parentDir == null )
201                 parentDir = path; // unix style
202
File JavaDoc f1=new File JavaDoc ( parentDir );
203             install = f1.getCanonicalPath();
204             if( installSysProp != null )
205                 System.getProperties().put( installSysProp,
206                             install );
207             if( home == null && homeSysProp != null )
208                 System.getProperties().put( homeSysProp, install );
209             return install;
210             } catch( Exception JavaDoc ex ) {
211             ex.printStackTrace();
212             }
213         }
214         }
215     }
216
217         // if install directory can't be found, use home as the default
218
if ( home != null ) {
219         System.getProperties().put( installSysProp, home );
220         return home;
221     }
222
223     return null;
224     }
225
226     /** Debug method, display the classpath
227      */

228     public static void displayClassPath( String JavaDoc msg, URL JavaDoc[] cp ) {
229     System.out.println(msg);
230     for( int i=0; i<cp.length; i++ ) {
231         System.out.println( cp[i].getFile() );
232     }
233     }
234
235     public static String JavaDoc PATH_SEPARATOR = System.getProperty("path.separator");
236     /**
237      * Adds classpath entries from a vector of URL's to the
238      * "tc_path_add" System property. This System property lists
239      * the classpath entries common to web applications. This System
240      * property is currently used by Jasper when its JSP servlet
241      * compiles the Java file for a JSP.
242     */

243     public static String JavaDoc classPathAdd(URL JavaDoc urls[], String JavaDoc cp )
244     {
245     if( urls==null ) return cp;
246
247     for( int i=0; i<urls.length; i++ ) {
248             if( cp != null)
249                 cp += PATH_SEPARATOR + urls[i].getFile();
250             else
251                 cp = urls[i].getFile();
252         }
253         return cp;
254     }
255
256     /** Find a method with the right name
257     If found, call the method ( if param is int or boolean we'll convert
258     value to the right type before) - that means you can have setDebug(1).
259     */

260     public static void setProperty( Object JavaDoc o, String JavaDoc name, String JavaDoc value ) {
261     if( dbg > 1 ) d("setProperty(" +
262             o.getClass() + " " + name + "=" +
263             value +")" );
264
265     String JavaDoc setter= "set" +capitalize(name);
266
267     try {
268         Method JavaDoc methods[]=findMethods( o.getClass() );
269         Method JavaDoc setPropertyMethod=null;
270
271         // First, the ideal case - a setFoo( String ) method
272
for( int i=0; i< methods.length; i++ ) {
273         Class JavaDoc paramT[]=methods[i].getParameterTypes();
274         if( setter.equals( methods[i].getName() ) &&
275             paramT.length == 1 &&
276             "java.lang.String".equals( paramT[0].getName())) {
277
278             methods[i].invoke( o, new Object JavaDoc[] { value } );
279             return;
280         }
281         }
282
283         // Try a setFoo ( int ) or ( boolean )
284
for( int i=0; i< methods.length; i++ ) {
285         boolean ok=true;
286         if( setter.equals( methods[i].getName() ) &&
287             methods[i].getParameterTypes().length == 1) {
288
289             // match - find the type and invoke it
290
Class JavaDoc paramType=methods[i].getParameterTypes()[0];
291             Object JavaDoc params[]=new Object JavaDoc[1];
292
293             // Try a setFoo ( int )
294
if ("java.lang.Integer".equals( paramType.getName()) ||
295             "int".equals( paramType.getName())) {
296             try {
297                 params[0]=new Integer JavaDoc(value);
298             } catch( NumberFormatException JavaDoc ex ) {ok=false;}
299
300             // Try a setFoo ( boolean )
301
} else if ("java.lang.Boolean".
302                    equals( paramType.getName()) ||
303             "boolean".equals( paramType.getName())) {
304             params[0]=new Boolean JavaDoc(value);
305
306             // Try a setFoo ( InetAddress )
307
} else if ("java.net.InetAddress".
308                 equals( paramType.getName())){
309             try{
310                 params[0]= InetAddress.getByName(value);
311             }catch(UnknownHostException JavaDoc exc) {
312                 d("Unable to resolve host name:" + value);
313                 ok=false;
314             }
315
316                     // Try a setFoo ( Object )
317
} else if ("java.lang.Object".
318                                equals( paramType.getName())) {
319                         params[0] = value;
320
321             // Unknown type
322
} else {
323             d("Unknown type " + paramType.getName() );
324             }
325
326             if( ok ) {
327             methods[i].invoke( o, params );
328             return;
329             }
330         }
331
332         // save "setProperty" for later
333
if( "setProperty".equals( methods[i].getName())) {
334             setPropertyMethod=methods[i];
335         }
336         }
337
338         // Ok, no setXXX found, try a setProperty("name", "value")
339
if( setPropertyMethod != null ) {
340         Object JavaDoc params[]=new Object JavaDoc[2];
341         params[0]=name;
342         params[1]=value;
343         setPropertyMethod.invoke( o, params );
344         }
345
346     } catch( IllegalArgumentException JavaDoc ex2 ) {
347             System.err.println("IAE " + o + " " + name + " " + value);
348             ex2.printStackTrace();
349     } catch( SecurityException JavaDoc ex1 ) {
350         if( dbg > 0 )
351         d("SecurityException for " + o.getClass() + " " +
352             name + "=" + value +")" );
353         if( dbg > 1 ) ex1.printStackTrace();
354     } catch (IllegalAccessException JavaDoc iae) {
355         if( dbg > 0 )
356         d("IllegalAccessException for " +
357             o.getClass() + " " + name + "=" + value +")" );
358         if( dbg > 1 ) iae.printStackTrace();
359     } catch (InvocationTargetException JavaDoc ie) {
360         if( dbg > 0 )
361         d("InvocationTargetException for " + o.getClass() +
362             " " + name + "=" + value +")" );
363         if( dbg > 1 ) ie.printStackTrace();
364     }
365     }
366
367     public static Object JavaDoc getProperty( Object JavaDoc o, String JavaDoc name ) {
368     String JavaDoc getter= "get" +capitalize(name);
369
370     try {
371         Method JavaDoc methods[]=findMethods( o.getClass() );
372         Method JavaDoc getPropertyMethod=null;
373
374         // First, the ideal case - a getFoo() method
375
for( int i=0; i< methods.length; i++ ) {
376         Class JavaDoc paramT[]=methods[i].getParameterTypes();
377         if( getter.equals( methods[i].getName() ) &&
378             paramT.length == 0 ) {
379             return methods[i].invoke( o, null );
380         }
381
382         if( "getProperty".equals( methods[i].getName())) {
383             getPropertyMethod=methods[i];
384         }
385         if( "getAttribute".equals( methods[i].getName())) {
386             getPropertyMethod=methods[i];
387         }
388         }
389
390         // Ok, no setXXX found, try a getProperty("name")
391
if( getPropertyMethod != null ) {
392         Object JavaDoc params[]=new Object JavaDoc[1];
393         params[0]=name;
394         getPropertyMethod.invoke( o, params );
395         }
396
397     } catch( IllegalArgumentException JavaDoc ex2 ) {
398             System.err.println("IAE " + o + " " + name );
399             ex2.printStackTrace();
400     } catch( SecurityException JavaDoc ex1 ) {
401         if( dbg > 0 )
402         d("SecurityException for " + o.getClass() + " " +
403             name + ")" );
404         if( dbg > 1 ) ex1.printStackTrace();
405     } catch (IllegalAccessException JavaDoc iae) {
406         if( dbg > 0 )
407         d("IllegalAccessException for " +
408             o.getClass() + " " + name +")" );
409         if( dbg > 1 ) iae.printStackTrace();
410     } catch (InvocationTargetException JavaDoc ie) {
411         if( dbg > 0 )
412         d("InvocationTargetException for " + o.getClass() +
413             " " + name +")" );
414         if( dbg > 1 ) ie.printStackTrace();
415     }
416         return null;
417     }
418
419     /**
420      */

421     public static void setProperty( Object JavaDoc o, String JavaDoc name ) {
422     String JavaDoc setter= "set" +capitalize(name);
423     try {
424         Method JavaDoc methods[]=findMethods( o.getClass() );
425         Method JavaDoc setPropertyMethod=null;
426         // find setFoo() method
427
for( int i=0; i< methods.length; i++ ) {
428         Class JavaDoc paramT[]=methods[i].getParameterTypes();
429         if( setter.equals( methods[i].getName() ) &&
430             paramT.length == 0 ) {
431             methods[i].invoke( o, new Object JavaDoc[] {} );
432             return;
433         }
434         }
435     } catch( Exception JavaDoc ex1 ) {
436         if( dbg > 0 )
437         d("Exception for " + o.getClass() + " " + name);
438         if( dbg > 1 ) ex1.printStackTrace();
439     }
440     }
441
442     /** Replace ${NAME} with the property value
443      * @deprecated Use the explicit method
444      */

445     public static String JavaDoc replaceProperties(String JavaDoc value,
446                        Object JavaDoc getter )
447     {
448         if( getter instanceof Hashtable JavaDoc )
449             return replaceProperties( value, (Hashtable JavaDoc)getter, null );
450
451         if( getter instanceof PropertySource ) {
452             PropertySource src[]=new PropertySource[] {(PropertySource)getter};
453             return replaceProperties( value, null, src);
454         }
455         return value;
456     }
457
458     /** Replace ${NAME} with the property value
459      */

460     public static String JavaDoc replaceProperties(String JavaDoc value,
461                        Hashtable JavaDoc staticProp, PropertySource dynamicProp[] )
462     {
463         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
464         int prev=0;
465         // assert value!=nil
466
int pos;
467         while( (pos=value.indexOf( "$", prev )) >= 0 ) {
468             if(pos>0) {
469                 sb.append( value.substring( prev, pos ) );
470             }
471             if( pos == (value.length() - 1)) {
472                 sb.append('$');
473                 prev = pos + 1;
474             }
475             else if (value.charAt( pos + 1 ) != '{' ) {
476                 sb.append( value.charAt( pos + 1 ) );
477                 prev=pos+2; // XXX
478
} else {
479                 int endName=value.indexOf( '}', pos );
480                 if( endName < 0 ) {
481             sb.append( value.substring( pos ));
482             prev=value.length();
483             continue;
484                 }
485                 String JavaDoc n=value.substring( pos+2, endName );
486         String JavaDoc v= null;
487         if( staticProp != null ) {
488             v=(String JavaDoc)((Hashtable JavaDoc)staticProp).get(n);
489         }
490                 if( v==null && dynamicProp != null) {
491                     for( int i=0; i<dynamicProp.length; i++ ) {
492                         v=dynamicProp[i].getProperty( n );
493                         if( v!=null ) {
494                             break;
495                         }
496                     }
497         }
498         if( v== null )
499             v = "${"+n+"}";
500
501                 sb.append( v );
502                 prev=endName+1;
503             }
504         }
505         if( prev < value.length() ) sb.append( value.substring( prev ) );
506         return sb.toString();
507     }
508
509     /** Reverse of Introspector.decapitalize
510      */

511     public static String JavaDoc capitalize(String JavaDoc name) {
512     if (name == null || name.length() == 0) {
513         return name;
514     }
515     char chars[] = name.toCharArray();
516     chars[0] = Character.toUpperCase(chars[0]);
517     return new String JavaDoc(chars);
518     }
519
520     public static String JavaDoc unCapitalize(String JavaDoc name) {
521     if (name == null || name.length() == 0) {
522         return name;
523     }
524     char chars[] = name.toCharArray();
525     chars[0] = Character.toLowerCase(chars[0]);
526     return new String JavaDoc(chars);
527     }
528
529     // -------------------- Class path tools --------------------
530

531     /** Add all the jar files in a dir to the classpath,
532      * represented as a Vector of URLs.
533      */

534     public static void addToClassPath( Vector JavaDoc cpV, String JavaDoc dir ) {
535     try{
536             String JavaDoc cpComp[]=getFilesByExt(dir, ".jar");
537             if (cpComp != null){
538                 int jarCount=cpComp.length;
539                 for( int i=0; i< jarCount ; i++ ) {
540             URL JavaDoc url=getURL( dir , cpComp[i] );
541                     if( url!=null )
542             cpV.addElement( url );
543                 }
544             }
545         }catch(Exception JavaDoc ex){
546             ex.printStackTrace();
547         }
548     }
549
550
551     public static void addToolsJar( Vector JavaDoc v )
552     {
553     try {
554             // Add tools.jar in any case
555
File JavaDoc f=new File JavaDoc( System.getProperty( "java.home" ) +
556                              "/../lib/tools.jar");
557
558             if( ! f.exists() ) {
559                 // On some systems java.home gets set to the root of jdk.
560
// That's a bug, but we can work around and be nice.
561
f=new File JavaDoc( System.getProperty( "java.home" ) +
562                                  "/lib/tools.jar");
563                 if( f.exists() ) {
564                     System.out.println("Detected strange java.home value " +
565                                        System.getProperty( "java.home" ) +
566                                        ", it should point to jre");
567                 }
568             }
569             URL JavaDoc url=new URL JavaDoc( "file", "" , f.getAbsolutePath() );
570
571         v.addElement( url );
572     } catch ( MalformedURLException JavaDoc ex ) {
573         ex.printStackTrace();
574     }
575     }
576
577
578     /** Return all files with a given extension in a dir
579      */

580     public static String JavaDoc[] getFilesByExt( String JavaDoc ld, String JavaDoc ext ) {
581     File JavaDoc dir = new File JavaDoc(ld);
582         String JavaDoc[] names=null;
583     final String JavaDoc lext=ext;
584         if (dir.isDirectory()){
585             names = dir.list( new FilenameFilter JavaDoc(){
586             public boolean accept(File JavaDoc d, String JavaDoc name) {
587                 if (name.endsWith(lext)){
588                     return true;
589                 }
590                 return false;
591             }
592             });
593         }
594     return names;
595     }
596
597
598     /** Construct a file url from a file, using a base dir
599      */

600     public static URL JavaDoc getURL( String JavaDoc base, String JavaDoc file ) {
601         try {
602             File JavaDoc baseF = new File JavaDoc(base);
603             File JavaDoc f = new File JavaDoc(baseF,file);
604             String JavaDoc path = f.getCanonicalPath();
605             if( f.isDirectory() ){
606                     path +="/";
607             }
608         if( ! f.exists() ) return null;
609             return new URL JavaDoc( "file", "", path );
610         } catch (Exception JavaDoc ex) {
611             ex.printStackTrace();
612             return null;
613         }
614     }
615
616     /**
617      * add elements from the classpath <i>cp</i> to a Vector
618      * <i>jars</i> as file URLs (We use Vector for JDK 1.1 compat).
619      *
620      * @param jars A vector of URLs
621      * @param cp a String classpath of directory or jar file
622      * elements separated by path.separator delimiters.
623      */

624     public static void addJarsFromClassPath(Vector JavaDoc jars, String JavaDoc cp)
625             throws IOException JavaDoc,MalformedURLException JavaDoc
626     {
627         String JavaDoc sep = System.getProperty("path.separator");
628         String JavaDoc token;
629         StringTokenizer JavaDoc st;
630         if(cp!=null){
631             st = new StringTokenizer JavaDoc(cp,sep);
632             while(st.hasMoreTokens()){
633                 File JavaDoc f = new File JavaDoc(st.nextToken());
634                 String JavaDoc path = f.getCanonicalPath();
635                 if(f.isDirectory()){
636                         path += "/";
637                 }
638                 URL JavaDoc url = new URL JavaDoc("file","",path);
639                 if(!jars.contains(url)){
640                         jars.addElement(url);
641                 }
642             }
643         }
644     }
645
646     /** Return a URL[] that can be used to construct a class loader
647      */

648     public static URL JavaDoc[] getClassPath(Vector JavaDoc v){
649         URL JavaDoc[] urls=new URL JavaDoc[ v.size() ];
650         for( int i=0; i<v.size(); i++ ) {
651             urls[i]=(URL JavaDoc)v.elementAt( i );
652         }
653         return urls;
654     }
655
656     /** Construct a URL classpath from files in a directory,
657      * a cpath property, and tools.jar.
658      */

659     public static URL JavaDoc[] getClassPath( String JavaDoc dir, String JavaDoc cpath,
660                       String JavaDoc cpathProp, boolean addTools )
661     throws IOException JavaDoc, MalformedURLException JavaDoc
662     {
663     Vector JavaDoc jarsV = new Vector JavaDoc();
664     if( dir!=null ) {
665         // Add dir/classes first, if it exists
666
URL JavaDoc url=getURL( dir, "classes");
667         if( url!=null )
668         jarsV.addElement(url);
669         addToClassPath( jarsV, dir );
670     }
671
672     if( cpath != null )
673         addJarsFromClassPath(jarsV,cpath);
674
675     if( cpathProp!=null ) {
676         String JavaDoc cpath1=System.getProperty( cpathProp );
677         addJarsFromClassPath(jarsV,cpath1);
678     }
679
680     if(addTools)
681         addToolsJar( jarsV );
682
683     return getClassPath(jarsV);
684     }
685
686