001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.bytecode;
005:
006: import com.tc.asm.AnnotationVisitor;
007: import com.tc.asm.Attribute;
008: import com.tc.asm.Label;
009: import com.tc.asm.MethodVisitor;
010:
011: import java.util.HashMap;
012: import java.util.Map;
013:
014: /**
015: * MethodVisitor that is able to delegate all the calls to an array of other
016: * method visitors. Labels are properly created for each individual visitor
017: * and a simple mapping is maintained to be able to retrieve which label
018: * belongs to which visitor.
019: */
020: public class MulticastMethodVisitor implements MethodVisitor {
021:
022: private final MethodVisitor[] visitors;
023:
024: private final Map labelsMapping = new HashMap();
025:
026: public MulticastMethodVisitor(MethodVisitor[] visitors) {
027: this .visitors = visitors;
028: }
029:
030: public AnnotationVisitor visitAnnotation(String desc,
031: boolean visible) {
032: AnnotationVisitor[] annotationVisitors = new AnnotationVisitor[visitors.length];
033: for (int i = 0; i < visitors.length; i++) {
034: annotationVisitors[i] = visitors[i].visitAnnotation(desc,
035: visible);
036: }
037:
038: return new MulticastAnnotationVisitor(annotationVisitors);
039: }
040:
041: public AnnotationVisitor visitAnnotationDefault() {
042: AnnotationVisitor[] annotationVisitors = new AnnotationVisitor[visitors.length];
043: for (int i = 0; i < visitors.length; i++) {
044: annotationVisitors[i] = visitors[i]
045: .visitAnnotationDefault();
046: }
047:
048: return new MulticastAnnotationVisitor(annotationVisitors);
049: }
050:
051: public void visitAttribute(Attribute attr) {
052: for (int i = 0; i < visitors.length; i++) {
053: visitors[i].visitAttribute(attr);
054: }
055: }
056:
057: public void visitCode() {
058: for (int i = 0; i < visitors.length; i++) {
059: visitors[i].visitCode();
060: }
061: }
062:
063: public void visitEnd() {
064: for (int i = 0; i < visitors.length; i++) {
065: visitors[i].visitEnd();
066: }
067: }
068:
069: public void visitFieldInsn(int opcode, String owner, String name,
070: String desc) {
071: for (int i = 0; i < visitors.length; i++) {
072: visitors[i].visitFieldInsn(opcode, owner, name, desc);
073: }
074: }
075:
076: public void visitFrame(int type, int local, Object[] local2,
077: int stack, Object[] stack2) {
078: for (int i = 0; i < visitors.length; i++) {
079: visitors[i].visitFrame(type, local, local2, stack, stack2);
080: }
081: }
082:
083: public void visitIincInsn(int var, int increment) {
084: for (int i = 0; i < visitors.length; i++) {
085: visitors[i].visitIincInsn(var, increment);
086: }
087: }
088:
089: public void visitInsn(int opcode) {
090: for (int i = 0; i < visitors.length; i++) {
091: visitors[i].visitInsn(opcode);
092: }
093: }
094:
095: public void visitIntInsn(int opcode, int operand) {
096: for (int i = 0; i < visitors.length; i++) {
097: visitors[i].visitIntInsn(opcode, operand);
098: }
099: }
100:
101: public void visitJumpInsn(int opcode, Label label) {
102: for (int i = 0; i < visitors.length; i++) {
103: visitors[i].visitJumpInsn(opcode, getMappedLabel(label, i));
104: }
105: }
106:
107: public void visitLabel(Label label) {
108: for (int i = 0; i < visitors.length; i++) {
109: visitors[i].visitLabel(getMappedLabel(label, i));
110: }
111: }
112:
113: public void visitLdcInsn(Object cst) {
114: for (int i = 0; i < visitors.length; i++) {
115: visitors[i].visitLdcInsn(cst);
116: }
117: }
118:
119: public void visitLineNumber(int line, Label start) {
120: for (int i = 0; i < visitors.length; i++) {
121: visitors[i].visitLineNumber(line, getMappedLabel(start, i));
122: }
123: }
124:
125: public void visitLocalVariable(String name, String desc,
126: String signature, Label start, Label end, int index) {
127: for (int i = 0; i < visitors.length; i++) {
128: visitors[i].visitLocalVariable(name, desc, signature,
129: getMappedLabel(start, i), getMappedLabel(end, i),
130: index);
131: }
132: }
133:
134: public void visitLookupSwitchInsn(Label dflt, int[] keys,
135: Label[] labels) {
136: for (int i = 0; i < visitors.length; i++) {
137: visitors[i].visitLookupSwitchInsn(getMappedLabel(dflt, i),
138: keys, getMappedLabels(labels, i));
139: }
140: }
141:
142: public void visitMaxs(int maxStack, int maxLocals) {
143: for (int i = 0; i < visitors.length; i++) {
144: visitors[i].visitMaxs(maxStack, maxLocals);
145: }
146: }
147:
148: public void visitMethodInsn(int opcode, String owner, String name,
149: String desc) {
150: for (int i = 0; i < visitors.length; i++) {
151: visitors[i].visitMethodInsn(opcode, owner, name, desc);
152: }
153: }
154:
155: public void visitMultiANewArrayInsn(String desc, int dims) {
156: for (int i = 0; i < visitors.length; i++) {
157: visitors[i].visitMultiANewArrayInsn(desc, dims);
158: }
159: }
160:
161: public AnnotationVisitor visitParameterAnnotation(int parameter,
162: String desc, boolean visible) {
163: AnnotationVisitor[] annotationVisitors = new AnnotationVisitor[visitors.length];
164: for (int i = 0; i < visitors.length; i++) {
165: annotationVisitors[i] = visitors[i]
166: .visitParameterAnnotation(parameter, desc, visible);
167: }
168:
169: return new MulticastAnnotationVisitor(annotationVisitors);
170: }
171:
172: public void visitTableSwitchInsn(int min, int max, Label dflt,
173: Label[] labels) {
174: for (int i = 0; i < visitors.length; i++) {
175: visitors[i].visitTableSwitchInsn(min, max, getMappedLabel(
176: dflt, i), getMappedLabels(labels, i));
177: }
178: }
179:
180: public void visitTryCatchBlock(Label start, Label end,
181: Label handler, String type) {
182: for (int i = 0; i < visitors.length; i++) {
183: visitors[i].visitTryCatchBlock(getMappedLabel(start, i),
184: getMappedLabel(end, i), getMappedLabel(handler, i),
185: type);
186: }
187: }
188:
189: public void visitTypeInsn(int opcode, String desc) {
190: for (int i = 0; i < visitors.length; i++) {
191: visitors[i].visitTypeInsn(opcode, desc);
192: }
193: }
194:
195: public void visitVarInsn(int opcode, int var) {
196: for (int i = 0; i < visitors.length; i++) {
197: visitors[i].visitVarInsn(opcode, var);
198: }
199: }
200:
201: private Label getMappedLabel(Label original, int visitorIndex) {
202: if (null == original)
203: return null;
204: return getMappedLabels(original)[visitorIndex];
205: }
206:
207: private Label[] getMappedLabels(Label[] originals, int visitorIndex) {
208: if (null == originals)
209: return null;
210:
211: Label[] result = new Label[originals.length];
212: for (int i = 0; i < result.length; i++) {
213: result[i] = getMappedLabel(originals[i], visitorIndex);
214: }
215: return result;
216: }
217:
218: private Label[] getMappedLabels(Label original) {
219: Label[] labels = (Label[]) labelsMapping.get(original);
220: if (null == labels) {
221: labels = new Label[visitors.length];
222: for (int i = 0; i < visitors.length; i++) {
223: labels[i] = new Label();
224: }
225: labelsMapping.put(original, labels);
226: }
227: return labels;
228: }
229: }
|