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 } 250