123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package sample.vector;
-
- import java.io.IOException;
- import javassist.*;
- import sample.preproc.Assistant;
-
- /**
- * This is a Javassist program which produce a new class representing
- * vectors of a given type. For example,
- *
- * <ul>import java.util.Vector by sample.vector.VectorAssistant(int)</ul>
- *
- * <p>requests the Javassist preprocessor to substitute the following
- * lines for the original import declaration:
- *
- * <ul><pre>
- * import java.util.Vector;
- * import sample.vector.intVector;
- * </pre></ul>
- *
- * <p>The Javassist preprocessor calls <code>VectorAssistant.assist()</code>
- * and produces class <code>intVector</code> equivalent to:
- *
- * <ul><pre>
- * package sample.vector;
- *
- * public class intVector extends Vector {
- * pubilc void add(int value) {
- * addElement(new Integer(value));
- * }
- *
- * public int at(int index) {
- * return elementAt(index).intValue();
- * }
- * }
- * </pre></ul>
- *
- * <p><code>VectorAssistant.assist()</code> uses
- * <code>sample.vector.Sample</code> and <code>sample.vector.Sample2</code>
- * as a template to produce the methods <code>add()</code> and
- * <code>at()</code>.
- */
- public class VectorAssistant implements Assistant {
- public final String packageName = "sample.vector.";
-
- /**
- * Calls <code>makeSubclass()</code> and produces a new vector class.
- * This method is called by a <code>sample.preproc.Compiler</code>.
- *
- * @see sample.preproc.Compiler
- */
- public CtClass[] assist(ClassPool pool, String vec, String[] args)
- throws CannotCompileException
- {
- if (args.length != 1)
- throw new CannotCompileException(
- "VectorAssistant receives a single argument.");
-
- try {
- CtClass subclass;
- CtClass elementType = pool.get(args[0]);
- if (elementType.isPrimitive())
- subclass = makeSubclass2(pool, elementType);
- else
- subclass = makeSubclass(pool, elementType);
-
- CtClass[] results = { subclass, pool.get(vec) };
- return results;
- }
- catch (NotFoundException e) {
- throw new CannotCompileException(e);
- }
- catch (IOException e) {
- throw new CannotCompileException(e);
- }
- }
-
- /**
- * Produces a new vector class. This method does not work if
- * the element type is a primitive type.
- *
- * @param type the type of elements
- */
- public CtClass makeSubclass(ClassPool pool, CtClass type)
- throws CannotCompileException, NotFoundException, IOException
- {
- CtClass vec = pool.makeClass(makeClassName(type));
- vec.setSuperclass(pool.get("java.util.Vector"));
-
- CtClass c = pool.get("sample.vector.Sample");
- CtMethod addmethod = c.getDeclaredMethod("add");
- CtMethod atmethod = c.getDeclaredMethod("at");
-
- ClassMap map = new ClassMap();
- map.put("sample.vector.X", type.getName());
-
- vec.addMethod(CtNewMethod.copy(addmethod, "add", vec, map));
- vec.addMethod(CtNewMethod.copy(atmethod, "at", vec, map));
- vec.writeFile();
- return vec;
- }
-
- /**
- * Produces a new vector class. This uses wrapped methods so that
- * the element type can be a primitive type.
- *
- * @param type the type of elements
- */
- public CtClass makeSubclass2(ClassPool pool, CtClass type)
- throws CannotCompileException, NotFoundException, IOException
- {
- CtClass vec = pool.makeClass(makeClassName(type));
- vec.setSuperclass(pool.get("java.util.Vector"));
-
- CtClass c = pool.get("sample.vector.Sample2");
- CtMethod addmethod = c.getDeclaredMethod("add");
- CtMethod atmethod = c.getDeclaredMethod("at");
-
- CtClass[] args1 = { type };
- CtClass[] args2 = { CtClass.intType };
- CtMethod m
- = CtNewMethod.wrapped(CtClass.voidType, "add", args1,
- null, addmethod, null, vec);
- vec.addMethod(m);
- m = CtNewMethod.wrapped(type, "at", args2,
- null, atmethod, null, vec);
- vec.addMethod(m);
- vec.writeFile();
- return vec;
- }
-
- private String makeClassName(CtClass type) {
- return packageName + type.getSimpleName() + "Vector";
- }
- }
|