org.testifyproject.tools.reflect.Compiler Maven / Gradle / Ivy
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in org.testifyproject.testifyprojectpliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package org.testifyproject.tools.reflect;
import org.testifyproject.CtClass;
import org.testifyproject.ClassPool;
import java.io.PrintStream;
class CompiledClass {
public String classname;
public String metaobject;
public String classobject;
}
/**
* A bytecode translator for reflection.
*
* This translator directly modifies class files on a local disk so that
* the classes represented by those class files are reflective.
* After the modification, the class files can be run with the standard JVM
* without org.testifyproject.tools.reflect.Loader
* or any other user-defined class loader.
*
*
The modified class files are given as the org.testifyproject.testifyprojectmand-line parameters,
* which are a sequence of fully-qualified class names followed by options:
*
*
-m classname
: specifies the class of the
* metaobjects associated with instances of the class followed by
* this option. The default is javassit.reflect.Metaobject
.
*
*
-c classname
: specifies the class of the
* class metaobjects associated with instances of the class followed by
* this option. The default is javassit.reflect.ClassMetaobject
.
*
*
If a class name is not followed by any options, the class indicated
* by that class name is not reflective.
*
*
For example,
*
% java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow
*
*
* modifies class files Dog.class
, Cat.class
,
* and Cow.class
.
* The metaobject of a Dog object is a MetaDog object and the class
* metaobject is a CMetaDog object.
* The metaobject of a Cat object is a MetaCat object but
* the class metaobject is a default one.
* Cow objects are not reflective.
*
*
Note that if the super class is also made reflective, it must be done
* before the sub class.
*
* @see org.testifyproject.tools.reflect.Metaobject
* @see org.testifyproject.tools.reflect.ClassMetaobject
* @see org.testifyproject.tools.reflect.Reflection
*/
public class Compiler {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
help(System.err);
return;
}
CompiledClass[] entries = new CompiledClass[args.length];
int n = parse(args, entries);
if (n < 1) {
System.err.println("bad parameter.");
return;
}
processClasses(entries, n);
}
private static void processClasses(CompiledClass[] entries, int n)
throws Exception
{
Reflection implementor = new Reflection();
ClassPool pool = ClassPool.getDefault();
implementor.start(pool);
for (int i = 0; i < n; ++i) {
CtClass c = pool.get(entries[i].classname);
if (entries[i].metaobject != null
|| entries[i].classobject != null) {
String metaobj, classobj;
if (entries[i].metaobject == null)
metaobj = "org.testifyproject.tools.reflect.Metaobject";
else
metaobj = entries[i].metaobject;
if (entries[i].classobject == null)
classobj = "org.testifyproject.tools.reflect.ClassMetaobject";
else
classobj = entries[i].classobject;
if (!implementor.makeReflective(c, pool.get(metaobj),
pool.get(classobj)))
System.err.println("Warning: " + c.getName()
+ " is reflective. It was not changed.");
System.err.println(c.getName() + ": " + metaobj + ", "
+ classobj);
}
else
System.err.println(c.getName() + ": not reflective");
}
for (int i = 0; i < n; ++i) {
implementor.onLoad(pool, entries[i].classname);
pool.get(entries[i].classname).writeFile();
}
}
private static int parse(String[] args, CompiledClass[] result) {
int n = -1;
for (int i = 0; i < args.length; ++i) {
String a = args[i];
if (a.equals("-m"))
if (n < 0 || i + 1 > args.length)
return -1;
else
result[n].metaobject = args[++i];
else if (a.equals("-c"))
if (n < 0 || i + 1 > args.length)
return -1;
else
result[n].classobject = args[++i];
else if (a.charAt(0) == '-')
return -1;
else {
CompiledClass cc = new CompiledClass();
cc.classname = a;
cc.metaobject = null;
cc.classobject = null;
result[++n] = cc;
}
}
return n + 1;
}
private static void help(PrintStream out) {
out.println("Usage: java org.testifyproject.tools.reflect.Compiler");
out.println(" ( [-m ] [-c ])+");
}
}