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