TransitiveHull.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;

  18. import org.apache.bcel.Repository;
  19. import org.apache.bcel.classfile.JavaClass;
  20. import org.apache.bcel.classfile.Utility;

  21. /**
  22.  * This class has a main method implementing a demonstration program of how to use the VerifierFactoryObserver. It
  23.  * transitively verifies all class files encountered; this may take up a lot of time and, more notably, memory.
  24.  */
  25. public class TransitiveHull implements VerifierFactoryObserver {

  26.     /**
  27.      * This method implements a demonstration program of how to use the VerifierFactoryObserver. It transitively verifies
  28.      * all class files encountered; this may take up a lot of time and, more notably, memory.
  29.      */
  30.     public static void main(final String[] args) {
  31.         if (args.length != 1) {
  32.             System.out.println("Need exactly one argument: The root class to verify.");
  33.             System.exit(1);
  34.         }
  35.         final int dotclasspos = args[0].lastIndexOf(JavaClass.EXTENSION);
  36.         if (dotclasspos != -1) {
  37.             args[0] = args[0].substring(0, dotclasspos);
  38.         }
  39.         args[0] = Utility.pathToPackage(args[0]);
  40.         final TransitiveHull th = new TransitiveHull();
  41.         VerifierFactory.attach(th);
  42.         VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick.
  43.         VerifierFactory.detach(th);
  44.     }

  45.     /** Used for indentation. */
  46.     private int indent;

  47.     /** Not publicly instantiable. */
  48.     private TransitiveHull() {
  49.     }

  50.     /* Implementing VerifierFactoryObserver. */
  51.     @Override
  52.     public void update(final String className) {
  53.         System.gc(); // avoid swapping if possible.
  54.         for (int i = 0; i < indent; i++) {
  55.             System.out.print(" ");
  56.         }
  57.         System.out.println(className);
  58.         indent += 1;
  59.         final Verifier v = VerifierFactory.getVerifier(className);
  60.         VerificationResult vr;
  61.         vr = v.doPass1();
  62.         if (vr != VerificationResult.VR_OK) {
  63.             System.out.println("Pass 1:\n" + vr);
  64.         }
  65.         vr = v.doPass2();
  66.         if (vr != VerificationResult.VR_OK) {
  67.             System.out.println("Pass 2:\n" + vr);
  68.         }
  69.         if (vr == VerificationResult.VR_OK) {
  70.             try {
  71.                 final JavaClass jc = Repository.lookupClass(v.getClassName());
  72.                 for (int i = 0; i < jc.getMethods().length; i++) {
  73.                     vr = v.doPass3a(i);
  74.                     if (vr != VerificationResult.VR_OK) {
  75.                         System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr);
  76.                     }
  77.                     vr = v.doPass3b(i);
  78.                     if (vr != VerificationResult.VR_OK) {
  79.                         System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr);
  80.                     }
  81.                 }
  82.             } catch (final ClassNotFoundException e) {
  83.                 System.err.println("Could not find class " + v.getClassName() + " in Repository");
  84.             }
  85.         }
  86.         indent -= 1;
  87.     }
  88. }