View Javadoc

1   /*
2    * Copyright  2000-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License"); 
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License. 
15   *
16   */ 
17  package org.apache.bcel.verifier.statics;
18  
19  
20  import org.apache.bcel.classfile.Code;
21  import org.apache.bcel.classfile.CodeException;
22  import org.apache.bcel.classfile.ConstantClass;
23  import org.apache.bcel.classfile.ConstantDouble;
24  import org.apache.bcel.classfile.ConstantFieldref;
25  import org.apache.bcel.classfile.ConstantFloat;
26  import org.apache.bcel.classfile.ConstantInteger;
27  import org.apache.bcel.classfile.ConstantInterfaceMethodref;
28  import org.apache.bcel.classfile.ConstantLong;
29  import org.apache.bcel.classfile.ConstantMethodref;
30  import org.apache.bcel.classfile.ConstantNameAndType;
31  import org.apache.bcel.classfile.ConstantPool;
32  import org.apache.bcel.classfile.ConstantString;
33  import org.apache.bcel.classfile.ConstantUtf8;
34  import org.apache.bcel.classfile.ConstantValue;
35  import org.apache.bcel.classfile.Deprecated;
36  import org.apache.bcel.classfile.ExceptionTable;
37  import org.apache.bcel.classfile.Field;
38  import org.apache.bcel.classfile.InnerClass;
39  import org.apache.bcel.classfile.InnerClasses;
40  import org.apache.bcel.classfile.JavaClass;
41  import org.apache.bcel.classfile.LineNumber;
42  import org.apache.bcel.classfile.LineNumberTable;
43  import org.apache.bcel.classfile.LocalVariable;
44  import org.apache.bcel.classfile.LocalVariableTable;
45  import org.apache.bcel.classfile.Method;
46  import org.apache.bcel.classfile.Node;
47  import org.apache.bcel.classfile.Signature;
48  import org.apache.bcel.classfile.SourceFile;
49  import org.apache.bcel.classfile.StackMap;
50  import org.apache.bcel.classfile.Synthetic;
51  import org.apache.bcel.classfile.Unknown;
52  import org.apache.bcel.classfile.Visitor;
53  import org.apache.bcel.verifier.exc.AssertionViolatedException;
54  
55  /***
56   * BCEL's Node classes (those from the classfile API that <B>accept()</B> Visitor
57   * instances) have <B>toString()</B> methods that were not designed to be robust,
58   * this gap is closed by this class.
59   * When performing class file verification, it may be useful to output which
60   * entity (e.g. a <B>Code</B> instance) is not satisfying the verifier's
61   * constraints, but in this case it could be possible for the <B>toString()</B>
62   * method to throw a RuntimeException.
63   * A (new StringRepresentation(Node n)).toString() never throws any exception.
64   * Note that this class also serves as a placeholder for more sophisticated message
65   * handling in future versions of JustIce.
66   *
67   * @version $Id: StringRepresentation.java 386056 2006-03-15 11:31:56Z tcurdt $
68   * @author Enver Haase
69   */
70  public class StringRepresentation extends org.apache.bcel.classfile.EmptyVisitor implements Visitor {
71      /*** The string representation, created by a visitXXX() method, output by toString(). */
72      private String tostring;
73      /*** The node we ask for its string representation. Not really needed; only for debug output. */
74      private Node n;
75  
76      /***
77       * Creates a new StringRepresentation object which is the representation of n.
78       *
79       * @see #toString()
80       */
81      public StringRepresentation(Node n) {
82          this.n = n;
83          n.accept(this); // assign a string representation to field 'tostring' if we know n's class.
84      }
85  
86      /***
87       * Returns the String representation.
88       */
89      public String toString() {
90  // The run-time check below is needed because we don't want to omit inheritance
91  // of "EmptyVisitor" and provide a thousand empty methods.
92  // However, in terms of performance this would be a better idea.
93  // If some new "Node" is defined in BCEL (such as some concrete "Attribute"), we
94  // want to know that this class has also to be adapted.
95          if (tostring == null) {
96              throw new AssertionViolatedException("Please adapt '" + getClass() + "' to deal with objects of class '" + n.getClass() + "'.");
97          }
98          return tostring;
99      }
100 
101     /***
102      * Returns the String representation of the Node object obj;
103      * this is obj.toString() if it does not throw any RuntimeException,
104      * or else it is a string derived only from obj's class name.
105      */
106     private String toString(Node obj) {
107         String ret;
108         try {
109             ret = obj.toString();
110         }
111         catch (RuntimeException e) { // including ClassFormatException, trying to convert the "signature" of a ReturnaddressType LocalVariable (shouldn't occur, but people do crazy things)
112             String s = obj.getClass().getName();
113             s = s.substring(s.lastIndexOf(".") + 1);
114             ret = "<<" + s + ">>";
115         }
116         return ret;
117     }
118 
119     ////////////////////////////////
120     // Visitor methods start here //
121     ////////////////////////////////
122     // We don't of course need to call some default implementation:
123     // e.g. we could also simply output "Code" instead of a possibly
124     // lengthy Code attribute's toString().
125     public void visitCode(Code obj) {
126         //tostring = toString(obj);
127         tostring = "<CODE>"; // We don't need real code outputs.
128     }
129 
130     public void visitCodeException(CodeException obj) {
131         tostring = toString(obj);
132     }
133 
134     public void visitConstantClass(ConstantClass obj) {
135         tostring = toString(obj);
136     }
137 
138     public void visitConstantDouble(ConstantDouble obj) {
139         tostring = toString(obj);
140     }
141 
142     public void visitConstantFieldref(ConstantFieldref obj) {
143         tostring = toString(obj);
144     }
145 
146     public void visitConstantFloat(ConstantFloat obj) {
147         tostring = toString(obj);
148     }
149 
150     public void visitConstantInteger(ConstantInteger obj) {
151         tostring = toString(obj);
152     }
153 
154     public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) {
155         tostring = toString(obj);
156     }
157 
158     public void visitConstantLong(ConstantLong obj) {
159         tostring = toString(obj);
160     }
161 
162     public void visitConstantMethodref(ConstantMethodref obj) {
163         tostring = toString(obj);
164     }
165 
166     public void visitConstantNameAndType(ConstantNameAndType obj) {
167         tostring = toString(obj);
168     }
169 
170     public void visitConstantPool(ConstantPool obj) {
171         tostring = toString(obj);
172     }
173 
174     public void visitConstantString(ConstantString obj) {
175         tostring = toString(obj);
176     }
177 
178     public void visitConstantUtf8(ConstantUtf8 obj) {
179         tostring = toString(obj);
180     }
181 
182     public void visitConstantValue(ConstantValue obj) {
183         tostring = toString(obj);
184     }
185 
186     public void visitDeprecated(Deprecated obj) {
187         tostring = toString(obj);
188     }
189 
190     public void visitExceptionTable(ExceptionTable obj) {
191         tostring = toString(obj);
192     }
193 
194     public void visitField(Field obj) {
195         tostring = toString(obj);
196     }
197 
198     public void visitInnerClass(InnerClass obj) {
199         tostring = toString(obj);
200     }
201 
202     public void visitInnerClasses(InnerClasses obj) {
203         tostring = toString(obj);
204     }
205 
206     public void visitJavaClass(JavaClass obj) {
207         tostring = toString(obj);
208     }
209 
210     public void visitLineNumber(LineNumber obj) {
211         tostring = toString(obj);
212     }
213 
214     public void visitLineNumberTable(LineNumberTable obj) {
215         tostring = "<LineNumberTable: " + toString(obj) + ">";
216     }
217 
218     public void visitLocalVariable(LocalVariable obj) {
219         tostring = toString(obj);
220     }
221 
222     public void visitLocalVariableTable(LocalVariableTable obj) {
223         tostring = "<LocalVariableTable: " + toString(obj) + ">";
224     }
225 
226     public void visitMethod(Method obj) {
227         tostring = toString(obj);
228     }
229 
230     public void visitSignature(Signature obj) {
231         tostring = toString(obj);
232     }
233 
234     public void visitSourceFile(SourceFile obj) {
235         tostring = toString(obj);
236     }
237 
238     public void visitStackMap(StackMap obj) {
239         tostring = toString(obj);
240     }
241 
242     public void visitSynthetic(Synthetic obj) {
243         tostring = toString(obj);
244     }
245 
246     public void visitUnknown(Unknown obj) {
247         tostring = toString(obj);
248     }
249 }