Home | History | Annotate | Download | only in vector
      1 package sample.vector;
      2 
      3 import java.io.IOException;
      4 import javassist.*;
      5 import sample.preproc.Assistant;
      6 
      7 /**
      8  * This is a Javassist program which produce a new class representing
      9  * vectors of a given type.  For example,
     10  *
     11  * <ul>import java.util.Vector by sample.vector.VectorAssistant(int)</ul>
     12  *
     13  * <p>requests the Javassist preprocessor to substitute the following
     14  * lines for the original import declaration:
     15  *
     16  * <ul><pre>
     17  * import java.util.Vector;
     18  * import sample.vector.intVector;
     19  * </pre></ul>
     20  *
     21  * <p>The Javassist preprocessor calls <code>VectorAssistant.assist()</code>
     22  * and produces class <code>intVector</code> equivalent to:
     23  *
     24  * <ul><pre>
     25  * package sample.vector;
     26  *
     27  * public class intVector extends Vector {
     28  *   pubilc void add(int value) {
     29  *     addElement(new Integer(value));
     30  *   }
     31  *
     32  *   public int at(int index) {
     33  *     return elementAt(index).intValue();
     34  *   }
     35  * }
     36  * </pre></ul>
     37  *
     38  * <p><code>VectorAssistant.assist()</code> uses
     39  * <code>sample.vector.Sample</code> and <code>sample.vector.Sample2</code>
     40  * as a template to produce the methods <code>add()</code> and
     41  * <code>at()</code>.
     42  */
     43 public class VectorAssistant implements Assistant {
     44     public final String packageName = "sample.vector.";
     45 
     46     /**
     47      * Calls <code>makeSubclass()</code> and produces a new vector class.
     48      * This method is called by a <code>sample.preproc.Compiler</code>.
     49      *
     50      * @see sample.preproc.Compiler
     51      */
     52     public CtClass[] assist(ClassPool pool, String vec, String[] args)
     53 	throws CannotCompileException
     54     {
     55 	if (args.length != 1)
     56 	    throw new CannotCompileException(
     57 			"VectorAssistant receives a single argument.");
     58 
     59 	try {
     60 	    CtClass subclass;
     61 	    CtClass elementType = pool.get(args[0]);
     62 	    if (elementType.isPrimitive())
     63 		subclass = makeSubclass2(pool, elementType);
     64 	    else
     65 		subclass = makeSubclass(pool, elementType);
     66 
     67 	    CtClass[] results = { subclass, pool.get(vec) };
     68 	    return results;
     69 	}
     70 	catch (NotFoundException e) {
     71 	    throw new CannotCompileException(e);
     72 	}
     73 	catch (IOException e) {
     74 	    throw new CannotCompileException(e);
     75 	}
     76     }
     77 
     78     /**
     79      * Produces a new vector class.  This method does not work if
     80      * the element type is a primitive type.
     81      *
     82      * @param type	the type of elements
     83      */
     84     public CtClass makeSubclass(ClassPool pool, CtClass type)
     85 	throws CannotCompileException, NotFoundException, IOException
     86     {
     87 	CtClass vec = pool.makeClass(makeClassName(type));
     88 	vec.setSuperclass(pool.get("java.util.Vector"));
     89 
     90 	CtClass c = pool.get("sample.vector.Sample");
     91 	CtMethod addmethod = c.getDeclaredMethod("add");
     92 	CtMethod atmethod = c.getDeclaredMethod("at");
     93 
     94 	ClassMap map = new ClassMap();
     95 	map.put("sample.vector.X", type.getName());
     96 
     97 	vec.addMethod(CtNewMethod.copy(addmethod, "add", vec, map));
     98 	vec.addMethod(CtNewMethod.copy(atmethod, "at", vec, map));
     99 	vec.writeFile();
    100 	return vec;
    101     }
    102 
    103     /**
    104      * Produces a new vector class.  This uses wrapped methods so that
    105      * the element type can be a primitive type.
    106      *
    107      * @param type	the type of elements
    108      */
    109     public CtClass makeSubclass2(ClassPool pool, CtClass type)
    110 	throws CannotCompileException, NotFoundException, IOException
    111     {
    112 	CtClass vec = pool.makeClass(makeClassName(type));
    113 	vec.setSuperclass(pool.get("java.util.Vector"));
    114 
    115 	CtClass c = pool.get("sample.vector.Sample2");
    116 	CtMethod addmethod = c.getDeclaredMethod("add");
    117 	CtMethod atmethod = c.getDeclaredMethod("at");
    118 
    119 	CtClass[] args1 = { type };
    120 	CtClass[] args2 = { CtClass.intType };
    121 	CtMethod m
    122 	    = CtNewMethod.wrapped(CtClass.voidType, "add", args1,
    123 				  null, addmethod, null, vec);
    124 	vec.addMethod(m);
    125 	m = CtNewMethod.wrapped(type, "at", args2,
    126 				null, atmethod, null, vec);
    127 	vec.addMethod(m);
    128 	vec.writeFile();
    129 	return vec;
    130     }
    131 
    132     private String makeClassName(CtClass type) {
    133 	return packageName + type.getSimpleName() + "Vector";
    134     }
    135 }
    136