001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.verifier; 019 020import org.apache.bcel.Repository; 021import org.apache.bcel.classfile.JavaClass; 022import org.apache.bcel.classfile.Utility; 023 024/** 025 * This class has a main method implementing a demonstration program of how to use the VerifierFactoryObserver. It 026 * transitively verifies all class files encountered; this may take up a lot of time and, more notably, memory. 027 * 028 */ 029public class TransitiveHull implements VerifierFactoryObserver { 030 031 /** 032 * This method implements a demonstration program of how to use the VerifierFactoryObserver. It transitively verifies 033 * all class files encountered; this may take up a lot of time and, more notably, memory. 034 */ 035 public static void main(final String[] args) { 036 if (args.length != 1) { 037 System.out.println("Need exactly one argument: The root class to verify."); 038 System.exit(1); 039 } 040 final int dotclasspos = args[0].lastIndexOf(".class"); 041 if (dotclasspos != -1) { 042 args[0] = args[0].substring(0, dotclasspos); 043 } 044 args[0] = Utility.pathToPackage(args[0]); 045 final TransitiveHull th = new TransitiveHull(); 046 VerifierFactory.attach(th); 047 VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick. 048 VerifierFactory.detach(th); 049 } 050 051 /** Used for indentation. */ 052 private int indent; 053 054 /** Not publicly instantiable. */ 055 private TransitiveHull() { 056 } 057 058 /* Implementing VerifierFactoryObserver. */ 059 @Override 060 public void update(final String classname) { 061 System.gc(); // avoid swapping if possible. 062 for (int i = 0; i < indent; i++) { 063 System.out.print(" "); 064 } 065 System.out.println(classname); 066 indent += 1; 067 final Verifier v = VerifierFactory.getVerifier(classname); 068 VerificationResult vr; 069 vr = v.doPass1(); 070 if (vr != VerificationResult.VR_OK) { 071 System.out.println("Pass 1:\n" + vr); 072 } 073 vr = v.doPass2(); 074 if (vr != VerificationResult.VR_OK) { 075 System.out.println("Pass 2:\n" + vr); 076 } 077 if (vr == VerificationResult.VR_OK) { 078 try { 079 final JavaClass jc = Repository.lookupClass(v.getClassName()); 080 for (int i = 0; i < jc.getMethods().length; i++) { 081 vr = v.doPass3a(i); 082 if (vr != VerificationResult.VR_OK) { 083 System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr); 084 } 085 vr = v.doPass3b(i); 086 if (vr != VerificationResult.VR_OK) { 087 System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr); 088 } 089 } 090 } catch (final ClassNotFoundException e) { 091 System.err.println("Could not find class " + v.getClassName() + " in Repository"); 092 } 093 } 094 indent -= 1; 095 } 096}