KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > util > WrapLib


1 /*
2   Copyright (C) 2001-2003 Renaud Pawlak.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.util;
19
20 import java.io.*;
21 import java.util.*;
22 import java.lang.reflect.*;
23
24 /**
25  * This class generates the <code>jac.lib</code> delegators
26  * source-files from the <code>jac.prop</code> file found in the
27  * current directory (exclude all other options).
28  *
29  * @author Renaud Pawlak */

30
31 public class WrapLib {
32
33    public static String JavaDoc listAsString(List l) {
34       String JavaDoc s="[";
35       for(int i=0;i<l.size();i++) {
36          s=s+l.get(i);
37          if(i+1<l.size()) s=s+",";
38       }
39       return s;
40    }
41
42    /**
43     * The entry point of the wraplib program.
44     *
45     * @param args none arguments are expected (parametrization is done
46     * by the <code>jac.prop</code> file in the current directory --
47     * user should define the jac.toWrap property as a list of classes
48     * to wrap */

49
50    public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
51       String JavaDoc propFileName = "jac.prop";
52       String JavaDoc toAdaptProp = "jac.toWrap";
53       Properties props;
54       Vector classesToAdapt = new Vector();
55       /** Try to load a jac.prop file from the current directory */
56       try {
57     
58          FileInputStream fis = new FileInputStream( propFileName );
59          
60          props = new Properties();
61          props.load( fis );
62          String JavaDoc prop = props.getProperty(toAdaptProp);
63          
64          if ( prop == null ) {
65             System.out.println( "-- ERROR: no property jac.toAdapt found in property file "+propFileName );
66             System.exit(-1);
67             
68          } else {
69             
70             StringTokenizer st = new StringTokenizer( prop );
71             while ( st.hasMoreElements() )
72                classesToAdapt.add( st.nextElement() );
73          }
74          
75          
76             for ( int i = 0; i < classesToAdapt.size(); i++ ) {
77                createDelegator( Class.forName( (String JavaDoc) classesToAdapt.get(i) ));
78             }
79             
80       }
81       catch( FileNotFoundException e ) {
82          System.out.println( "-- ERROR: property file "+propFileName+" not found" );
83          System.exit(-1);
84       }
85       catch( Exception JavaDoc e ) { e.printStackTrace(); }
86    }
87
88    /**
89     * Creates a class that present the same interface that the
90     * original class but that delegates all the work to an instance of
91     * the original class.
92     *
93     * <p>This feature is implemented to be able to easily wrap
94     * libraries that would have been hardly wrappable on the "as is"
95     * classes, for instance the jdk classes (see the -g option of Jac).
96     *
97     * <p>As a result, this method creates a Java source file in the
98     * src/org/objectweb/jac/lib directory of the JAC distribution. This file should
99     * then be compiled as a regular file.
100     *
101     * @param c the original class */

102
103    protected static void createDelegator( Class JavaDoc c ) {
104       try {
105          System.out.println("-- Generating delegator version of " + c + ".");
106          File f = new File(
107             "src/org/objectweb/jac/lib/" + c.getName().replace('.','/') + ".java" );
108          if ( f.exists() )
109             f.delete();
110          f.getParentFile().mkdirs();
111          f.createNewFile();
112          String JavaDoc shortName = c.getName().substring( c.getName().lastIndexOf('.') + 1 );
113          FileWriter fw = new FileWriter( f );
114          fw.write( "/**\n" +
115                    " * This class delegates to " + c.getName() + "\n" +
116                    " * This file was automatically generated by JAC (-g option)\n" +
117                    " * DO NOT MODIFY\n" +
118                    " * Author: Renaud Pawlak (pawlak@cnam.fr)\n" +
119                    " */\n" );
120          fw.write( "\npackage jac.lib." + c.getPackage().getName() + ";\n" );
121          fw.write( "\npublic class " + shortName + ((c.getInterfaces().length == 0)? "" : " implements " +
122                    arrayToString( createArray( c.getInterfaces() ) )) );
123          fw.write( " {\n" );
124          fw.write( "\n private " + c.getName() + " delegate = new " + c.getName() + "();\n" );
125          fw.write( "\n public Object clone() {\n Object result=null;\n try { result=super.clone(); } catch(Exception e) {};\n (("+ shortName +")result).delegate=("+c.getName()+")delegate.clone();\n return result;\n }\n");
126      fw.write( "\n public boolean equals(Object o1) {\n return (delegate==null?super.equals(o1):delegate.equals(o1));\n }\n");
127          //fw.write( "\n public String toString() {\n return delegate.toString();\n }\n");
128
Method[] ms = c.getMethods();
129          for ( int i = 0; i < ms.length; i++ ) {
130             int mod = ms[i].getModifiers();
131             if( Modifier.isPrivate(mod) || Modifier.isAbstract(mod) ||
132                 Modifier.isInterface(mod) || Modifier.isProtected(mod) ||
133                 Modifier.isStatic(mod) ) continue;
134             if( ms[i].getName().equals("clone") ) continue;
135             //if( ms[i].getName().equals("hashCode") ) continue;
136
if( ms[i].getDeclaringClass() == Object JavaDoc.class ||
137                 ms[i].getDeclaringClass().isInterface() ) continue;
138             
139             try {
140                Object JavaDoc.class.getMethod( ms[i].getName(), ms[i].getParameterTypes() );
141                continue;
142             } catch ( Exception JavaDoc e ) {}
143
144             fw.write( "\n " + getMethodPrototype( ms[i] ) + " {\n" );
145             if ( ms[i].getReturnType().getName().equals( "void" ) ) {
146                // fw.write( " if ( delegate == null ) return;\n" );
147
fw.write( " delegate." + ms[i].getName() + "(" +
148                arrayToString( createParameterNames( ms[i].getParameterTypes() ) ) + ");\n" );
149             } else {
150                // fw.write( " if ( delegate == null ) return " +
151
// getDefaultValueFor( ms[i].getReturnType() ) + ";\n" );
152
fw.write( " return delegate." + ms[i].getName() + "(" +
153                arrayToString( createParameterNames( ms[i].getParameterTypes() ) ) + ");\n" );
154             }
155             fw.write( " }\n" );
156          }
157          fw.write( "}\n" );
158          fw.close();
159       } catch ( Exception JavaDoc e ) {
160          e.printStackTrace();
161       }
162    }
163
164    /**
165     * Return the default string value that should return a method with
166     * a <code>c</code> return type.
167     *
168     * <p>By default:
169     *
170     * <ul><pre>
171     * - c == boolean => "false"
172     * - c == char => "''"
173     * - c == byte => "0"
174     * - c == all other primitive types => "-1"
175     * - c is an object => "null"
176     * </pre></ul>
177     *
178     * @param c the type
179     * @return the default string value for this type */

180
181    private static String JavaDoc getDefaultValueFor( Class JavaDoc c ) {
182       if ( c.isPrimitive() ) {
183          if (c == Boolean.TYPE )
184             return "false";
185          if (c == Character.TYPE )
186             return "''";
187          if ( c == Byte.TYPE )
188             return "0";
189          if (c == Short.TYPE || c == Integer.TYPE ||
190              c == Long.TYPE || c == Float.TYPE || c == Double.TYPE )
191             return "-1";
192       }
193       return "null";
194    }
195
196    /**
197     * Return a Java-syntax-compiliant string representation of the
198     * given method.
199     *
200     * @param m the method
201     * @return the string representation
202     */

203
204    private static String JavaDoc getMethodPrototype( Method m ) {
205       return "public " + createStringFor( m.getReturnType() ) + " " + m.getName() +
206          " ( " + arrayToString( createTypedParameterNames( m.getParameterTypes() ) ) +
207          " ) " + arrayToString( createArray( m.getExceptionTypes() ) );
208    }
209    
210    /**
211     * Return a comma-separated string for a string array.
212     *
213     * <p>For instance:
214     *
215     * <ul><pre>
216     * - {"a", "b", "c"} => "a, b, c"
217     * - {"a"} => "a"
218     * - {} => ""
219     * </pre></ul>
220     *
221     * @param array the given array
222     * @return its string representation
223     */

224
225    private static String JavaDoc arrayToString( String JavaDoc[] array ) {
226       if ( array.length == 0 ) return "";
227       String JavaDoc ls = java.util.Arrays.asList(array).toString();
228       return ls.substring( 1, ls.length() - 1 );
229    }
230
231    /**
232     * Create an array of Java-syntax-compiliant string from an array of types.
233     *
234     * <p>For instance:
235     *
236     * <ul><pre>
237     * - {class int, class java.lang.object} => {"int", "java.lang.Object"}
238     * - {class [java.lang.object} => {"java.lang.Object[]"}
239     * </pre></ul>
240     *
241     * @param array the types
242     * @return the corresponding strings
243     *
244     * @see #createStringFor(Class)
245     */

246    
247    private static String JavaDoc[] createArray( Class JavaDoc[] array ) {
248       String JavaDoc[] res = new String JavaDoc[array.length];
249       for ( int i = 0; i < array.length; i ++ ) {
250          res[i] = createStringFor( array[i] );
251       }
252       return res;
253    }
254
255    /**
256     * Create a Java-syntax-compiliant string from a type.
257     *
258     * <p>For instance:
259     *
260     * <ul><pre>
261     * - class java.lang.object => "java.lang.Object"
262     * - class [java.lang.object => "java.lang.Object[]"
263     * </pre></ul>
264     *
265     * @param c the type
266     * @return the corresponding string
267     */

268
269    private static String JavaDoc createStringFor ( Class JavaDoc c ) {
270       if ( c.isArray() ) {
271          return c.getComponentType().getName() + "[]";
272       } else {
273          return c.getName();
274       }
275    }
276
277    /**
278     * Create a Java-syntax-compiliant string for a method that would
279     * take a set of parameters defined in <code>array</code>.
280     *
281     * <p>The parameter names are generated to "p[0-array.length]". For
282     * instance:
283     *
284     * <ul><pre>
285     * - {class int, class byte} => {"int p0", "byte p1"}
286     * </pre></ul>
287     *
288     * @param array the types
289     * @param the resulting strings
290     *
291     * @see #createParametersName( array ) */

292
293    private static String JavaDoc[] createTypedParameterNames ( Class JavaDoc[] array ) {
294       String JavaDoc[] res = new String JavaDoc[array.length];
295       for ( int i = 0; i < array.length; i ++ ) {
296          res[i] = createStringFor( array[i] ) + " p" + i;
297       }
298       return res;
299    }
300
301    /**
302     * Create untyped paramameter names that correspond to the names
303     * that would have been given by the
304     * <code>createTypedParameterNames</code>.
305     *
306     * <p>For instance, an array of 2 types always returns:
307     *
308     * <ul><pre>
309     * {"p0, "p1"}
310     * </pre></ul>
311     *
312     * @param array the types
313     * @param the resulting strings
314     *
315     * @see #createTypedParametersName( array ) */

316
317    private static String JavaDoc[] createParameterNames ( Class JavaDoc[] array ) {
318       String JavaDoc[] res = new String JavaDoc[array.length];
319       for ( int i = 0; i < array.length; i ++ ) {
320          res[i] = "p" + i;
321       }
322       return res;
323    }
324    
325 }
326
327
Popular Tags