KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > java > AbstractGenerator


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.java;
31
32 import com.caucho.java.gen.DependencyComponent;
33 import com.caucho.java.gen.GenClass;
34 import com.caucho.loader.SimpleLoader;
35 import com.caucho.server.util.CauchoSystem;
36 import com.caucho.util.CharBuffer;
37 import com.caucho.vfs.IOExceptionWrapper;
38 import com.caucho.vfs.Path;
39 import com.caucho.vfs.PersistentDependency;
40 import com.caucho.vfs.WriteStream;
41
42 import java.io.IOException JavaDoc;
43 import java.lang.reflect.Method JavaDoc;
44 import java.util.ArrayList JavaDoc;
45
46 /**
47  * Generates the Java code for the wrapped object.
48  */

49 public abstract class AbstractGenerator {
50   // The full name of the generated class
51
private String JavaDoc _fullClassName;
52   // The package of the generated class
53
private String JavaDoc _packageName;
54   // The class name of the generated class
55
private String JavaDoc _className;
56   
57   // Parent class loader
58
private ClassLoader JavaDoc _parentLoader;
59   // class loader
60
private ClassLoader JavaDoc _loader;
61   
62   // Write stream for generating the code
63
private WriteStream _os;
64   // The java writer
65
protected JavaWriter _out;
66   
67   // The search path
68
private Path _searchPath;
69
70   // The work directory
71
private Path _workPath;
72
73   private GenClass _genClass;
74
75   private String JavaDoc _initMethod = "_caucho_init";
76   private String JavaDoc _isModifiedMethod = "_caucho_is_modified";
77   
78   /**
79    * Sets the search path.
80    */

81   public void setSearchPath(Path path)
82   {
83     _searchPath = path;
84   }
85
86   public Path getSearchPath()
87   {
88     return _searchPath;
89   }
90
91   /**
92    * Sets the full generated class.
93    */

94   public void setFullClassName(String JavaDoc fullClassName)
95   {
96     CharBuffer cb = CharBuffer.allocate();
97     for (int i = 0; i < fullClassName.length(); i++) {
98       char ch = fullClassName.charAt(i);
99
100       if (ch == '.' || ch == '/')
101     cb.append('.');
102       else if (Character.isJavaIdentifierPart(ch))
103     cb.append(ch);
104       else
105     cb.append('_');
106     }
107     
108     _fullClassName = cb.close();
109
110     int p = _fullClassName.lastIndexOf('.');
111     if (p > 0) {
112       _packageName = _fullClassName.substring(0, p);
113       _className = _fullClassName.substring(p + 1);
114     }
115     else {
116       _packageName = "";
117       _className = _fullClassName;
118     }
119   }
120   
121   /**
122    * Returns the full class name
123    */

124   public String JavaDoc getFullClassName()
125   {
126     if (_genClass != null)
127       return _genClass.getFullClassName();
128     else
129       return _fullClassName;
130   }
131   
132   /**
133    * Returns the generated package name
134    */

135   public String JavaDoc getPackageName()
136   {
137     if (_genClass != null)
138       return _genClass.getPackageName();
139     else
140       return _packageName;
141   }
142   
143   /**
144    * Returns the generated class name
145    */

146   public String JavaDoc getClassName()
147   {
148     if (_genClass != null)
149       return _genClass.getClassName();
150     else
151       return _className;
152   }
153
154   /**
155    * Sets the java class.
156    */

157   public void setGenClass(GenClass genClass)
158   {
159     _genClass = genClass;
160   }
161
162   /**
163    * Gets the java class.
164    */

165   public GenClass getGenClass()
166   {
167     return _genClass;
168   }
169   
170   /**
171    * Sets the parent class loader.
172    *
173    * @param loader parent class loader
174    */

175   public void setParentLoader(ClassLoader JavaDoc loader)
176   {
177     _parentLoader = loader;
178   }
179   
180   /**
181    * Sets the class loader.
182    *
183    * @param loader parent class loader
184    */

185   public void setLoader(ClassLoader JavaDoc loader)
186   {
187     _loader = loader;
188   }
189
190   /**
191    * Sets the parent class loader.
192    *
193    * @return the parent class loader
194    */

195   public ClassLoader JavaDoc getParentLoader()
196   {
197     if (_parentLoader == null)
198       _parentLoader = Thread.currentThread().getContextClassLoader();
199     
200     return _parentLoader;
201   }
202
203   /**
204    * Sets the work path for the generated class.
205    */

206   public void setClassDir(Path workPath)
207   {
208     _workPath = workPath;
209   }
210   
211   /**
212    * Returns the class dir for the generated class.
213    */

214   public Path getClassDir()
215   {
216     if (_workPath == null)
217       return CauchoSystem.getWorkPath();
218     else
219       return _workPath;
220   }
221
222   /**
223    * Try to preload the class.
224    *
225    * @return true if the preloaded class is still valid.
226    */

227   public Class JavaDoc preload()
228     throws IOException JavaDoc
229   {
230     return loadClass(true);
231   }
232
233   /**
234    * Call to generate the java source.
235    */

236   public void generate()
237     throws Exception JavaDoc
238   {
239     String JavaDoc className = getFullClassName();
240     String JavaDoc javaPathName = className.replace('.', '/') + ".java";
241     String JavaDoc classPathName = className.replace('.', '/') + ".class";
242
243     Path javaPath = getClassDir().lookup(javaPathName);
244     Path classPath = getClassDir().lookup(classPathName);
245
246     try {
247       classPath.remove();
248     } catch (IOException JavaDoc e) {
249     }
250
251     javaPath.getParent().mkdirs();
252
253     _os = javaPath.openWrite();
254     _out = new JavaWriter(_os);
255
256     if (_genClass != null)
257       _genClass.generate(_out);
258     else
259       generateJava();
260
261     _os.close();
262   }
263
264   /**
265    * Compiles the Java code
266    */

267   public Class JavaDoc compile()
268     throws Exception JavaDoc
269   {
270     compileJava();
271     
272     return loadClass(false);
273   }
274   
275   /**
276    * Starts generation of the Java code
277    */

278   public void generateJava()
279     throws Exception JavaDoc
280   {
281   }
282
283   /**
284    * Generates the class dependency code.
285    *
286    * @param depends list of Paths representing dependencies
287    */

288   protected void printDependList(ArrayList JavaDoc<PersistentDependency> depends)
289     throws IOException JavaDoc
290   {
291     DependencyComponent depend = new DependencyComponent();
292     depend.setSearchPath(_searchPath);
293
294     for (int i = 0; i < depends.size(); i++)
295       depend.addDependency(depends.get(i));
296
297     depend.generate(getOut());
298   }
299
300   /**
301    * Prints code to detect a version change.
302    */

303   protected void printVersionChange()
304     throws IOException JavaDoc
305   {
306     println("if (com.caucho.server.util.CauchoSystem.getVersionId() != " +
307             CauchoSystem.getVersionId() + ")");
308     println(" return true;");
309   }
310
311   /**
312    * Prints a method header.
313    *
314    * @param method the method to print
315    */

316   public void printMethodHeader(Method JavaDoc method)
317     throws IOException JavaDoc
318   {
319     printMethodHeader(method.getName(), method.getParameterTypes(),
320                       method.getReturnType(), method.getExceptionTypes());
321   }
322
323   /**
324    * Prints a method header.
325    *
326    * @param name the method name to print
327    * @param method the method to print
328    */

329   public void printMethodHeader(String JavaDoc name, Method JavaDoc method)
330     throws IOException JavaDoc
331   {
332     printMethodHeader(name, method.getParameterTypes(),
333                       method.getReturnType(), method.getExceptionTypes());
334   }
335   
336   /**
337    * Prints a method header.
338    *
339    * @param methodName the method name to print
340    * @param param the method argument classes
341    * @param returnType the return type of the method
342    * @param exn array of exceptions thrown by the method
343    */

344   public void printMethodHeader(String JavaDoc methodName, Class JavaDoc []parameters,
345                 Class JavaDoc returnType, Class JavaDoc []exn)
346     throws IOException JavaDoc
347   {
348     println();
349     print("public ");
350     printClass(returnType);
351     print(" ");
352     print(methodName);
353     print("(");
354
355     for (int i = 0; i < parameters.length; i++) {
356       if (i != 0)
357         print(", ");
358
359       printClass(parameters[i]);
360       print(" a" + i);
361     }
362     println(")");
363
364     if (exn != null && exn.length > 0) {
365       print(" throws ");
366       printClass(exn[0]);
367       
368       for (int i = 1; i < exn.length; i++) {
369         print(", ");
370         printClass(exn[i]);
371       }
372       println();
373     }
374   }
375   
376   /**
377    * Prints the Java represention of the class
378    */

379   public void printClass(Class JavaDoc cl)
380     throws IOException JavaDoc
381   {
382     if (! cl.isArray())
383       print(cl.getName().replace('$', '.'));
384     else {
385       printClass(cl.getComponentType());
386       print("[]");
387     }
388   }
389   
390   /**
391    * Compiles the class.
392    */

393   public void compileJava()
394     throws IOException JavaDoc, ClassNotFoundException JavaDoc
395   {
396     JavaCompiler compiler = getCompiler();
397     
398     compiler.compile(getFullClassName().replace('.', '/') + ".java", null);
399   }
400
401   public JavaCompiler getCompiler()
402   {
403     JavaCompiler compiler = JavaCompiler.create(getParentLoader());
404
405     compiler.setClassLoader(getParentLoader());
406     compiler.setClassDir(getClassDir());
407
408     return compiler;
409   }
410
411   /**
412    * Loads the generated class. If any class dependencies have
413    * changed, return null.
414    */

415   public Class JavaDoc loadClass(boolean preload)
416     throws IOException JavaDoc
417   {
418     return loadClass(getFullClassName(), preload);
419   }
420
421   /**
422    * Loads the generated class. If any class dependencies have
423    * changed, return null.
424    */

425   public Class JavaDoc loadClass(String JavaDoc fullClassName, boolean preload)
426     throws IOException JavaDoc
427   {
428     try {
429       ClassLoader JavaDoc loader;
430
431       if (! preload && _loader != null)
432         loader = _loader;
433       else {
434         loader = SimpleLoader.create(getParentLoader(),
435                                      getClassDir(),
436                                      fullClassName);
437       }
438
439       Class JavaDoc cl = CauchoSystem.loadClass(fullClassName, false, loader);
440
441
442       if (cl == null)
443         return null;
444       if (! preload)
445         return cl;
446
447       Method JavaDoc method = cl.getMethod(_initMethod, new Class JavaDoc[] { Path.class });
448       method.invoke(null, new Object JavaDoc[] { getSearchPath() });
449
450       method = cl.getMethod(_isModifiedMethod, new Class JavaDoc[0]);
451       Boolean JavaDoc value = (Boolean JavaDoc) method.invoke(null, new Object JavaDoc[] {});
452
453       if (value.booleanValue())
454         return null;
455
456       if (_loader != null)
457         loader = _loader;
458       else {
459         loader = SimpleLoader.create(getParentLoader(),
460                                      getClassDir(),
461                                      fullClassName);
462       }
463
464       return CauchoSystem.loadClass(fullClassName, false, loader);
465     } catch (Throwable JavaDoc e) {
466       if (! preload)
467         throw new IOExceptionWrapper(e);
468       else
469         return null;
470     }
471   }
472
473   /**
474    * Returns the java writer.
475    */

476   public JavaWriter getOut()
477   {
478     return _out;
479   }
480
481   /**
482    * Pushes an indentation depth.
483    */

484   public void pushDepth()
485     throws IOException JavaDoc
486   {
487     _out.pushDepth();
488   }
489
490   /**
491    * Pops an indentation depth.
492    */

493   public void popDepth()
494     throws IOException JavaDoc
495   {
496     _out.popDepth();
497   }
498
499   /**
500    * Prints a character
501    */

502   public void print(int ch)
503     throws IOException JavaDoc
504   {
505     _out.print(ch);
506   }
507
508   /**
509    * Prints a character
510    */

511   public void print(char ch)
512     throws IOException JavaDoc
513   {
514     _out.print(ch);
515   }
516
517   /**
518    * Prints a string
519    */

520   public void print(String JavaDoc s)
521     throws IOException JavaDoc
522   {
523     _out.print(s);
524   }
525
526   /**
527    * Prints a string
528    */

529   public void printStr(String JavaDoc s)
530     throws IOException JavaDoc
531   {
532     int len = s.length();
533     for (int i = 0; i < len; i++) {
534       char ch = s.charAt(i);
535
536       switch (ch) {
537       case '\\':
538         _out.print("\\\\");
539         break;
540       case '\n':
541         _out.print("\\n");
542         break;
543       case '\r':
544         _out.print("\\r");
545         break;
546       case '"':
547         _out.print("\\\"");
548         break;
549       default:
550         _out.print(ch);
551       }
552     }
553   }
554
555   /**
556    * Prints a new line.
557    */

558   public void println()
559     throws IOException JavaDoc
560   {
561     _out.println();
562   }
563
564   /**
565    * Prints a string with a new line
566    */

567   public void println(String JavaDoc s)
568     throws IOException JavaDoc
569   {
570     _out.println(s);
571   }
572 }
573
Popular Tags