/Users/lyon/j4p/src/javassist/reflect/Compiler.java

1    /* 
2     * Javassist, a Java-bytecode translator toolkit. 
3     * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. 
4     * 
5     * The contents of this file are subject to the Mozilla Public License Version 
6     * 1.1 (the "License"); you may not use this file except in compliance with 
7     * the License.  Alternatively, the contents of this file may be used under 
8     * the terms of the GNU Lesser General Public License Version 2.1 or later. 
9     * 
10    * Software distributed under the License is distributed on an "AS IS" basis, 
11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
12    * for the specific language governing rights and limitations under the 
13    * License. 
14    */ 
15    
16   package javassist.reflect; 
17    
18   import javassist.CtClass; 
19   import javassist.ClassPool; 
20    
21   import java.io.PrintStream; 
22    
23   class CompiledClass { 
24       public String classname; 
25       public String metaobject; 
26       public String classobject; 
27   } 
28    
29   /** 
30    * A bytecode translator for reflection. 
31    * 
32    * <p>This translator directly modifies class files on a local disk so that 
33    * the classes represented by those class files are reflective. 
34    * After the modification, the class files can be run with the standard JVM 
35    * without <code>javassist.reflect.Loader</code> 
36    * or any other user-defined class loader. 
37    * 
38    * <p>The modified class files are given as the command-line parameters, 
39    * which are a sequence of fully-qualified class names followed by options: 
40    * 
41    * <p><code>-m <i>classname</i></code> : specifies the class of the 
42    * metaobjects associated with instances of the class followed by 
43    * this option.  The default is <code>javassit.reflect.Metaobject</code>. 
44    * 
45    * <p><code>-c <i>classname</i></code> : specifies the class of the 
46    * class metaobjects associated with instances of the class followed by 
47    * this option.  The default is <code>javassit.reflect.ClassMetaobject</code>. 
48    * 
49    * <p>If a class name is not followed by any options, the class indicated 
50    * by that class name is not reflective. 
51    * 
52    * <p>For example, 
53    * <ul><pre>% java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow 
54    * </pre></ul> 
55    * 
56    * <p>modifies class files <code>Dog.class</code>, <code>Cat.class</code>, 
57    * and <code>Cow.class</code>. 
58    * The metaobject of a Dog object is a MetaDog object and the class 
59    * metaobject is a CMetaDog object. 
60    * The metaobject of a Cat object is a MetaCat object but 
61    * the class metaobject is a default one. 
62    * Cow objects are not reflective. 
63    * 
64    * <p>Note that if the super class is also made reflective, it must be done 
65    * before the sub class. 
66    * 
67    * @see javassist.reflect.Metaobject 
68    * @see javassist.reflect.ClassMetaobject 
69    * @see javassist.reflect.Reflection 
70    */ 
71   public class Compiler { 
72    
73       public static void main(String[] args) throws Exception { 
74           if (args.length == 0) { 
75               help(System.err); 
76               return; 
77           } 
78    
79           CompiledClass[] entries = new CompiledClass[args.length]; 
80           int n = parse(args, entries); 
81    
82           if (n < 1) { 
83               System.err.println("bad parameter."); 
84               return; 
85           } 
86    
87           processClasses(entries, n); 
88       } 
89    
90       private static void processClasses(CompiledClass[] entries, int n) 
91               throws Exception { 
92           Reflection implementor = new Reflection(); 
93           ClassPool pool = ClassPool.getDefault(implementor); 
94    
95           for (int i = 0; i < n; ++i) { 
96               CtClass c = pool.get(entries[i].classname); 
97               if (entries[i].metaobject != null 
98                       || entries[i].classobject != null) { 
99                   String metaobj, classobj; 
100   
101                  if (entries[i].metaobject == null) 
102                      metaobj = "javassist.reflect.Metaobject"; 
103                  else 
104                      metaobj = entries[i].metaobject; 
105   
106                  if (entries[i].classobject == null) 
107                      classobj = "javassist.reflect.ClassMetaobject"; 
108                  else 
109                      classobj = entries[i].classobject; 
110   
111                  if (!implementor.makeReflective(c, pool.get(metaobj), 
112                          pool.get(classobj))) 
113                      System.err.println("Warning: " + c.getName() 
114                              + " is reflective.  It was not changed."); 
115   
116                  System.err.println(c.getName() + ": " + metaobj + ", " 
117                          + classobj); 
118              } else 
119                  System.err.println(c.getName() + ": not reflective"); 
120          } 
121   
122          for (int i = 0; i < n; ++i) 
123              pool.writeFile(entries[i].classname); 
124      } 
125   
126      private static int parse(String[] args, CompiledClass[] result) { 
127          int n = -1; 
128          for (int i = 0; i < args.length; ++i) { 
129              String a = args[i]; 
130              if (a.equals("-m")) 
131                  if (n < 0 || i + 1 > args.length) 
132                      return -1; 
133                  else 
134                      result[n].metaobject = args[++i]; 
135              else if (a.equals("-c")) 
136                  if (n < 0 || i + 1 > args.length) 
137                      return -1; 
138                  else 
139                      result[n].classobject = args[++i]; 
140              else if (a.charAt(0) == '-') 
141                  return -1; 
142              else { 
143                  CompiledClass cc = new CompiledClass(); 
144                  cc.classname = a; 
145                  cc.metaobject = null; 
146                  cc.classobject = null; 
147                  result[++n] = cc; 
148              } 
149          } 
150   
151          return n + 1; 
152      } 
153   
154      private static void help(PrintStream out) { 
155          out.println("Usage: java javassist.reflect.Compiler"); 
156          out.println("            (<class> [-m <metaobject>] [-c <class metaobject>])+"); 
157      } 
158  } 
159