KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > xml > ASMContentHandler


1 /***
2  * ASM XML Adapter
3  * Copyright (c) 2004, Eugene Kuleshov
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.tc.asm.xml;
31
32 import java.io.IOException JavaDoc;
33 import java.io.OutputStream JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Map JavaDoc;
39
40 import com.tc.asm.AnnotationVisitor;
41 import com.tc.asm.ClassVisitor;
42 import com.tc.asm.ClassWriter;
43 import com.tc.asm.FieldVisitor;
44 import com.tc.asm.MethodVisitor;
45 import com.tc.asm.Opcodes;
46 import com.tc.asm.Label;
47 import com.tc.asm.Type;
48
49 import org.xml.sax.Attributes JavaDoc;
50 import org.xml.sax.SAXException JavaDoc;
51 import org.xml.sax.helpers.DefaultHandler JavaDoc;
52
53 /**
54  * A {@link org.xml.sax.ContentHandler ContentHandler} that transforms XML
55  * document into Java class file. This class can be feeded by any kind of SAX
56  * 2.0 event producers, e.g. XML parser, XSLT or XPath engines, or custom code.
57  *
58  * @see org.objectweb.asm.xml.SAXClassAdapter
59  * @see org.objectweb.asm.xml.Processor
60  *
61  * @author Eugene Kuleshov
62  */

63 public class ASMContentHandler extends DefaultHandler JavaDoc implements Opcodes {
64     /**
65      * Stack of the intermediate processing contexts.
66      */

67     private List JavaDoc stack = new ArrayList JavaDoc();
68
69     /**
70      * Complete name of the current element.
71      */

72     private String JavaDoc match = "";
73
74     /**
75      * <tt>true</tt> if the maximum stack size and number of local variables
76      * must be automatically computed.
77      */

78     protected boolean computeMax;
79
80     /**
81      * Output stream to write result bytecode.
82      */

83     protected OutputStream JavaDoc os;
84
85     /**
86      * Current instance of the {@link ClassWriter ClassWriter} used to write
87      * class bytecode.
88      */

89     protected ClassWriter cw;
90
91     /**
92      * Map of the active {@link Label Label} instances for current method.
93      */

94     protected Map JavaDoc labels;
95
96     private static final String JavaDoc BASE = "class";
97
98     private final RuleSet RULES = new RuleSet();
99     {
100         RULES.add(BASE, new ClassRule());
101         RULES.add(BASE + "/interfaces/interface", new InterfaceRule());
102         RULES.add(BASE + "/interfaces", new InterfacesRule());
103         RULES.add(BASE + "/outerclass", new OuterClassRule());
104         RULES.add(BASE + "/innerclass", new InnerClassRule());
105         RULES.add(BASE + "/source", new SourceRule());
106         RULES.add(BASE + "/field", new FieldRule());
107
108         RULES.add(BASE + "/method", new MethodRule());
109         RULES.add(BASE + "/method/exceptions/exception", new ExceptionRule());
110         RULES.add(BASE + "/method/exceptions", new ExceptionsRule());
111
112         RULES.add(BASE + "/method/annotationDefault",
113                 new AnnotationDefaultRule());
114
115         RULES.add(BASE + "/method/code/*", new OpcodesRule()); // opcodes
116

117         RULES.add(BASE + "/method/code/TABLESWITCH", new TableSwitchRule());
118         RULES.add(BASE + "/method/code/TABLESWITCH/label",
119                 new TableSwitchLabelRule());
120         RULES.add(BASE + "/method/code/LOOKUPSWITCH", new LookupSwitchRule());
121         RULES.add(BASE + "/method/code/LOOKUPSWITCH/label",
122                 new LookupSwitchLabelRule());
123
124         RULES.add(BASE + "/method/code/Label", new LabelRule());
125         RULES.add(BASE + "/method/code/TryCatch", new TryCatchRule());
126         RULES.add(BASE + "/method/code/LineNumber", new LineNumberRule());
127         RULES.add(BASE + "/method/code/LocalVar", new LocalVarRule());
128         RULES.add(BASE + "/method/code/Max", new MaxRule());
129
130         RULES.add("*/annotation", new AnnotationRule());
131         RULES.add("*/parameterAnnotation", new AnnotationParameterRule());
132         RULES.add("*/annotationValue", new AnnotationValueRule());
133         RULES.add("*/annotationValueAnnotation",
134                 new AnnotationValueAnnotationRule());
135         RULES.add("*/annotationValueEnum", new AnnotationValueEnumRule());
136         RULES.add("*/annotationValueArray", new AnnotationValueArrayRule());
137     };
138
139     private static interface OpcodeGroup {
140         public static final int INSN = 0;
141         public static final int INSN_INT = 1;
142         public static final int INSN_VAR = 2;
143         public static final int INSN_TYPE = 3;
144         public static final int INSN_FIELD = 4;
145         public static final int INSN_METHOD = 5;
146         public static final int INSN_JUMP = 6;
147         public static final int INSN_LDC = 7;
148         public static final int INSN_IINC = 8;
149         public static final int INSN_MULTIANEWARRAY = 9;
150     }
151
152     /**
153      * Map of the opcode names to opcode and opcode group
154      */

155     static final Map JavaDoc OPCODES = new HashMap JavaDoc();
156     static {
157         OPCODES.put("NOP", new Opcode(NOP, OpcodeGroup.INSN));
158         OPCODES.put("ACONST_NULL", new Opcode(ACONST_NULL, OpcodeGroup.INSN));
159         OPCODES.put("ICONST_M1", new Opcode(ICONST_M1, OpcodeGroup.INSN));
160         OPCODES.put("ICONST_0", new Opcode(ICONST_0, OpcodeGroup.INSN));
161         OPCODES.put("ICONST_1", new Opcode(ICONST_1, OpcodeGroup.INSN));
162         OPCODES.put("ICONST_2", new Opcode(ICONST_2, OpcodeGroup.INSN));
163         OPCODES.put("ICONST_3", new Opcode(ICONST_3, OpcodeGroup.INSN));
164         OPCODES.put("ICONST_4", new Opcode(ICONST_4, OpcodeGroup.INSN));
165         OPCODES.put("ICONST_5", new Opcode(ICONST_5, OpcodeGroup.INSN));
166         OPCODES.put("LCONST_0", new Opcode(LCONST_0, OpcodeGroup.INSN));
167         OPCODES.put("LCONST_1", new Opcode(LCONST_1, OpcodeGroup.INSN));
168         OPCODES.put("FCONST_0", new Opcode(FCONST_0, OpcodeGroup.INSN));
169         OPCODES.put("FCONST_1", new Opcode(FCONST_1, OpcodeGroup.INSN));
170         OPCODES.put("FCONST_2", new Opcode(FCONST_2, OpcodeGroup.INSN));
171         OPCODES.put("DCONST_0", new Opcode(DCONST_0, OpcodeGroup.INSN));
172         OPCODES.put("DCONST_1", new Opcode(DCONST_1, OpcodeGroup.INSN));
173         OPCODES.put("BIPUSH", new Opcode(BIPUSH, OpcodeGroup.INSN_INT));
174         OPCODES.put("SIPUSH", new Opcode(SIPUSH, OpcodeGroup.INSN_INT));
175         OPCODES.put("LDC", new Opcode(LDC, OpcodeGroup.INSN_LDC));
176         OPCODES.put("ILOAD", new Opcode(ILOAD, OpcodeGroup.INSN_VAR));
177         OPCODES.put("LLOAD", new Opcode(LLOAD, OpcodeGroup.INSN_VAR));
178         OPCODES.put("FLOAD", new Opcode(FLOAD, OpcodeGroup.INSN_VAR));
179         OPCODES.put("DLOAD", new Opcode(DLOAD, OpcodeGroup.INSN_VAR));
180         OPCODES.put("ALOAD", new Opcode(ALOAD, OpcodeGroup.INSN_VAR));
181         OPCODES.put("IALOAD", new Opcode(IALOAD, OpcodeGroup.INSN));
182         OPCODES.put("LALOAD", new Opcode(LALOAD, OpcodeGroup.INSN));
183         OPCODES.put("FALOAD", new Opcode(FALOAD, OpcodeGroup.INSN));
184         OPCODES.put("DALOAD", new Opcode(DALOAD, OpcodeGroup.INSN));
185         OPCODES.put("AALOAD", new Opcode(AALOAD, OpcodeGroup.INSN));
186         OPCODES.put("BALOAD", new Opcode(BALOAD, OpcodeGroup.INSN));
187         OPCODES.put("CALOAD", new Opcode(CALOAD, OpcodeGroup.INSN));
188         OPCODES.put("SALOAD", new Opcode(SALOAD, OpcodeGroup.INSN));
189         OPCODES.put("ISTORE", new Opcode(ISTORE, OpcodeGroup.INSN_VAR));
190         OPCODES.put("LSTORE", new Opcode(LSTORE, OpcodeGroup.INSN_VAR));
191         OPCODES.put("FSTORE", new Opcode(FSTORE, OpcodeGroup.INSN_VAR));
192         OPCODES.put("DSTORE", new Opcode(DSTORE, OpcodeGroup.INSN_VAR));
193         OPCODES.put("ASTORE", new Opcode(ASTORE, OpcodeGroup.INSN_VAR));
194         OPCODES.put("IASTORE", new Opcode(IASTORE, OpcodeGroup.INSN));
195         OPCODES.put("LASTORE", new Opcode(LASTORE, OpcodeGroup.INSN));
196         OPCODES.put("FASTORE", new Opcode(FASTORE, OpcodeGroup.INSN));
197         OPCODES.put("DASTORE", new Opcode(DASTORE, OpcodeGroup.INSN));
198         OPCODES.put("AASTORE", new Opcode(AASTORE, OpcodeGroup.INSN));
199         OPCODES.put("BASTORE", new Opcode(BASTORE, OpcodeGroup.INSN));
200         OPCODES.put("CASTORE", new Opcode(CASTORE, OpcodeGroup.INSN));
201         OPCODES.put("SASTORE", new Opcode(SASTORE, OpcodeGroup.INSN));
202         OPCODES.put("POP", new Opcode(POP, OpcodeGroup.INSN));
203         OPCODES.put("POP2", new Opcode(POP2, OpcodeGroup.INSN));
204         OPCODES.put("DUP", new Opcode(DUP, OpcodeGroup.INSN));
205         OPCODES.put("DUP_X1", new Opcode(DUP_X1, OpcodeGroup.INSN));
206         OPCODES.put("DUP_X2", new Opcode(DUP_X2, OpcodeGroup.INSN));
207         OPCODES.put("DUP2", new Opcode(DUP2, OpcodeGroup.INSN));
208         OPCODES.put("DUP2_X1", new Opcode(DUP2_X1, OpcodeGroup.INSN));
209         OPCODES.put("DUP2_X2", new Opcode(DUP2_X2, OpcodeGroup.INSN));
210         OPCODES.put("SWAP", new Opcode(SWAP, OpcodeGroup.INSN));
211         OPCODES.put("IADD", new Opcode(IADD, OpcodeGroup.INSN));
212         OPCODES.put("LADD", new Opcode(LADD, OpcodeGroup.INSN));
213         OPCODES.put("FADD", new Opcode(FADD, OpcodeGroup.INSN));
214         OPCODES.put("DADD", new Opcode(DADD, OpcodeGroup.INSN));
215         OPCODES.put("ISUB", new Opcode(ISUB, OpcodeGroup.INSN));
216         OPCODES.put("LSUB", new Opcode(LSUB, OpcodeGroup.INSN));
217         OPCODES.put("FSUB", new Opcode(FSUB, OpcodeGroup.INSN));
218         OPCODES.put("DSUB", new Opcode(DSUB, OpcodeGroup.INSN));
219         OPCODES.put("IMUL", new Opcode(IMUL, OpcodeGroup.INSN));
220         OPCODES.put("LMUL", new Opcode(LMUL, OpcodeGroup.INSN));
221         OPCODES.put("FMUL", new Opcode(FMUL, OpcodeGroup.INSN));
222         OPCODES.put("DMUL", new Opcode(DMUL, OpcodeGroup.INSN));
223         OPCODES.put("IDIV", new Opcode(IDIV, OpcodeGroup.INSN));
224         OPCODES.put("LDIV", new Opcode(LDIV, OpcodeGroup.INSN));
225         OPCODES.put("FDIV", new Opcode(FDIV, OpcodeGroup.INSN));
226         OPCODES.put("DDIV", new Opcode(DDIV, OpcodeGroup.INSN));
227         OPCODES.put("IREM", new Opcode(IREM, OpcodeGroup.INSN));
228         OPCODES.put("LREM", new Opcode(LREM, OpcodeGroup.INSN));
229         OPCODES.put("FREM", new Opcode(FREM, OpcodeGroup.INSN));
230         OPCODES.put("DREM", new Opcode(DREM, OpcodeGroup.INSN));
231         OPCODES.put("INEG", new Opcode(INEG, OpcodeGroup.INSN));
232         OPCODES.put("LNEG", new Opcode(LNEG, OpcodeGroup.INSN));
233         OPCODES.put("FNEG", new Opcode(FNEG, OpcodeGroup.INSN));
234         OPCODES.put("DNEG", new Opcode(DNEG, OpcodeGroup.INSN));
235         OPCODES.put("ISHL", new Opcode(ISHL, OpcodeGroup.INSN));
236         OPCODES.put("LSHL", new Opcode(LSHL, OpcodeGroup.INSN));
237         OPCODES.put("ISHR", new Opcode(ISHR, OpcodeGroup.INSN));
238         OPCODES.put("LSHR", new Opcode(LSHR, OpcodeGroup.INSN));
239         OPCODES.put("IUSHR", new Opcode(IUSHR, OpcodeGroup.INSN));
240         OPCODES.put("LUSHR", new Opcode(LUSHR, OpcodeGroup.INSN));
241         OPCODES.put("IAND", new Opcode(IAND, OpcodeGroup.INSN));
242         OPCODES.put("LAND", new Opcode(LAND, OpcodeGroup.INSN));
243         OPCODES.put("IOR", new Opcode(IOR, OpcodeGroup.INSN));
244         OPCODES.put("LOR", new Opcode(LOR, OpcodeGroup.INSN));
245         OPCODES.put("IXOR", new Opcode(IXOR, OpcodeGroup.INSN));
246         OPCODES.put("LXOR", new Opcode(LXOR, OpcodeGroup.INSN));
247         OPCODES.put("IINC", new Opcode(IINC, OpcodeGroup.INSN_IINC));
248         OPCODES.put("I2L", new Opcode(I2L, OpcodeGroup.INSN));
249         OPCODES.put("I2F", new Opcode(I2F, OpcodeGroup.INSN));
250         OPCODES.put("I2D", new Opcode(I2D, OpcodeGroup.INSN));
251         OPCODES.put("L2I", new Opcode(L2I, OpcodeGroup.INSN));
252         OPCODES.put("L2F", new Opcode(L2F, OpcodeGroup.INSN));
253         OPCODES.put("L2D", new Opcode(L2D, OpcodeGroup.INSN));
254         OPCODES.put("F2I", new Opcode(F2I, OpcodeGroup.INSN));
255         OPCODES.put("F2L", new Opcode(F2L, OpcodeGroup.INSN));
256         OPCODES.put("F2D", new Opcode(F2D, OpcodeGroup.INSN));
257         OPCODES.put("D2I", new Opcode(D2I, OpcodeGroup.INSN));
258         OPCODES.put("D2L", new Opcode(D2L, OpcodeGroup.INSN));
259         OPCODES.put("D2F", new Opcode(D2F, OpcodeGroup.INSN));
260         OPCODES.put("I2B", new Opcode(I2B, OpcodeGroup.INSN));
261         OPCODES.put("I2C", new Opcode(I2C, OpcodeGroup.INSN));
262         OPCODES.put("I2S", new Opcode(I2S, OpcodeGroup.INSN));
263         OPCODES.put("LCMP", new Opcode(LCMP, OpcodeGroup.INSN));
264         OPCODES.put("FCMPL", new Opcode(FCMPL, OpcodeGroup.INSN));
265         OPCODES.put("FCMPG", new Opcode(FCMPG, OpcodeGroup.INSN));
266         OPCODES.put("DCMPL", new Opcode(DCMPL, OpcodeGroup.INSN));
267         OPCODES.put("DCMPG", new Opcode(DCMPG, OpcodeGroup.INSN));
268         OPCODES.put("IFEQ", new Opcode(IFEQ, OpcodeGroup.INSN_JUMP));
269         OPCODES.put("IFNE", new Opcode(IFNE, OpcodeGroup.INSN_JUMP));
270         OPCODES.put("IFLT", new Opcode(IFLT, OpcodeGroup.INSN_JUMP));
271         OPCODES.put("IFGE", new Opcode(IFGE, OpcodeGroup.INSN_JUMP));
272         OPCODES.put("IFGT", new Opcode(IFGT, OpcodeGroup.INSN_JUMP));
273         OPCODES.put("IFLE", new Opcode(IFLE, OpcodeGroup.INSN_JUMP));
274         OPCODES.put("IF_ICMPEQ", new Opcode(IF_ICMPEQ, OpcodeGroup.INSN_JUMP));
275         OPCODES.put("IF_ICMPNE", new Opcode(IF_ICMPNE, OpcodeGroup.INSN_JUMP));
276         OPCODES.put("IF_ICMPLT", new Opcode(IF_ICMPLT, OpcodeGroup.INSN_JUMP));
277         OPCODES.put("IF_ICMPGE", new Opcode(IF_ICMPGE, OpcodeGroup.INSN_JUMP));
278         OPCODES.put("IF_ICMPGT", new Opcode(IF_ICMPGT, OpcodeGroup.INSN_JUMP));
279         OPCODES.put("IF_ICMPLE", new Opcode(IF_ICMPLE, OpcodeGroup.INSN_JUMP));
280         OPCODES.put("IF_ACMPEQ", new Opcode(IF_ACMPEQ, OpcodeGroup.INSN_JUMP));
281         OPCODES.put("IF_ACMPNE", new Opcode(IF_ACMPNE, OpcodeGroup.INSN_JUMP));
282         OPCODES.put("GOTO", new Opcode(GOTO, OpcodeGroup.INSN_JUMP));
283         OPCODES.put("JSR", new Opcode(JSR, OpcodeGroup.INSN_JUMP));
284         OPCODES.put("RET", new Opcode(RET, OpcodeGroup.INSN_VAR));
285         // OPCODES.put( "TABLESWITCH", new Opcode( TABLESWITCH,
286
// "visiTableSwitchInsn"));
287
// OPCODES.put( "LOOKUPSWITCH", new Opcode( LOOKUPSWITCH,
288
// "visitLookupSwitch"));
289
OPCODES.put("IRETURN", new Opcode(IRETURN, OpcodeGroup.INSN));
290         OPCODES.put("LRETURN", new Opcode(LRETURN, OpcodeGroup.INSN));
291         OPCODES.put("FRETURN", new Opcode(FRETURN, OpcodeGroup.INSN));
292         OPCODES.put("DRETURN", new Opcode(DRETURN, OpcodeGroup.INSN));
293         OPCODES.put("ARETURN", new Opcode(ARETURN, OpcodeGroup.INSN));
294         OPCODES.put("RETURN", new Opcode(RETURN, OpcodeGroup.INSN));
295         OPCODES.put("GETSTATIC", new Opcode(GETSTATIC, OpcodeGroup.INSN_FIELD));
296         OPCODES.put("PUTSTATIC", new Opcode(PUTSTATIC, OpcodeGroup.INSN_FIELD));
297         OPCODES.put("GETFIELD", new Opcode(GETFIELD, OpcodeGroup.INSN_FIELD));
298         OPCODES.put("PUTFIELD", new Opcode(PUTFIELD, OpcodeGroup.INSN_FIELD));
299         OPCODES.put("INVOKEVIRTUAL", new Opcode(INVOKEVIRTUAL,
300                 OpcodeGroup.INSN_METHOD));
301         OPCODES.put("INVOKESPECIAL", new Opcode(INVOKESPECIAL,
302                 OpcodeGroup.INSN_METHOD));
303         OPCODES.put("INVOKESTATIC", new Opcode(INVOKESTATIC,
304                 OpcodeGroup.INSN_METHOD));
305         OPCODES.put("INVOKEINTERFACE", new Opcode(INVOKEINTERFACE,
306                 OpcodeGroup.INSN_METHOD));
307         OPCODES.put("NEW", new Opcode(NEW, OpcodeGroup.INSN_TYPE));
308         OPCODES.put("NEWARRAY", new Opcode(NEWARRAY, OpcodeGroup.INSN_INT));
309         OPCODES.put("ANEWARRAY", new Opcode(ANEWARRAY, OpcodeGroup.INSN_TYPE));
310         OPCODES.put("ARRAYLENGTH", new Opcode(ARRAYLENGTH, OpcodeGroup.INSN));
311         OPCODES.put("ATHROW", new Opcode(ATHROW, OpcodeGroup.INSN));
312         OPCODES.put("CHECKCAST", new Opcode(CHECKCAST, OpcodeGroup.INSN_TYPE));
313         OPCODES.put("INSTANCEOF", new Opcode(INSTANCEOF, OpcodeGroup.INSN_TYPE));
314         OPCODES.put("MONITORENTER", new Opcode(MONITORENTER, OpcodeGroup.INSN));
315         OPCODES.put("MONITOREXIT", new Opcode(MONITOREXIT, OpcodeGroup.INSN));
316         OPCODES.put("MULTIANEWARRAY", new Opcode(MULTIANEWARRAY,
317                 OpcodeGroup.INSN_MULTIANEWARRAY));
318         OPCODES.put("IFNULL", new Opcode(IFNULL, OpcodeGroup.INSN_JUMP));
319         OPCODES.put("IFNONNULL", new Opcode(IFNONNULL, OpcodeGroup.INSN_JUMP));
320     }
321
322     /**
323      * Constructs a new {@link ASMContentHandler ASMContentHandler} object.
324      *
325      * @param os output stream to write generated class.
326      * @param computeMax <tt>true</tt> if the maximum stack size and the
327      * maximum number of local variables must be automatically computed.
328      * This value is passed to {@link ClassWriter ClassWriter} instance.
329      */

330     public ASMContentHandler(OutputStream JavaDoc os, boolean computeMax) {
331         this.os = os;
332         this.computeMax = computeMax;
333     }
334
335     /**
336      * Returns the bytecode of the class that was build with underneath class
337      * writer.
338      *
339      * @return the bytecode of the class that was build with underneath class
340      * writer or null if there are no classwriter created.
341      */

342     public byte[] toByteArray() {
343         return cw == null ? null : cw.toByteArray();
344     }
345
346     /**
347      * Process notification of the start of an XML element being reached.
348      *
349      * @param ns - The Namespace URI, or the empty string if the element has no
350      * Namespace URI or if Namespace processing is not being performed.
351      * @param localName - The local name (without prefix), or the empty string
352      * if Namespace processing is not being performed.
353      * @param qName - The qualified name (with prefix), or the empty string if
354      * qualified names are not available.
355      * @param list - The attributes attached to the element. If there are no
356      * attributes, it shall be an empty Attributes object.
357      * @exception SAXException if a parsing error is to be reported
358      */

359     public final void startElement(
360         String JavaDoc ns,
361         String JavaDoc localName,
362         String JavaDoc qName,
363         Attributes JavaDoc list) throws SAXException JavaDoc
364     {
365         // the actual element name is either in localName or qName, depending
366
// on whether the parser is namespace aware
367
String JavaDoc name = localName;
368         if (name == null || name.length() < 1) {
369             name = qName;
370         }
371
372         // Compute the current matching rule
373
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(match);
374         if (match.length() > 0) {
375             sb.append('/');
376         }
377         sb.append(name);
378         match = sb.toString();
379
380         // Fire "begin" events for all relevant rules
381
Rule r = (Rule) RULES.match(match);
382         if (r != null)
383             r.begin(name, list);
384     }
385
386     /**
387      * Process notification of the end of an XML element being reached.
388      *
389      * @param ns - The Namespace URI, or the empty string if the element has no
390      * Namespace URI or if Namespace processing is not being performed.
391      * @param localName - The local name (without prefix), or the empty string
392      * if Namespace processing is not being performed.
393      * @param qName - The qualified XML 1.0 name (with prefix), or the empty
394      * string if qualified names are not available.
395      *
396      * @exception SAXException if a parsing error is to be reported
397      */

398     public final void endElement(String JavaDoc ns, String JavaDoc localName, String JavaDoc qName)
399             throws SAXException JavaDoc
400     {
401         // the actual element name is either in localName or qName, depending
402
// on whether the parser is namespace aware
403
String JavaDoc name = localName;
404         if (name == null || name.length() < 1) {
405             name = qName;
406         }
407
408         // Fire "end" events for all relevant rules in reverse order
409
Rule r = (Rule) RULES.match(match);
410         if (r != null)
411             r.end(name);
412
413         // Recover the previous match expression
414
int slash = match.lastIndexOf('/');
415         if (slash >= 0) {
416             match = match.substring(0, slash);
417         } else {
418             match = "";
419         }
420     }
421
422     /**
423      * Process notification of the end of a document and write generated
424      * bytecode into output stream.
425      *
426      * @exception SAXException if parsing or writing error is to be reported.
427      */

428     public final void endDocument() throws SAXException JavaDoc {
429         try {
430             os.write(cw.toByteArray());
431         } catch (IOException JavaDoc ex) {
432             throw new SAXException JavaDoc(ex.toString(), ex);
433         }
434     }
435
436     /**
437      * Return the top object on the stack without removing it. If there are no
438      * objects on the stack, return <code>null</code>.
439      *
440      * @return the top object on the stack without removing it.
441      */

442     final Object JavaDoc peek() {
443         return stack.size() == 0 ? null : stack.get(stack.size() - 1);
444     }
445
446     /**
447      * Return the n'th object down the stack, where 0 is the top element and
448      * [getCount()-1] is the bottom element. If the specified index is out of
449      * range, return <code>null</code>.
450      *
451      * @param n Index of the desired element, where 0 is the top of the stack, 1
452      * is the next element down, and so on.
453      * @return the n'th object down the stack.
454      */

455     final Object JavaDoc peek(int n) {
456         return stack.size() < (n + 1) ? null : stack.get(n);
457     }
458
459     /**
460      * Pop the top object off of the stack, and return it. If there are no
461      * objects on the stack, return <code>null</code>.
462      *
463      * @return the top object off of the stack.
464      */

465     final Object JavaDoc pop() {
466         return stack.size() == 0 ? null : stack.remove(stack.size() - 1);
467     }
468
469     /**
470      * Push a new object onto the top of the object stack.
471      *
472      * @param object The new object
473      */

474     final void push(Object JavaDoc object) {
475         stack.add(object);
476     }
477
478     private static final class RuleSet {
479         private Map JavaDoc rules = new HashMap JavaDoc();
480
481         private List JavaDoc lpatterns = new ArrayList JavaDoc();
482
483         private List JavaDoc rpatterns = new ArrayList JavaDoc();
484
485         public void add(String JavaDoc path, Object JavaDoc rule) {
486             String JavaDoc pattern = path;
487             if (path.startsWith("*/")) {
488                 pattern = path.substring(1);
489                 lpatterns.add(pattern);
490             } else if (path.endsWith("/*")) {
491                 pattern = path.substring(0, path.length() - 1);
492                 rpatterns.add(pattern);
493             }
494             rules.put(pattern, rule);
495         }
496
497         public Object JavaDoc match(String JavaDoc path) {
498             if (rules.containsKey(path)) {
499                 return rules.get(path);
500             }
501
502             int n = path.lastIndexOf('/');
503             for (Iterator JavaDoc it = lpatterns.iterator(); it.hasNext();) {
504                 String JavaDoc pattern = (String JavaDoc) it.next();
505                 if (path.substring(n).endsWith(pattern)) {
506                     return rules.get(pattern);
507                 }
508             }
509
510             for (Iterator JavaDoc it = rpatterns.iterator(); it.hasNext();) {
511                 String JavaDoc pattern = (String JavaDoc) it.next();
512                 if (path.startsWith(pattern)) {
513                     return rules.get(pattern);
514                 }
515             }
516
517             return null;
518         }
519
520     }
521
522     /**
523      * Rule
524      */

525     protected abstract class Rule {
526
527         public void begin(String JavaDoc name, Attributes JavaDoc attrs) {
528         }
529
530         public void end(String JavaDoc name) {
531         }
532
533         protected final Object JavaDoc getValue(String JavaDoc desc, String JavaDoc val) {
534             Object JavaDoc value = null;
535             if (val != null) {
536                 if (desc.equals("Ljava/lang/String;")) {
537                     value = decode(val);
538                 } else if ("Ljava/lang/Integer;".equals(desc)
539                         || "I".equals(desc) || "S".equals(desc)
540                         || "B".equals(desc) || "C".equals(desc)
541                         || desc.equals("Z"))
542                 {
543                     value = new Integer JavaDoc(val);
544
545                 } else if ("Ljava/lang/Short;".equals(desc)) {
546                     value = new Short JavaDoc(val);
547
548                 } else if ("Ljava/lang/Byte;".equals(desc)) {
549                     value = new Byte JavaDoc(val);
550
551                 } else if ("Ljava/lang/Character;".equals(desc)) {
552                     value = new Character JavaDoc(decode(val).charAt(0));
553
554                 } else if ("Ljava/lang/Boolean;".equals(desc)) {
555                     value = Boolean.valueOf(val);
556
557                     // } else if ("Ljava/lang/Integer;".equals(desc)
558
// || desc.equals("I"))
559
// {
560
// value = new Integer(val);
561
// } else if ("Ljava/lang/Character;".equals(desc)
562
// || desc.equals("C"))
563
// {
564
// value = new Character(decode(val).charAt(0));
565
// } else if ("Ljava/lang/Short;".equals(desc) ||
566
// desc.equals("S"))
567
// {
568
// value = Short.valueOf(val);
569
// } else if ("Ljava/lang/Byte;".equals(desc) ||
570
// desc.equals("B"))
571
// {
572
// value = Byte.valueOf(val);
573

574                 } else if ("Ljava/lang/Long;".equals(desc) || desc.equals("J"))
575                 {
576                     value = new Long JavaDoc(val);
577                 } else if ("Ljava/lang/Float;".equals(desc) || desc.equals("F"))
578                 {
579                     value = new Float JavaDoc(val);
580                 } else if ("Ljava/lang/Double;".equals(desc)
581                         || desc.equals("D"))
582                 {
583                     value = new Double JavaDoc(val);
584                 } else if (Type.getDescriptor(Type.class).equals(desc)) {
585                     value = Type.getType(val);
586
587                     // } else if ("[I".equals(desc)) {
588
// value = new int[0]; // TODO
589
// } else if ("[C".equals(desc)) {
590
// value = new char[0]; // TODO
591
// } else if ("[Z".equals(desc)) {
592
// value = new boolean[0]; // TODO
593
// } else if ("[S".equals(desc)) {
594
// value = new short[0]; // TODO
595
// } else if ("[B".equals(desc)) {
596
// value = new byte[0]; // TODO
597
// } else if ("[J".equals(desc)) {
598
// value = new long[0]; // TODO
599
// } else if ("[F".equals(desc)) {
600
// value = new float[0]; // TODO
601
// } else if ("[D".equals(desc)) {
602
// value = new double[0]; // TODO
603

604                 } else {
605                     throw new RuntimeException JavaDoc("Invalid value:" + val
606                             + " desc:" + desc + " ctx:" + this);
607                 }
608             }
609             return value;
610         }
611
612         private final String JavaDoc decode(String JavaDoc val) {
613             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(val.length());
614             try {
615                 int n = 0;
616                 while (n < val.length()) {
617                     char c = val.charAt(n);
618                     if (c == '\\') {
619                         n++;
620                         c = val.charAt(n);
621                         if (c == '\\') {
622                             sb.append('\\');
623                         } else {
624                             n++; // skip 'u'
625
sb.append((char) Integer.parseInt(val.substring(n,
626                                     n + 4), 16));
627                             n += 3;
628                         }
629                     } else {
630                         sb.append(c);
631                     }
632                     n++;
633                 }
634
635             } catch (RuntimeException JavaDoc ex) {
636                 System.err.println(val + "\n" + ex.toString());
637                 ex.printStackTrace();
638                 throw ex;
639             }
640             return sb.toString();
641         }
642
643         protected final Label getLabel(Object JavaDoc label) {
644             Label lbl = (Label) labels.get(label);
645             if (lbl == null) {
646                 lbl = new Label();
647                 labels.put(label, lbl);
648             }
649             return lbl;
650         }
651
652         // TODO verify move to stack
653
protected final MethodVisitor getCodeVisitor() {
654             return (MethodVisitor) peek();
655         }
656         
657         protected final int getAccess(String JavaDoc s) {
658             int access = 0;
659             if (s.indexOf("public") != -1)
660                 access |= Opcodes.ACC_PUBLIC;
661             if (s.indexOf("private") != -1)
662                 access |= Opcodes.ACC_PRIVATE;
663             if (s.indexOf("protected") != -1)
664                 access |= Opcodes.ACC_PROTECTED;
665             if (s.indexOf("static") != -1)
666                 access |= Opcodes.ACC_STATIC;
667             if (s.indexOf("final") != -1)
668                 access |= Opcodes.ACC_FINAL;
669             if (s.indexOf("super") != -1)
670                 access |= Opcodes.ACC_SUPER;
671             if (s.indexOf("synchronized") != -1)
672                 access |= Opcodes.ACC_SYNCHRONIZED;
673             if (s.indexOf("volatile") != -1)
674                 access |= Opcodes.ACC_VOLATILE;
675             if (s.indexOf("bridge") != -1)
676                 access |= Opcodes.ACC_BRIDGE;
677             if (s.indexOf("varargs") != -1)
678                 access |= Opcodes.ACC_VARARGS;
679             if (s.indexOf("transient") != -1)
680                 access |= Opcodes.ACC_TRANSIENT;
681             if (s.indexOf("native") != -1)
682                 access |= Opcodes.ACC_NATIVE;
683             if (s.indexOf("interface") != -1)
684                 access |= Opcodes.ACC_INTERFACE;
685             if (s.indexOf("abstract") != -1)
686                 access |= Opcodes.ACC_ABSTRACT;
687             if (s.indexOf("strict") != -1)
688                 access |= Opcodes.ACC_STRICT;
689             if (s.indexOf("synthetic") != -1)
690                 access |= Opcodes.ACC_SYNTHETIC;
691             if (s.indexOf("annotation") != -1)
692                 access |= Opcodes.ACC_ANNOTATION;
693             if (s.indexOf("enum") != -1)
694                 access |= Opcodes.ACC_ENUM;
695             if (s.indexOf("deprecated") != -1)
696                 access |= Opcodes.ACC_DEPRECATED;
697             return access;
698         }
699
700     }
701
702     /**
703      * ClassRule
704      */

705     private final class ClassRule extends Rule {
706
707         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
708             int major = Integer.parseInt(attrs.getValue("major"));
709             int minor = Integer.parseInt(attrs.getValue("minor"));
710             cw = new ClassWriter(computeMax);
711             Map JavaDoc vals = new HashMap JavaDoc();
712             vals.put("version", new Integer JavaDoc(minor << 16 | major));
713             vals.put("access", attrs.getValue("access"));
714             vals.put("name", attrs.getValue("name"));
715             vals.put("parent", attrs.getValue("parent"));
716             vals.put("source", attrs.getValue("source"));
717             vals.put("signature", attrs.getValue("signature"));
718             vals.put("interfaces", new ArrayList JavaDoc());
719             push(vals);
720             // values will be extracted in InterfacesRule.end();
721
}
722
723     }
724
725     private final class SourceRule extends Rule {
726
727         public void begin(String JavaDoc name, Attributes JavaDoc attrs) {
728             String JavaDoc file = attrs.getValue("file");
729             String JavaDoc debug = attrs.getValue("debug");
730             cw.visitSource(file, debug);
731         }
732
733     }
734
735     /**
736      * InterfaceRule
737      */

738     private final class InterfaceRule extends Rule {
739
740         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
741             ((List JavaDoc) ((Map JavaDoc) peek()).get("interfaces")).add(attrs.getValue("name"));
742         }
743
744     }
745
746     /**
747      * InterfacesRule
748      */

749     private final class InterfacesRule extends Rule {
750
751         public final void end(String JavaDoc element) {
752             Map JavaDoc vals = (Map JavaDoc) pop();
753             int version = ((Integer JavaDoc) vals.get("version")).intValue();
754             int access = getAccess((String JavaDoc) vals.get("access"));
755             String JavaDoc name = (String JavaDoc) vals.get("name");
756             String JavaDoc signature = (String JavaDoc) vals.get("signature");
757             String JavaDoc parent = (String JavaDoc) vals.get("parent");
758             List JavaDoc infs = (List JavaDoc) vals.get("interfaces");
759             String JavaDoc[] interfaces = (String JavaDoc[]) infs.toArray(new String JavaDoc[infs.size()]);
760             cw.visit(version, access, name, signature, parent, interfaces);
761             push(cw);
762         }
763
764     }
765
766     /**
767      * OuterClassRule
768      */

769     private final class OuterClassRule extends Rule {
770
771         public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
772             String JavaDoc owner = attrs.getValue("owner");
773             String JavaDoc name = attrs.getValue("name");
774             String JavaDoc desc = attrs.getValue("desc");
775             cw.visitOuterClass(owner, name, desc);
776         }
777
778     }
779
780     /**
781      * InnerClassRule
782      */

783     private final class InnerClassRule extends Rule {
784
785         public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
786             int access = getAccess(attrs.getValue("access"));
787             String JavaDoc name = attrs.getValue("name");
788             String JavaDoc outerName = attrs.getValue("outerName");
789             String JavaDoc innerName = attrs.getValue("innerName");
790             cw.visitInnerClass(name, outerName, innerName, access);
791         }
792
793     }
794
795     /**
796      * FieldRule
797      */

798     private final class FieldRule extends Rule {
799
800         public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
801             int access = getAccess(attrs.getValue("access"));
802             String JavaDoc name = attrs.getValue("name");
803             String JavaDoc signature = attrs.getValue("signature");
804             String JavaDoc desc = attrs.getValue("desc");
805             Object JavaDoc value = getValue(desc, attrs.getValue("value"));
806             push(cw.visitField(access, name, desc, signature, value));
807         }
808
809         public void end(String JavaDoc name) {
810             ((FieldVisitor) pop()).visitEnd();
811         }
812
813     }
814
815     /**
816      * MethodRule
817      */

818     private final class MethodRule extends Rule {
819
820         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
821             labels = new HashMap JavaDoc();
822             Map JavaDoc vals = new HashMap JavaDoc();
823             vals.put("access", attrs.getValue("access"));
824             vals.put("name", attrs.getValue("name"));
825             vals.put("desc", attrs.getValue("desc"));
826             vals.put("signature", attrs.getValue("signature"));
827             vals.put("exceptions", new ArrayList JavaDoc());
828             push(vals);
829             // values will be extracted in ExceptionsRule.end();
830
}
831
832         public final void end(String JavaDoc name) {
833             ((MethodVisitor) pop()).visitEnd();
834             labels = null;
835         }
836
837     }
838
839     /**
840      * ExceptionRule
841      */

842     private final class ExceptionRule extends Rule {
843
844         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
845             ((List JavaDoc) ((Map JavaDoc) peek()).get("exceptions")).add(attrs.getValue("name"));
846         }
847
848     }
849
850     /**
851      * ExceptionsRule
852      */

853     private final class ExceptionsRule extends Rule {
854
855         public final void end(String JavaDoc element) {
856             Map JavaDoc vals = (Map JavaDoc) pop();
857             int access = getAccess((String JavaDoc) vals.get("access"));
858             String JavaDoc name = (String JavaDoc) vals.get("name");
859             String JavaDoc desc = (String JavaDoc) vals.get("desc");
860             String JavaDoc signature = (String JavaDoc) vals.get("signature");
861             List JavaDoc excs = (List JavaDoc) vals.get("exceptions");
862             String JavaDoc[] exceptions = (String JavaDoc[]) excs.toArray(new String JavaDoc[excs.size()]);
863
864             push(cw.visitMethod(access, name, desc, signature, exceptions));
865         }
866
867     }
868
869     /**
870      * TableSwitchRule
871      */

872     private class TableSwitchRule extends Rule {
873
874         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
875             Map JavaDoc vals = new HashMap JavaDoc();
876             vals.put("min", attrs.getValue("min"));
877             vals.put("max", attrs.getValue("max"));
878             vals.put("dflt", attrs.getValue("dflt"));
879             vals.put("labels", new ArrayList JavaDoc());
880             push(vals);
881         }
882
883         public final void end(String JavaDoc name) {
884             Map JavaDoc vals = (Map JavaDoc) pop();
885             int min = Integer.parseInt((String JavaDoc) vals.get("min"));
886             int max = Integer.parseInt((String JavaDoc) vals.get("max"));
887             Label dflt = getLabel(vals.get("dflt"));
888             List JavaDoc lbls = (List JavaDoc) vals.get("labels");
889             Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
890             getCodeVisitor().visitTableSwitchInsn(min, max, dflt, labels);
891         }
892
893     }
894
895     /**
896      * TableSwitchLabelRule
897      */

898     private final class TableSwitchLabelRule extends Rule {
899
900         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
901             ((List JavaDoc) ((Map JavaDoc) peek()).get("labels")).add(getLabel(attrs.getValue("name")));
902         }
903
904     }
905
906     /**
907      * LookupSwitchRule
908      */

909     private final class LookupSwitchRule extends Rule {
910
911         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
912             Map JavaDoc vals = new HashMap JavaDoc();
913             vals.put("dflt", attrs.getValue("dflt"));
914             vals.put("labels", new ArrayList JavaDoc());
915             vals.put("keys", new ArrayList JavaDoc());
916             push(vals);
917         }
918
919         public final void end(String JavaDoc name) {
920             Map JavaDoc vals = (Map JavaDoc) pop();
921             Label dflt = getLabel(vals.get("dflt"));
922             List JavaDoc keyList = (List JavaDoc) vals.get("keys");
923             List JavaDoc lbls = (List JavaDoc) vals.get("labels");
924             Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
925             int[] keys = new int[keyList.size()];
926             for (int i = 0; i < keys.length; i++) {
927                 keys[i] = Integer.parseInt((String JavaDoc) keyList.get(i));
928             }
929             getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels);
930         }
931
932     }
933
934     /**
935      * LookupSwitchLabelRule
936      */

937     private final class LookupSwitchLabelRule extends Rule {
938
939         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
940             Map JavaDoc vals = (Map JavaDoc) peek();
941             ((List JavaDoc) vals.get("labels")).add(getLabel(attrs.getValue("name")));
942             ((List JavaDoc) vals.get("keys")).add(attrs.getValue("key"));
943         }
944
945     }
946
947     /**
948      * LabelRule
949      */

950     private final class LabelRule extends Rule {
951
952         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
953             getCodeVisitor().visitLabel(getLabel(attrs.getValue("name")));
954         }
955
956     }
957
958     /**
959      * TryCatchRule
960      */

961     private final class TryCatchRule extends Rule {
962
963         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
964             Label start = getLabel(attrs.getValue("start"));
965             Label end = getLabel(attrs.getValue("end"));
966             Label handler = getLabel(attrs.getValue("handler"));
967             String JavaDoc type = attrs.getValue("type");
968             getCodeVisitor().visitTryCatchBlock(start, end, handler, type);
969         }
970
971     }
972
973     /**
974      * LineNumberRule
975      */

976     private final class LineNumberRule extends Rule {
977
978         public final void begin(String JavaDoc name, Attributes JavaDoc attrs) {
979             int line = Integer.parseInt(attrs.getValue("line"));
980             Label start = getLabel(attrs.getValue("start"));
981             getCodeVisitor().visitLineNumber(line, start);
982         }
983
984     }
985
986     /**
987      * LocalVarRule
988      */

989     private final class LocalVarRule extends Rule {
990
991         public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
992             String JavaDoc name = attrs.getValue("name");
993             String JavaDoc desc = attrs.getValue("desc");
994             String JavaDoc signature = attrs.getValue("signature");
995             Label start = getLabel(attrs.getValue("start"));
996             Label end = getLabel(attrs.getValue("end"));
997             int var = Integer.parseInt(attrs.getValue("var"));
998             getCodeVisitor().visitLocalVariable(name,
999                     desc,
1000                    signature,
1001                    start,
1002                    end,
1003                    var);
1004        }
1005
1006    }
1007
1008    /**
1009     * OpcodesRule
1010     */

1011    private final class OpcodesRule extends Rule {
1012
1013        // public boolean match( String match, String element) {
1014
// return match.startsWith( path) && OPCODES.containsKey( element);
1015
// }
1016

1017        public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
1018            Opcode o = ((Opcode) OPCODES.get(element));
1019            if (o == null)
1020                return;
1021
1022            switch (o.type) {
1023                case OpcodeGroup.INSN:
1024                    getCodeVisitor().visitInsn(o.opcode);
1025                    break;
1026
1027                case OpcodeGroup.INSN_FIELD:
1028                    getCodeVisitor().visitFieldInsn(o.opcode,
1029                            attrs.getValue("owner"),
1030                            attrs.getValue("name"),
1031                            attrs.getValue("desc"));
1032                    break;
1033
1034                case OpcodeGroup.INSN_INT:
1035                    getCodeVisitor().visitIntInsn(o.opcode,
1036                            Integer.parseInt(attrs.getValue("value")));
1037                    break;
1038
1039                case OpcodeGroup.INSN_JUMP:
1040                    getCodeVisitor().visitJumpInsn(o.opcode,
1041                            getLabel(attrs.getValue("label")));
1042                    break;
1043
1044                case OpcodeGroup.INSN_METHOD:
1045                    getCodeVisitor().visitMethodInsn(o.opcode,
1046                            attrs.getValue("owner"),
1047                            attrs.getValue("name"),
1048                            attrs.getValue("desc"));
1049                    break;
1050
1051                case OpcodeGroup.INSN_TYPE:
1052                    getCodeVisitor().visitTypeInsn(o.opcode,
1053                            attrs.getValue("desc"));
1054                    break;
1055
1056                case OpcodeGroup.INSN_VAR:
1057                    getCodeVisitor().visitVarInsn(o.opcode,
1058                            Integer.parseInt(attrs.getValue("var")));
1059                    break;
1060
1061                case OpcodeGroup.INSN_IINC:
1062                    getCodeVisitor().visitIincInsn(Integer.parseInt(attrs.getValue("var")),
1063                            Integer.parseInt(attrs.getValue("inc")));
1064                    break;
1065
1066                case OpcodeGroup.INSN_LDC:
1067                    getCodeVisitor().visitLdcInsn(getValue(attrs.getValue("desc"),
1068                            attrs.getValue("cst")));
1069                    break;
1070
1071                case OpcodeGroup.INSN_MULTIANEWARRAY:
1072                    getCodeVisitor().visitMultiANewArrayInsn(attrs.getValue("desc"),
1073                            Integer.parseInt(attrs.getValue("dims")));
1074                    break;
1075
1076                default:
1077                    throw new RuntimeException JavaDoc("Invalid element: " + element
1078                            + " at " + match);
1079
1080            }
1081        }
1082    }
1083
1084    /**
1085     * MaxRule
1086     */

1087    private final class MaxRule extends Rule {
1088
1089        public final void begin(String JavaDoc element, Attributes JavaDoc attrs) {
1090            int maxStack = Integer.parseInt(attrs.getValue("maxStack"));
1091            int maxLocals = Integer.parseInt(attrs.getValue("maxLocals"));
1092            getCodeVisitor().visitMaxs(maxStack, maxLocals);
1093        }
1094
1095    }
1096
1097    private final class AnnotationRule extends Rule {
1098
1099        public void begin(String JavaDoc name, Attributes JavaDoc attrs) {
1100            String JavaDoc desc = attrs.getValue("desc");
1101            boolean visible = Boolean.valueOf(attrs.getValue("visible"))
1102                    .booleanValue();
1103
1104            Object JavaDoc v = peek();
1105            if (v instanceof ClassVisitor) {
1106                push(((ClassVisitor) v).visitAnnotation(desc, visible));
1107            } else if (v instanceof FieldVisitor) {
1108                push(((FieldVisitor) v).visitAnnotation(desc, visible));
1109            } else if (v instanceof MethodVisitor) {
1110                push(((MethodVisitor) v).visitAnnotation(desc, visible));
1111            }
1112        }
1113
1114        public void end(String JavaDoc name) {
1115            ((AnnotationVisitor) pop()).visitEnd();
1116        }
1117
1118    }
1119
1120    private final class AnnotationParameterRule extends Rule {
1121
1122        public void begin(String JavaDoc name, Attributes JavaDoc attrs) {
1123            int parameter = Integer.parseInt(attrs.getValue("parameter"));
1124            String JavaDoc desc = attrs.getValue("desc");
1125            boolean visible = Boolean.valueOf(attrs.getValue("visible"))
1126                    .booleanValue();
1127
1128            push(((MethodVisitor) peek()).visitParameterAnnotation(parameter,
1129                    desc,
1130                    visible));
1131        }
1132
1133        public void end(String JavaDoc name) {
1134            ((AnnotationVisitor) pop()).visitEnd();
1135        }
1136
1137    }
1138
1139    private final class AnnotationValueRule extends Rule {
1140
1141        public void begin(String JavaDoc nm, Attributes JavaDoc attrs) {
1142            String JavaDoc name = attrs.getValue("name");
1143            String JavaDoc desc = attrs.getValue("desc");
1144            String JavaDoc value = attrs.getValue("value");
1145            ((AnnotationVisitor) peek()).visit(name, getValue(desc, value));
1146        }
1147
1148    }
1149
1150    private final class AnnotationValueEnumRule extends Rule {
1151
1152        public void begin(String JavaDoc nm, Attributes JavaDoc attrs) {
1153            String JavaDoc name = attrs.getValue("name");
1154            String JavaDoc desc = attrs.getValue("desc");
1155            String JavaDoc value = attrs.getValue("value");
1156            ((AnnotationVisitor) peek()).visitEnum(name, desc, value);
1157        }
1158
1159    }
1160
1161    private final class AnnotationValueAnnotationRule extends Rule {
1162
1163        public void begin(String JavaDoc nm, Attributes JavaDoc attrs) {
1164            String JavaDoc name = attrs.getValue("name");
1165            String JavaDoc desc = attrs.getValue("desc");
1166            push(((AnnotationVisitor) peek()).visitAnnotation(name, desc));
1167        }
1168
1169        public void end(String JavaDoc name) {
1170            ((AnnotationVisitor) pop()).visitEnd();
1171        }
1172
1173    }
1174
1175    private final class AnnotationValueArrayRule extends Rule {
1176
1177        public void begin(String JavaDoc nm, Attributes JavaDoc attrs) {
1178            String JavaDoc name = attrs.getValue("name");
1179            push(((AnnotationVisitor) peek()).visitArray(name));
1180        }
1181
1182        public void end(String JavaDoc name) {
1183            ((AnnotationVisitor) pop()).visitEnd();
1184        }
1185
1186    }
1187
1188    private final class AnnotationDefaultRule extends Rule {
1189
1190        public void begin(String JavaDoc nm, Attributes JavaDoc attrs) {
1191            push(((MethodVisitor) peek()).visitAnnotationDefault());
1192        }
1193
1194        public void end(String JavaDoc name) {
1195            ((AnnotationVisitor) pop()).visitEnd();
1196        }
1197
1198    }
1199
1200    /**
1201     * Opcode
1202     */

1203    private final static class Opcode {
1204        public int opcode;
1205
1206        public int type;
1207
1208        public Opcode(int opcode, int type) {
1209            this.opcode = opcode;
1210            this.type = type;
1211        }
1212
1213    }
1214
1215}
1216
Popular Tags