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