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