• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.objectweb.asm.xml;
31 
32 import org.objectweb.asm.AnnotationVisitor;
33 import org.objectweb.asm.Attribute;
34 import org.objectweb.asm.ClassVisitor;
35 import org.objectweb.asm.TypeAnnotationVisitor;
36 import org.objectweb.asm.FieldVisitor;
37 import org.objectweb.asm.MethodVisitor;
38 import org.objectweb.asm.Opcodes;
39 import org.xml.sax.ContentHandler;
40 import org.xml.sax.helpers.AttributesImpl;
41 
42 /**
43  * A {@link org.objectweb.asm.ClassVisitor ClassVisitor} that generates SAX 2.0
44  * events from the visited class. It can feed any kind of
45  * {@link org.xml.sax.ContentHandler ContentHandler}, e.g. XML serializer, XSLT
46  * or XQuery engines.
47  *
48  * @see org.objectweb.asm.xml.Processor
49  * @see org.objectweb.asm.xml.ASMContentHandler
50  *
51  * @author Eugene Kuleshov
52  */
53 public final class SAXClassAdapter extends SAXAdapter implements ClassVisitor {
54     private boolean singleDocument;
55 
56     /**
57      * Constructs a new {@link SAXClassAdapter SAXClassAdapter} object.
58      *
59      * @param h content handler that will be used to send SAX 2.0 events.
60      * @param singleDocument if <tt>true</tt> adapter will not produce
61      *        {@link ContentHandler#startDocument() startDocument()} and
62      *        {@link ContentHandler#endDocument() endDocument()} events.
63      */
SAXClassAdapter(ContentHandler h, boolean singleDocument)64     public SAXClassAdapter(ContentHandler h, boolean singleDocument) {
65         super(h);
66         this.singleDocument = singleDocument;
67         if (!singleDocument) {
68             addDocumentStart();
69         }
70     }
71 
visitSource(String source, String debug)72     public void visitSource(String source, String debug) {
73         if (source == null && debug == null) {
74             return;
75         }
76 
77         AttributesImpl att = new AttributesImpl();
78         if (source != null)
79             att.addAttribute("", "file", "file", "", encode(source));
80         if (debug != null)
81             att.addAttribute("", "debug", "debug", "", encode(debug));
82 
83         addElement("source", att);
84     }
85 
visitOuterClass(String owner, String name, String desc)86     public void visitOuterClass(String owner, String name, String desc) {
87         AttributesImpl att = new AttributesImpl();
88         att.addAttribute("", "owner", "owner", "", owner);
89         if (name != null)
90             att.addAttribute("", "name", "name", "", name);
91         if (desc != null)
92             att.addAttribute("", "desc", "desc", "", desc);
93 
94         addElement("outerclass", att);
95     }
96 
visitAttribute(Attribute attr)97     public final void visitAttribute(Attribute attr) {
98         // TODO Auto-generated SAXClassAdapter.visitAttribute
99     }
100 
visitAnnotation(String desc, boolean visible)101     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
102         return new SAXAnnotationAdapter(getContentHandler(),
103                 "annotation",
104                 visible ? 1 : -1,
105                 null,
106                 desc);
107     }
108 
visitTypeAnnotation( String desc, boolean visible, boolean inCode)109     public TypeAnnotationVisitor visitTypeAnnotation(
110         String desc, boolean visible, boolean inCode) {
111         throw new RuntimeException("Jaime did not implement yet");
112     }
113 
visit( int version, int access, String name, String signature, String superName, String[] interfaces)114     public void visit(
115         int version,
116         int access,
117         String name,
118         String signature,
119         String superName,
120         String[] interfaces)
121     {
122         StringBuffer sb = new StringBuffer();
123         if ((access & Opcodes.ACC_PUBLIC) != 0)
124             sb.append("public ");
125         if ((access & Opcodes.ACC_PRIVATE) != 0)
126             sb.append("private ");
127         if ((access & Opcodes.ACC_PROTECTED) != 0)
128             sb.append("protected ");
129         if ((access & Opcodes.ACC_FINAL) != 0)
130             sb.append("final ");
131         if ((access & Opcodes.ACC_SUPER) != 0)
132             sb.append("super ");
133         if ((access & Opcodes.ACC_INTERFACE) != 0)
134             sb.append("interface ");
135         if ((access & Opcodes.ACC_ABSTRACT) != 0)
136             sb.append("abstract ");
137         if ((access & Opcodes.ACC_SYNTHETIC) != 0)
138             sb.append("synthetic ");
139         if ((access & Opcodes.ACC_ANNOTATION) != 0)
140             sb.append("annotation ");
141         if ((access & Opcodes.ACC_ENUM) != 0)
142             sb.append("enum ");
143         if ((access & Opcodes.ACC_DEPRECATED) != 0)
144             sb.append("deprecated ");
145 
146         AttributesImpl att = new AttributesImpl();
147         att.addAttribute("", "access", "access", "", sb.toString());
148         if (name != null)
149             att.addAttribute("", "name", "name", "", name);
150         if (signature != null)
151             att.addAttribute("",
152                     "signature",
153                     "signature",
154                     "",
155                     encode(signature));
156         if (superName != null)
157             att.addAttribute("", "parent", "parent", "", superName);
158         att.addAttribute("",
159                 "major",
160                 "major",
161                 "",
162                 Integer.toString(version & 0xFFFF));
163         att.addAttribute("",
164                 "minor",
165                 "minor",
166                 "",
167                 Integer.toString(version >>> 16));
168         addStart("class", att);
169 
170         addStart("interfaces", new AttributesImpl());
171         if (interfaces != null && interfaces.length > 0) {
172             for (int i = 0; i < interfaces.length; i++) {
173                 AttributesImpl att2 = new AttributesImpl();
174                 att2.addAttribute("", "name", "name", "", interfaces[i]);
175                 addElement("interface", att2);
176             }
177         }
178         addEnd("interfaces");
179     }
180 
visitField( int access, String name, String desc, String signature, Object value)181     public FieldVisitor visitField(
182         int access,
183         String name,
184         String desc,
185         String signature,
186         Object value)
187     {
188         StringBuffer sb = new StringBuffer();
189         if ((access & Opcodes.ACC_PUBLIC) != 0)
190             sb.append("public ");
191         if ((access & Opcodes.ACC_PRIVATE) != 0)
192             sb.append("private ");
193         if ((access & Opcodes.ACC_PROTECTED) != 0)
194             sb.append("protected ");
195         if ((access & Opcodes.ACC_STATIC) != 0)
196             sb.append("static ");
197         if ((access & Opcodes.ACC_FINAL) != 0)
198             sb.append("final ");
199         if ((access & Opcodes.ACC_VOLATILE) != 0)
200             sb.append("volatile ");
201         if ((access & Opcodes.ACC_TRANSIENT) != 0)
202             sb.append("transient ");
203         if ((access & Opcodes.ACC_SYNTHETIC) != 0)
204             sb.append("synthetic ");
205         if ((access & Opcodes.ACC_ENUM) != 0)
206             sb.append("enum ");
207         if ((access & Opcodes.ACC_DEPRECATED) != 0)
208             sb.append("deprecated ");
209 
210         AttributesImpl att = new AttributesImpl();
211         att.addAttribute("", "access", "access", "", sb.toString());
212         att.addAttribute("", "name", "name", "", name);
213         att.addAttribute("", "desc", "desc", "", desc);
214         if (signature != null)
215             att.addAttribute("",
216                     "signature",
217                     "signature",
218                     "",
219                     encode(signature));
220         if (value != null) {
221             att.addAttribute("", "value", "value", "", encode(value.toString()));
222         }
223 
224         return new SAXFieldAdapter(getContentHandler(), att);
225     }
226 
visitMethod( int access, String name, String desc, String signature, String[] exceptions)227     public MethodVisitor visitMethod(
228         int access,
229         String name,
230         String desc,
231         String signature,
232         String[] exceptions)
233     {
234         StringBuffer sb = new StringBuffer();
235         if ((access & Opcodes.ACC_PUBLIC) != 0)
236             sb.append("public ");
237         if ((access & Opcodes.ACC_PRIVATE) != 0)
238             sb.append("private ");
239         if ((access & Opcodes.ACC_PROTECTED) != 0)
240             sb.append("protected ");
241         if ((access & Opcodes.ACC_STATIC) != 0)
242             sb.append("static ");
243         if ((access & Opcodes.ACC_FINAL) != 0)
244             sb.append("final ");
245         if ((access & Opcodes.ACC_SYNCHRONIZED) != 0)
246             sb.append("synchronized ");
247         if ((access & Opcodes.ACC_BRIDGE) != 0)
248             sb.append("bridge ");
249         if ((access & Opcodes.ACC_VARARGS) != 0)
250             sb.append("varargs ");
251         if ((access & Opcodes.ACC_NATIVE) != 0)
252             sb.append("native ");
253         if ((access & Opcodes.ACC_ABSTRACT) != 0)
254             sb.append("abstract ");
255         if ((access & Opcodes.ACC_STRICT) != 0)
256             sb.append("strict ");
257         if ((access & Opcodes.ACC_SYNTHETIC) != 0)
258             sb.append("synthetic ");
259         if ((access & Opcodes.ACC_DEPRECATED) != 0)
260             sb.append("deprecated ");
261 
262         AttributesImpl att = new AttributesImpl();
263         att.addAttribute("", "access", "access", "", sb.toString());
264         att.addAttribute("", "name", "name", "", name);
265         att.addAttribute("", "desc", "desc", "", desc);
266         if (signature != null) {
267             att.addAttribute("", "signature", "signature", "", signature);
268         }
269         addStart("method", att);
270 
271         addStart("exceptions", new AttributesImpl());
272         if (exceptions != null && exceptions.length > 0) {
273             for (int i = 0; i < exceptions.length; i++) {
274                 AttributesImpl att2 = new AttributesImpl();
275                 att2.addAttribute("", "name", "name", "", exceptions[i]);
276                 addElement("exception", att2);
277             }
278         }
279         addEnd("exceptions");
280 
281         return new SAXCodeAdapter(getContentHandler(), access);
282     }
283 
visitInnerClass( String name, String outerName, String innerName, int access)284     public final void visitInnerClass(
285         String name,
286         String outerName,
287         String innerName,
288         int access)
289     {
290         StringBuffer sb = new StringBuffer();
291         if ((access & Opcodes.ACC_PUBLIC) != 0)
292             sb.append("public ");
293         if ((access & Opcodes.ACC_PRIVATE) != 0)
294             sb.append("private ");
295         if ((access & Opcodes.ACC_PROTECTED) != 0)
296             sb.append("protected ");
297         if ((access & Opcodes.ACC_STATIC) != 0)
298             sb.append("static ");
299         if ((access & Opcodes.ACC_FINAL) != 0)
300             sb.append("final ");
301         if ((access & Opcodes.ACC_SUPER) != 0)
302             sb.append("super ");
303         if ((access & Opcodes.ACC_INTERFACE) != 0)
304             sb.append("interface ");
305         if ((access & Opcodes.ACC_ABSTRACT) != 0)
306             sb.append("abstract ");
307         if ((access & Opcodes.ACC_SYNTHETIC) != 0)
308             sb.append("synthetic ");
309         if ((access & Opcodes.ACC_ANNOTATION) != 0)
310             sb.append("annotation ");
311         if ((access & Opcodes.ACC_ENUM) != 0)
312             sb.append("enum ");
313         if ((access & Opcodes.ACC_DEPRECATED) != 0)
314             sb.append("deprecated ");
315 
316         AttributesImpl att = new AttributesImpl();
317         att.addAttribute("", "access", "access", "", sb.toString());
318         if (name != null)
319             att.addAttribute("", "name", "name", "", name);
320         if (outerName != null)
321             att.addAttribute("", "outerName", "outerName", "", outerName);
322         if (innerName != null)
323             att.addAttribute("", "innerName", "innerName", "", innerName);
324         addElement("innerclass", att);
325     }
326 
visitEnd()327     public final void visitEnd() {
328         addEnd("class");
329         if (!singleDocument) {
330             addDocumentEnd();
331         }
332     }
333 
encode(String s)334     static final String encode(String s) {
335         StringBuffer sb = new StringBuffer();
336         for (int i = 0; i < s.length(); i++) {
337             char c = s.charAt(i);
338             if (c == '\\') {
339                 sb.append("\\\\");
340             } else if (c < 0x20 || c > 0x7f) {
341                 sb.append("\\u");
342                 if (c < 0x10) {
343                     sb.append("000");
344                 } else if (c < 0x100) {
345                     sb.append("00");
346                 } else if (c < 0x1000) {
347                     sb.append("0");
348                 }
349                 sb.append(Integer.toString(c, 16));
350             } else {
351                 sb.append(c);
352             }
353         }
354         return sb.toString();
355     }
356 
357 }
358