001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JCheckClassAdapter.java 2057 2007-11-21 15:35:32Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.tests.enhancer;
025:
026: import java.util.List;
027:
028: import org.ow2.easybeans.asm.ClassReader;
029: import org.ow2.easybeans.asm.ClassVisitor;
030: import org.ow2.easybeans.asm.Opcodes;
031: import org.ow2.easybeans.asm.Type;
032: import org.ow2.easybeans.asm.tree.ClassNode;
033: import org.ow2.easybeans.asm.tree.MethodNode;
034: import org.ow2.easybeans.asm.tree.analysis.Analyzer;
035: import org.ow2.easybeans.asm.tree.analysis.AnalyzerException;
036: import org.ow2.easybeans.asm.tree.analysis.Frame;
037: import org.ow2.easybeans.asm.tree.analysis.SimpleVerifier;
038: import org.ow2.easybeans.asm.util.CheckClassAdapter;
039: import org.ow2.easybeans.asm.util.TraceMethodVisitor;
040:
041: /**
042: * Checks a class.
043: * @author Florent Benoit
044: */
045: public class JCheckClassAdapter extends CheckClassAdapter {
046:
047: /**
048: * Start of int (debug traces).
049: */
050: private static final int START_INT = 100000;
051:
052: /**
053: * Constructs a new JCheckClassAdapter.
054: * @param cv the class visitor to which this adapter must delegate calls.
055: */
056: public JCheckClassAdapter(final ClassVisitor cv) {
057: super (cv);
058: }
059:
060: /**
061: * Check a set of bytes.
062: * @param bytes representing a class.
063: * @throws AnalyzerException if class is incorrect.
064: */
065: public static void checkClass(final byte[] bytes)
066: throws AnalyzerException {
067: ClassReader cr = new ClassReader(bytes);
068: ClassNode cn = new ClassNode();
069: cr.accept(new CheckClassAdapter(cn), ClassReader.SKIP_DEBUG);
070: List methods = cn.methods;
071: for (int i = 0; i < methods.size(); ++i) {
072: MethodNode method = (MethodNode) methods.get(i);
073: if (method.instructions.size() > 0) {
074: Analyzer a = new Analyzer(new SimpleVerifier(Type
075: .getType("L" + cn.name + ";"), Type.getType("L"
076: + cn.super Name + ";"),
077: (cn.access & Opcodes.ACC_INTERFACE) != 0));
078: AnalyzerException throwE = null;
079: try {
080: a.analyze(cn.name, method);
081: continue;
082: } catch (AnalyzerException e) {
083: throwE = e;
084: }
085: final Frame[] frames = a.getFrames();
086:
087: if (throwE != null) {
088: System.out.println(method.name + method.desc);
089:
090: TraceMethodVisitor mv = new TraceMethodVisitor() {
091:
092: @Override
093: public void visitMaxs(final int maxStack,
094: final int maxLocals) {
095: for (int i = 0; i < text.size(); ++i) {
096: String s;
097: if (frames[i] == null) {
098: s = "null";
099: } else {
100: s = frames[i].toString();
101: }
102: while (s.length() < maxStack
103: + maxLocals + 1) {
104: s += " ";
105: }
106: System.out.print(Integer.toString(
107: i + START_INT).substring(1));
108: System.out.print(" " + s + " : "
109: + text.get(i));
110: }
111: System.out.println();
112: }
113: };
114: for (int j = 0; j < method.instructions.size(); ++j) {
115: method.instructions.get(j).accept(mv);
116: }
117: mv.visitMaxs(method.maxStack, method.maxLocals);
118: throw throwE;
119: }
120: }
121: }
122: }
123:
124: }
|