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
16package javassist.tools.reflect;
17
18import javassist.CtClass;
19import javassist.ClassPool;
20import java.io.PrintStream;
21
22class 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 */
70public class Compiler {
71
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
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
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
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