View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.bcel.verifier;
20  
21  import org.apache.bcel.Repository;
22  import org.apache.bcel.classfile.JavaClass;
23  import org.apache.bcel.classfile.Utility;
24  
25  /**
26   * This class has a main method implementing a demonstration program of how to use the VerifierFactoryObserver. It
27   * transitively verifies all class files encountered; this may take up a lot of time and, more notably, memory.
28   */
29  public class TransitiveHull implements VerifierFactoryObserver {
30  
31      /**
32       * This method implements a demonstration program of how to use the VerifierFactoryObserver. It transitively verifies
33       * all class files encountered; this may take up a lot of time and, more notably, memory.
34       */
35      public static void main(final String[] args) {
36          if (args.length != 1) {
37              System.out.println("Need exactly one argument: The root class to verify.");
38              System.exit(1);
39          }
40          final int dotclasspos = args[0].lastIndexOf(JavaClass.EXTENSION);
41          if (dotclasspos != -1) {
42              args[0] = args[0].substring(0, dotclasspos);
43          }
44          args[0] = Utility.pathToPackage(args[0]);
45          final TransitiveHull th = new TransitiveHull();
46          VerifierFactory.attach(th);
47          VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick.
48          VerifierFactory.detach(th);
49      }
50  
51      /** Used for indentation. */
52      private int indent;
53  
54      /** Not publicly instantiable. */
55      private TransitiveHull() {
56      }
57  
58      /* Implementing VerifierFactoryObserver. */
59      @Override
60      public void update(final String className) {
61          System.gc(); // avoid swapping if possible.
62          for (int i = 0; i < indent; i++) {
63              System.out.print(" ");
64          }
65          System.out.println(className);
66          indent += 1;
67          final Verifier v = VerifierFactory.getVerifier(className);
68          VerificationResult vr;
69          vr = v.doPass1();
70          if (vr != VerificationResult.VR_OK) {
71              System.out.println("Pass 1:\n" + vr);
72          }
73          vr = v.doPass2();
74          if (vr != VerificationResult.VR_OK) {
75              System.out.println("Pass 2:\n" + vr);
76          }
77          if (vr == VerificationResult.VR_OK) {
78              try {
79                  final JavaClass jc = Repository.lookupClass(v.getClassName());
80                  for (int i = 0; i < jc.getMethods().length; i++) {
81                      vr = v.doPass3a(i);
82                      if (vr != VerificationResult.VR_OK) {
83                          System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr);
84                      }
85                      vr = v.doPass3b(i);
86                      if (vr != VerificationResult.VR_OK) {
87                          System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr);
88                      }
89                  }
90              } catch (final ClassNotFoundException e) {
91                  System.err.println("Could not find class " + v.getClassName() + " in Repository");
92              }
93          }
94          indent -= 1;
95      }
96  }