001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.tools.reflect;
017:
018: import javassist.CtClass;
019: import javassist.ClassPool;
020: import java.io.PrintStream;
021:
022: class CompiledClass {
023: public String classname;
024: public String metaobject;
025: public String classobject;
026: }
027:
028: /**
029: * A bytecode translator for reflection.
030: *
031: * <p>This translator directly modifies class files on a local disk so that
032: * the classes represented by those class files are reflective.
033: * After the modification, the class files can be run with the standard JVM
034: * without <code>javassist.tools.reflect.Loader</code>
035: * or any other user-defined class loader.
036: *
037: * <p>The modified class files are given as the command-line parameters,
038: * which are a sequence of fully-qualified class names followed by options:
039: *
040: * <p><code>-m <i>classname</i></code> : specifies the class of the
041: * metaobjects associated with instances of the class followed by
042: * this option. The default is <code>javassit.reflect.Metaobject</code>.
043: *
044: * <p><code>-c <i>classname</i></code> : specifies the class of the
045: * class metaobjects associated with instances of the class followed by
046: * this option. The default is <code>javassit.reflect.ClassMetaobject</code>.
047: *
048: * <p>If a class name is not followed by any options, the class indicated
049: * by that class name is not reflective.
050: *
051: * <p>For example,
052: * <ul><pre>% java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow
053: * </pre></ul>
054: *
055: * <p>modifies class files <code>Dog.class</code>, <code>Cat.class</code>,
056: * and <code>Cow.class</code>.
057: * The metaobject of a Dog object is a MetaDog object and the class
058: * metaobject is a CMetaDog object.
059: * The metaobject of a Cat object is a MetaCat object but
060: * the class metaobject is a default one.
061: * Cow objects are not reflective.
062: *
063: * <p>Note that if the super class is also made reflective, it must be done
064: * before the sub class.
065: *
066: * @see javassist.tools.reflect.Metaobject
067: * @see javassist.tools.reflect.ClassMetaobject
068: * @see javassist.tools.reflect.Reflection
069: */
070: public class Compiler {
071:
072: public static void main(String[] args) throws Exception {
073: if (args.length == 0) {
074: help(System.err);
075: return;
076: }
077:
078: CompiledClass[] entries = new CompiledClass[args.length];
079: int n = parse(args, entries);
080:
081: if (n < 1) {
082: System.err.println("bad parameter.");
083: return;
084: }
085:
086: processClasses(entries, n);
087: }
088:
089: private static void processClasses(CompiledClass[] entries, int n)
090: throws Exception {
091: Reflection implementor = new Reflection();
092: ClassPool pool = ClassPool.getDefault();
093: implementor.start(pool);
094:
095: for (int i = 0; i < n; ++i) {
096: CtClass c = pool.get(entries[i].classname);
097: if (entries[i].metaobject != null
098: || entries[i].classobject != null) {
099: String metaobj, classobj;
100:
101: if (entries[i].metaobject == null)
102: metaobj = "javassist.tools.reflect.Metaobject";
103: else
104: metaobj = entries[i].metaobject;
105:
106: if (entries[i].classobject == null)
107: classobj = "javassist.tools.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: implementor.onLoad(pool, entries[i].classname);
124: pool.get(entries[i].classname).writeFile();
125: }
126: }
127:
128: private static int parse(String[] args, CompiledClass[] result) {
129: int n = -1;
130: for (int i = 0; i < args.length; ++i) {
131: String a = args[i];
132: if (a.equals("-m"))
133: if (n < 0 || i + 1 > args.length)
134: return -1;
135: else
136: result[n].metaobject = args[++i];
137: else if (a.equals("-c"))
138: if (n < 0 || i + 1 > args.length)
139: return -1;
140: else
141: result[n].classobject = args[++i];
142: else if (a.charAt(0) == '-')
143: return -1;
144: else {
145: CompiledClass cc = new CompiledClass();
146: cc.classname = a;
147: cc.metaobject = null;
148: cc.classobject = null;
149: result[++n] = cc;
150: }
151: }
152:
153: return n + 1;
154: }
155:
156: private static void help(PrintStream out) {
157: out.println("Usage: java javassist.tools.reflect.Compiler");
158: out
159: .println(" (<class> [-m <metaobject>] [-c <class metaobject>])+");
160: }
161: }
|