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;
19 
20 import org.apache.bcel.Repository;
21 import org.apache.bcel.classfile.JavaClass;
22 
23 /**
24  * This class has a main method implementing a demonstration program
25  * of how to use the VerifierFactoryObserver. It transitively verifies
26  * all class files encountered; this may take up a lot of time and,
27  * more notably, memory.
28  *
29  * @version $Id$
30  */
31 public class TransitiveHull implements VerifierFactoryObserver {
32 
33     /** Used for indentation. */
34     private int indent = 0;
35 
36 
37     /** Not publicly instantiable. */
TransitiveHull()38     private TransitiveHull() {
39     }
40 
41 
42     /* Implementing VerifierFactoryObserver. */
43     @Override
update( final String classname )44     public void update( final String classname ) {
45         System.gc(); // avoid swapping if possible.
46         for (int i = 0; i < indent; i++) {
47             System.out.print(" ");
48         }
49         System.out.println(classname);
50         indent += 1;
51         final Verifier v = VerifierFactory.getVerifier(classname);
52         VerificationResult vr;
53         vr = v.doPass1();
54         if (vr != VerificationResult.VR_OK) {
55             System.out.println("Pass 1:\n" + vr);
56         }
57         vr = v.doPass2();
58         if (vr != VerificationResult.VR_OK) {
59             System.out.println("Pass 2:\n" + vr);
60         }
61         if (vr == VerificationResult.VR_OK) {
62             try {
63                 final JavaClass jc = Repository.lookupClass(v.getClassName());
64                 for (int i = 0; i < jc.getMethods().length; i++) {
65                     vr = v.doPass3a(i);
66                     if (vr != VerificationResult.VR_OK) {
67                         System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['"
68                                 + jc.getMethods()[i] + "']:\n" + vr);
69                     }
70                     vr = v.doPass3b(i);
71                     if (vr != VerificationResult.VR_OK) {
72                         System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['"
73                                 + jc.getMethods()[i] + "']:\n" + vr);
74                     }
75                 }
76             } catch (final ClassNotFoundException e) {
77                 System.err.println("Could not find class " + v.getClassName() + " in Repository");
78             }
79         }
80         indent -= 1;
81     }
82 
83 
84     /**
85      * This method implements a demonstration program
86      * of how to use the VerifierFactoryObserver. It transitively verifies
87      * all class files encountered; this may take up a lot of time and,
88      * more notably, memory.
89      */
main( final String[] args )90     public static void main( final String[] args ) {
91         if (args.length != 1) {
92             System.out.println("Need exactly one argument: The root class to verify.");
93             System.exit(1);
94         }
95         final int dotclasspos = args[0].lastIndexOf(".class");
96         if (dotclasspos != -1) {
97             args[0] = args[0].substring(0, dotclasspos);
98         }
99         args[0] = args[0].replace('/', '.');
100         final TransitiveHull th = new TransitiveHull();
101         VerifierFactory.attach(th);
102         VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick.
103         VerifierFactory.detach(th);
104     }
105 }
106