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