KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > transformer > ReferenceVerifyingVisitor


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

32 package net.sf.retrotranslator.transformer;
33
34 import java.util.*;
35 import net.sf.retrotranslator.runtime.asm.*;
36 import net.sf.retrotranslator.runtime.impl.*;
37
38 /**
39  * @author Taras Puchko
40  */

41 class ReferenceVerifyingVisitor extends GenericClassVisitor {
42
43     private ClassReaderFactory factory;
44     private SystemLogger logger;
45     private Set<String JavaDoc> warnings;
46
47     public ReferenceVerifyingVisitor(ClassReaderFactory factory, SystemLogger logger) {
48         super(new EmptyVisitor());
49         this.factory = factory;
50         this.logger = logger;
51     }
52
53     public int verify(byte[] bytes) {
54         warnings = new LinkedHashSet<String JavaDoc>();
55         new ClassReader(bytes).accept(this, true);
56         return warnings.size();
57     }
58
59     protected String JavaDoc typeName(String JavaDoc s) {
60         if (s == null) return null;
61         try {
62             factory.getClassReader(s);
63         } catch (ClassNotFoundException JavaDoc e) {
64             println("Class not found: " + getClassInfo(e.getMessage()));
65         }
66         return s;
67     }
68
69     protected void visitFieldInstruction(MethodVisitor visitor, int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
70         super.visitFieldInstruction(visitor, opcode, owner, name, desc);
71         boolean stat = (opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC);
72         try {
73             int found = new MemberFinder(factory, false, stat, name, desc).findIn(owner, null);
74             if (found == 0) {
75                 println(getFieldInfo(owner, stat, name, desc, "not found"));
76             } else if (found > 1) {
77                 println(getFieldInfo(owner, stat, name, desc, "duplicated"));
78             }
79         } catch (ClassNotFoundException JavaDoc e) {
80             cannotVerify(getFieldInfo(owner, stat, name, desc, "not verified"), e);
81         }
82     }
83
84     protected void visitMethodInstruction(MethodVisitor visitor, int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
85         super.visitMethodInstruction(visitor, opcode, owner, name, desc);
86         if (owner.startsWith("[")) return;
87         boolean stat = (opcode == Opcodes.INVOKESTATIC);
88         try {
89             int found = new MemberFinder(factory, true, stat, name, desc).findIn(owner, null);
90             if (found == 0) {
91                 println(getMethodInfo(owner, stat, name, desc, "not found"));
92             } else if (found > 1) {
93                 println(getMethodInfo(owner, stat, name, desc, "duplicated"));
94             }
95         } catch (ClassNotFoundException JavaDoc e) {
96             cannotVerify(getMethodInfo(owner, stat, name, desc, "not verified"), e);
97         }
98     }
99
100     private void cannotVerify(String JavaDoc text, ClassNotFoundException JavaDoc e) {
101         println(text + " (class not found: " + getClassInfo(e.getMessage()) + ")");
102     }
103
104     private void println(String JavaDoc text) {
105         if (!warnings.contains(text)) {
106             warnings.add(text);
107             logger.logForFile(Level.WARNING, text);
108         }
109     }
110
111     private static String JavaDoc getClassInfo(String JavaDoc name) {
112         return name.replace('/', '.');
113     }
114
115     private static String JavaDoc getFieldInfo(String JavaDoc owner, boolean stat, String JavaDoc name, String JavaDoc desc, String JavaDoc message) {
116         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("Field ").append(message).append(": ");
117         if (stat) buffer.append("static ");
118         buffer.append(Type.getType(desc).getClassName()).append(' ');
119         buffer.append(getClassInfo(owner)).append('.').append(name);
120         return buffer.toString();
121     }
122
123     private static String JavaDoc getMethodInfo(String JavaDoc owner, boolean stat, String JavaDoc name, String JavaDoc desc, String JavaDoc message) {
124         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
125         if (name.equals(RuntimeTools.CONSTRUCTOR_NAME)) {
126             buffer.append("Constructor ").append(message).append(": ");
127             buffer.append(getClassInfo(owner));
128         } else {
129             buffer.append("Method ").append(message).append(": ");
130             if (stat) buffer.append("static ");
131             buffer.append(Type.getReturnType(desc).getClassName());
132             buffer.append(' ').append(getClassInfo(owner)).append('.').append(name);
133         }
134         buffer.append('(');
135         boolean first = true;
136         for (Type type : Type.getArgumentTypes(desc)) {
137             buffer.append(first ? "" : ",").append(type.getClassName());
138             first = false;
139         }
140         return buffer.append(')').toString();
141     }
142 }
143
Popular Tags