001: /***
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */package org.drools.asm.util;
030:
031: import java.util.HashMap;
032:
033: import org.drools.asm.AnnotationVisitor;
034: import org.drools.asm.Attribute;
035: import org.drools.asm.Type;
036: import org.drools.asm.util.attrs.ASMifiable;
037:
038: /**
039: * An abstract ASMifier visitor.
040: *
041: * @author Eric Bruneton
042: */
043: public class ASMifierAbstractVisitor extends AbstractVisitor {
044:
045: /**
046: * The name of the variable for this visitor in the produced code.
047: */
048: protected String name;
049:
050: /**
051: * The label names. This map associates String values to Label keys. It is
052: * used only in ASMifierMethodVisitor.
053: */
054: HashMap labelNames;
055:
056: /**
057: * Constructs a new {@link ASMifierAbstractVisitor}.
058: *
059: * @param name the name of the variable for this visitor in the produced
060: * code.
061: */
062: protected ASMifierAbstractVisitor(final String name) {
063: this .name = name;
064: }
065:
066: /**
067: * Prints the ASM code that generates the given annotation.
068: *
069: * @param desc the class descriptor of the annotation class.
070: * @param visible <tt>true</tt> if the annotation is visible at runtime.
071: * @return a visitor to visit the annotation values.
072: */
073: public AnnotationVisitor visitAnnotation(final String desc,
074: final boolean visible) {
075: this .buf.setLength(0);
076: this .buf.append("{\n").append("av0 = ").append(this .name)
077: .append(".visitAnnotation(");
078: appendConstant(desc);
079: this .buf.append(", ").append(visible).append(");\n");
080: this .text.add(this .buf.toString());
081: final ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(
082: 0);
083: this .text.add(av.getText());
084: this .text.add("}\n");
085: return av;
086: }
087:
088: /**
089: * Prints the ASM code that generates the given attribute.
090: *
091: * @param attr an attribute.
092: */
093: public void visitAttribute(final Attribute attr) {
094: this .buf.setLength(0);
095: if (attr instanceof ASMifiable) {
096: this .buf.append("{\n");
097: this .buf.append("// ATTRIBUTE\n");
098: ((ASMifiable) attr).asmify(this .buf, "attr",
099: this .labelNames);
100: this .buf.append(this .name).append(
101: ".visitAttribute(attr);\n");
102: this .buf.append("}\n");
103: } else {
104: this .buf
105: .append("// WARNING! skipped a non standard attribute of type \"");
106: this .buf.append(attr.type).append("\"\n");
107: }
108: this .text.add(this .buf.toString());
109: }
110:
111: /**
112: * Prints the ASM code to end the visit.
113: */
114: public void visitEnd() {
115: this .buf.setLength(0);
116: this .buf.append(this .name).append(".visitEnd();\n");
117: this .text.add(this .buf.toString());
118: }
119:
120: /**
121: * Appends a string representation of the given constant to the given
122: * buffer.
123: *
124: * @param cst an {@link Integer}, {@link Float}, {@link Long},
125: * {@link Double} or {@link String} object. May be <tt>null</tt>.
126: */
127: void appendConstant(final Object cst) {
128: appendConstant(this .buf, cst);
129: }
130:
131: /**
132: * Appends a string representation of the given constant to the given
133: * buffer.
134: *
135: * @param buf a string buffer.
136: * @param cst an {@link Integer}, {@link Float}, {@link Long},
137: * {@link Double} or {@link String} object. May be <tt>null</tt>.
138: */
139: static void appendConstant(final StringBuffer buf, final Object cst) {
140: if (cst == null) {
141: buf.append("null");
142: } else if (cst instanceof String) {
143: appendString(buf, (String) cst);
144: } else if (cst instanceof Type) {
145: buf.append("Type.getType(\"");
146: buf.append(((Type) cst).getDescriptor());
147: buf.append("\")");
148: } else if (cst instanceof Byte) {
149: buf.append("new Byte((byte)").append(cst).append(")");
150: } else if (cst instanceof Boolean) {
151: buf.append("new Boolean(").append(cst).append(")");
152: } else if (cst instanceof Short) {
153: buf.append("new Short((short)").append(cst).append(")");
154: } else if (cst instanceof Character) {
155: final int c = ((Character) cst).charValue();
156: buf.append("new Character((char)").append(c).append(")");
157: } else if (cst instanceof Integer) {
158: buf.append("new Integer(").append(cst).append(")");
159: } else if (cst instanceof Float) {
160: buf.append("new Float(\"").append(cst).append("\")");
161: } else if (cst instanceof Long) {
162: buf.append("new Long(").append(cst).append("L)");
163: } else if (cst instanceof Double) {
164: buf.append("new Double(\"").append(cst).append("\")");
165: } else if (cst instanceof byte[]) {
166: final byte[] v = (byte[]) cst;
167: buf.append("new byte[] {");
168: for (int i = 0; i < v.length; i++) {
169: buf.append(i == 0 ? "" : ",").append(v[i]);
170: }
171: buf.append("}");
172: } else if (cst instanceof boolean[]) {
173: final boolean[] v = (boolean[]) cst;
174: buf.append("new boolean[] {");
175: for (int i = 0; i < v.length; i++) {
176: buf.append(i == 0 ? "" : ",").append(v[i]);
177: }
178: buf.append("}");
179: } else if (cst instanceof short[]) {
180: final short[] v = (short[]) cst;
181: buf.append("new short[] {");
182: for (int i = 0; i < v.length; i++) {
183: buf.append(i == 0 ? "" : ",").append("(short)").append(
184: v[i]);
185: }
186: buf.append("}");
187: } else if (cst instanceof char[]) {
188: final char[] v = (char[]) cst;
189: buf.append("new char[] {");
190: for (int i = 0; i < v.length; i++) {
191: buf.append(i == 0 ? "" : ",").append("(char)").append(
192: (int) v[i]);
193: }
194: buf.append("}");
195: } else if (cst instanceof int[]) {
196: final int[] v = (int[]) cst;
197: buf.append("new int[] {");
198: for (int i = 0; i < v.length; i++) {
199: buf.append(i == 0 ? "" : ",").append(v[i]);
200: }
201: buf.append("}");
202: } else if (cst instanceof long[]) {
203: final long[] v = (long[]) cst;
204: buf.append("new long[] {");
205: for (int i = 0; i < v.length; i++) {
206: buf.append(i == 0 ? "" : ",").append(v[i]).append("L");
207: }
208: buf.append("}");
209: } else if (cst instanceof float[]) {
210: final float[] v = (float[]) cst;
211: buf.append("new float[] {");
212: for (int i = 0; i < v.length; i++) {
213: buf.append(i == 0 ? "" : ",").append(v[i]).append("f");
214: }
215: buf.append("}");
216: } else if (cst instanceof double[]) {
217: final double[] v = (double[]) cst;
218: buf.append("new double[] {");
219: for (int i = 0; i < v.length; i++) {
220: buf.append(i == 0 ? "" : ",").append(v[i]).append("d");
221: }
222: buf.append("}");
223: }
224: }
225: }
|