StringRepresentation.java

  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. package org.apache.bcel.verifier.statics;

  18. import org.apache.bcel.classfile.AnnotationDefault;
  19. import org.apache.bcel.classfile.AnnotationEntry;
  20. import org.apache.bcel.classfile.Annotations;
  21. import org.apache.bcel.classfile.BootstrapMethods;
  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.ConstantDynamic;
  27. import org.apache.bcel.classfile.ConstantFieldref;
  28. import org.apache.bcel.classfile.ConstantFloat;
  29. import org.apache.bcel.classfile.ConstantInteger;
  30. import org.apache.bcel.classfile.ConstantInterfaceMethodref;
  31. import org.apache.bcel.classfile.ConstantInvokeDynamic;
  32. import org.apache.bcel.classfile.ConstantLong;
  33. import org.apache.bcel.classfile.ConstantMethodHandle;
  34. import org.apache.bcel.classfile.ConstantMethodType;
  35. import org.apache.bcel.classfile.ConstantMethodref;
  36. import org.apache.bcel.classfile.ConstantModule;
  37. import org.apache.bcel.classfile.ConstantNameAndType;
  38. import org.apache.bcel.classfile.ConstantPackage;
  39. import org.apache.bcel.classfile.ConstantPool;
  40. import org.apache.bcel.classfile.ConstantString;
  41. import org.apache.bcel.classfile.ConstantUtf8;
  42. import org.apache.bcel.classfile.ConstantValue;
  43. import org.apache.bcel.classfile.Deprecated;
  44. import org.apache.bcel.classfile.EnclosingMethod;
  45. import org.apache.bcel.classfile.ExceptionTable;
  46. import org.apache.bcel.classfile.Field;
  47. import org.apache.bcel.classfile.InnerClass;
  48. import org.apache.bcel.classfile.InnerClasses;
  49. import org.apache.bcel.classfile.JavaClass;
  50. import org.apache.bcel.classfile.LineNumber;
  51. import org.apache.bcel.classfile.LineNumberTable;
  52. import org.apache.bcel.classfile.LocalVariable;
  53. import org.apache.bcel.classfile.LocalVariableTable;
  54. import org.apache.bcel.classfile.LocalVariableTypeTable;
  55. import org.apache.bcel.classfile.Method;
  56. import org.apache.bcel.classfile.MethodParameters;
  57. import org.apache.bcel.classfile.NestMembers;
  58. import org.apache.bcel.classfile.Node;
  59. import org.apache.bcel.classfile.ParameterAnnotationEntry;
  60. import org.apache.bcel.classfile.ParameterAnnotations;
  61. import org.apache.bcel.classfile.Record;
  62. import org.apache.bcel.classfile.RecordComponentInfo;
  63. import org.apache.bcel.classfile.Signature;
  64. import org.apache.bcel.classfile.SourceFile;
  65. import org.apache.bcel.classfile.StackMap;
  66. import org.apache.bcel.classfile.StackMapEntry;
  67. import org.apache.bcel.classfile.Synthetic;
  68. import org.apache.bcel.classfile.Unknown;
  69. import org.apache.bcel.verifier.exc.AssertionViolatedException;

  70. /**
  71.  * BCEL's Node classes (those from the classfile API that <B>accept()</B> Visitor instances) have <B>toString()</B>
  72.  * methods that were not designed to be robust, this gap is closed by this class. When performing class file
  73.  * verification, it may be useful to output which entity (e.g. a <B>Code</B> instance) is not satisfying the verifier's
  74.  * constraints, but in this case it could be possible for the <B>toString()</B> method to throw a RuntimeException. A
  75.  * (new StringRepresentation(Node n)).toString() never throws any exception. Note that this class also serves as a
  76.  * placeholder for more sophisticated message handling in future versions of JustIce.
  77.  */
  78. public class StringRepresentation extends org.apache.bcel.classfile.EmptyVisitor {
  79.     /** The string representation, created by a visitXXX() method, output by toString(). */
  80.     private String tostring;
  81.     /** The node we ask for its string representation. Not really needed; only for debug output. */
  82.     private final Node n;

  83.     /**
  84.      * Creates a new StringRepresentation object which is the representation of n.
  85.      *
  86.      * @param n The node to represent.
  87.      * @see #toString()
  88.      */
  89.     public StringRepresentation(final Node n) {
  90.         this.n = n;
  91.         n.accept(this); // assign a string representation to field 'tostring' if we know n's class.
  92.     }

  93.     /**
  94.      * Returns the String representation.
  95.      */
  96.     @Override
  97.     public String toString() {
  98. // The run-time check below is needed because we don't want to omit inheritance
  99. // of "EmptyVisitor" and provide a thousand empty methods.
  100. // However, in terms of performance this would be a better idea.
  101. // If some new "Node" is defined in BCEL (such as some concrete "Attribute"), we
  102. // want to know that this class has also to be adapted.
  103.         if (tostring == null) {
  104.             throw new AssertionViolatedException("Please adapt '" + getClass() + "' to deal with objects of class '" + n.getClass() + "'.");
  105.         }
  106.         return tostring;
  107.     }

  108.     /**
  109.      * Returns the String representation of the Node object obj; this is obj.toString() if it does not throw any
  110.      * RuntimeException, or else it is a string derived only from obj's class name.
  111.      */
  112.     private String toString(final Node obj) {
  113.         String ret;
  114.         try {
  115.             ret = obj.toString();
  116.         }

  117.         catch (final RuntimeException e) {
  118.             // including ClassFormatException, trying to convert the "signature" of a ReturnaddressType LocalVariable
  119.             // (shouldn't occur, but people do crazy things)
  120.             String s = obj.getClass().getName();
  121.             s = s.substring(s.lastIndexOf(".") + 1);
  122.             ret = "<<" + s + ">>";
  123.         }
  124.         return ret;
  125.     }

  126.     /**
  127.      * @since 6.0
  128.      */
  129.     @Override
  130.     public void visitAnnotation(final Annotations obj) {
  131.         // this is invoked whenever an annotation is found
  132.         // when verifier is passed over a class
  133.         tostring = toString(obj);
  134.     }

  135.     /**
  136.      * @since 6.0
  137.      */
  138.     @Override
  139.     public void visitAnnotationDefault(final AnnotationDefault obj) {
  140.         tostring = toString(obj);
  141.     }

  142.     /**
  143.      * @since 6.0
  144.      */
  145.     @Override
  146.     public void visitAnnotationEntry(final AnnotationEntry obj) {
  147.         tostring = toString(obj);
  148.     }

  149.     /**
  150.      * @since 6.0
  151.      */
  152.     @Override
  153.     public void visitBootstrapMethods(final BootstrapMethods obj) {
  154.         tostring = toString(obj);
  155.     }

  156.     ////////////////////////////////
  157.     // Visitor methods start here //
  158.     ////////////////////////////////
  159.     // We don't of course need to call some default implementation:
  160.     // e.g. we could also simply output "Code" instead of a possibly
  161.     // lengthy Code attribute's toString().
  162.     @Override
  163.     public void visitCode(final Code obj) {
  164.         // tostring = toString(obj);
  165.         tostring = "<CODE>"; // We don't need real code outputs.
  166.     }

  167.     @Override
  168.     public void visitCodeException(final CodeException obj) {
  169.         tostring = toString(obj);
  170.     }

  171.     @Override
  172.     public void visitConstantClass(final ConstantClass obj) {
  173.         tostring = toString(obj);
  174.     }

  175.     @Override
  176.     public void visitConstantDouble(final ConstantDouble obj) {
  177.         tostring = toString(obj);
  178.     }

  179.     /**
  180.      * @since 6.6.0
  181.      */
  182.     @Override
  183.     public void visitConstantDynamic(final ConstantDynamic obj) {
  184.         tostring = toString(obj);
  185.     }

  186.     @Override
  187.     public void visitConstantFieldref(final ConstantFieldref obj) {
  188.         tostring = toString(obj);
  189.     }

  190.     @Override
  191.     public void visitConstantFloat(final ConstantFloat obj) {
  192.         tostring = toString(obj);
  193.     }

  194.     @Override
  195.     public void visitConstantInteger(final ConstantInteger obj) {
  196.         tostring = toString(obj);
  197.     }

  198.     @Override
  199.     public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref obj) {
  200.         tostring = toString(obj);
  201.     }

  202.     /**
  203.      * @since 6.0
  204.      */
  205.     @Override
  206.     public void visitConstantInvokeDynamic(final ConstantInvokeDynamic obj) {
  207.         tostring = toString(obj);
  208.     }

  209.     @Override
  210.     public void visitConstantLong(final ConstantLong obj) {
  211.         tostring = toString(obj);
  212.     }

  213.     /**
  214.      * @since 6.0
  215.      */
  216.     @Override
  217.     public void visitConstantMethodHandle(final ConstantMethodHandle obj) {
  218.         tostring = toString(obj);
  219.     }

  220.     @Override
  221.     public void visitConstantMethodref(final ConstantMethodref obj) {
  222.         tostring = toString(obj);
  223.     }

  224.     /**
  225.      * @since 6.0
  226.      */
  227.     @Override
  228.     public void visitConstantMethodType(final ConstantMethodType obj) {
  229.         tostring = toString(obj);
  230.     }

  231.     /**
  232.      * @since 6.6.0
  233.      */
  234.     @Override
  235.     public void visitConstantModule(final ConstantModule obj) {
  236.         tostring = toString(obj);
  237.     }

  238.     @Override
  239.     public void visitConstantNameAndType(final ConstantNameAndType obj) {
  240.         tostring = toString(obj);
  241.     }

  242.     /**
  243.      * @since 6.6.0
  244.      */
  245.     @Override
  246.     public void visitConstantPackage(final ConstantPackage obj) {
  247.         tostring = toString(obj);
  248.     }

  249.     @Override
  250.     public void visitConstantPool(final ConstantPool obj) {
  251.         tostring = toString(obj);
  252.     }

  253.     @Override
  254.     public void visitConstantString(final ConstantString obj) {
  255.         tostring = toString(obj);
  256.     }

  257.     @Override
  258.     public void visitConstantUtf8(final ConstantUtf8 obj) {
  259.         tostring = toString(obj);
  260.     }

  261.     @Override
  262.     public void visitConstantValue(final ConstantValue obj) {
  263.         tostring = toString(obj);
  264.     }

  265.     @Override
  266.     public void visitDeprecated(final Deprecated obj) {
  267.         tostring = toString(obj);
  268.     }

  269.     /**
  270.      * @since 6.0
  271.      */
  272.     @Override
  273.     public void visitEnclosingMethod(final EnclosingMethod obj) {
  274.         tostring = toString(obj);
  275.     }

  276.     @Override
  277.     public void visitExceptionTable(final ExceptionTable obj) {
  278.         tostring = toString(obj);
  279.     }

  280.     @Override
  281.     public void visitField(final Field obj) {
  282.         tostring = toString(obj);
  283.     }

  284.     @Override
  285.     public void visitInnerClass(final InnerClass obj) {
  286.         tostring = toString(obj);
  287.     }

  288.     @Override
  289.     public void visitInnerClasses(final InnerClasses obj) {
  290.         tostring = toString(obj);
  291.     }

  292.     @Override
  293.     public void visitJavaClass(final JavaClass obj) {
  294.         tostring = toString(obj);
  295.     }

  296.     @Override
  297.     public void visitLineNumber(final LineNumber obj) {
  298.         tostring = toString(obj);
  299.     }

  300.     @Override
  301.     public void visitLineNumberTable(final LineNumberTable obj) {
  302.         tostring = "<LineNumberTable: " + toString(obj) + ">";
  303.     }

  304.     @Override
  305.     public void visitLocalVariable(final LocalVariable obj) {
  306.         tostring = toString(obj);
  307.     }

  308.     @Override
  309.     public void visitLocalVariableTable(final LocalVariableTable obj) {
  310.         tostring = "<LocalVariableTable: " + toString(obj) + ">";
  311.     }

  312.     /**
  313.      * @since 6.0
  314.      */
  315.     @Override
  316.     public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) {
  317.         // this is invoked whenever a local variable type is found
  318.         // when verifier is passed over a class
  319.         tostring = toString(obj);
  320.     }

  321.     @Override
  322.     public void visitMethod(final Method obj) {
  323.         tostring = toString(obj);
  324.     }

  325.     /**
  326.      * @since 6.0
  327.      */
  328.     @Override
  329.     public void visitMethodParameters(final MethodParameters obj) {
  330.         tostring = toString(obj);
  331.     }

  332.     /**
  333.      * @since 6.4.0
  334.      */
  335.     @Override
  336.     public void visitNestMembers(final NestMembers obj) {
  337.         tostring = toString(obj);
  338.     }

  339.     /**
  340.      * @since 6.0
  341.      */
  342.     @Override
  343.     public void visitParameterAnnotation(final ParameterAnnotations obj) {
  344.         tostring = toString(obj);
  345.     }

  346.     /**
  347.      * @since 6.0
  348.      */
  349.     @Override
  350.     public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) {
  351.         tostring = toString(obj);
  352.     }

  353.     @Override
  354.     public void visitRecord(final Record obj) {
  355.         tostring = toString(obj);
  356.     }

  357.     @Override
  358.     public void visitRecordComponent(final RecordComponentInfo obj) {
  359.         tostring = toString(obj);
  360.     }

  361.     @Override
  362.     public void visitSignature(final Signature obj) {
  363.         tostring = toString(obj);
  364.     }

  365.     @Override
  366.     public void visitSourceFile(final SourceFile obj) {
  367.         tostring = toString(obj);
  368.     }

  369.     @Override
  370.     public void visitStackMap(final StackMap obj) {
  371.         tostring = toString(obj);
  372.     }

  373.     /**
  374.      * @since 6.0
  375.      */
  376.     @Override
  377.     public void visitStackMapEntry(final StackMapEntry obj) {
  378.         tostring = toString(obj);
  379.     }

  380.     @Override
  381.     public void visitSynthetic(final Synthetic obj) {
  382.         tostring = toString(obj);
  383.     }

  384.     @Override
  385.     public void visitUnknown(final Unknown obj) {
  386.         tostring = toString(obj);
  387.     }

  388. }