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 */ 017package org.apache.bcel.verifier; 018 019import org.apache.bcel.Repository; 020import org.apache.bcel.classfile.JavaClass; 021import org.apache.bcel.classfile.Utility; 022 023/** 024 * This class has a main method implementing a demonstration program of how to use the VerifierFactoryObserver. It 025 * transitively verifies all class files encountered; this may take up a lot of time and, more notably, memory. 026 */ 027public class TransitiveHull implements VerifierFactoryObserver { 028 029 /** 030 * This method implements a demonstration program of how to use the VerifierFactoryObserver. It transitively verifies 031 * all class files encountered; this may take up a lot of time and, more notably, memory. 032 */ 033 public static void main(final String[] args) { 034 if (args.length != 1) { 035 System.out.println("Need exactly one argument: The root class to verify."); 036 System.exit(1); 037 } 038 final int dotclasspos = args[0].lastIndexOf(JavaClass.EXTENSION); 039 if (dotclasspos != -1) { 040 args[0] = args[0].substring(0, dotclasspos); 041 } 042 args[0] = Utility.pathToPackage(args[0]); 043 final TransitiveHull th = new TransitiveHull(); 044 VerifierFactory.attach(th); 045 VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick. 046 VerifierFactory.detach(th); 047 } 048 049 /** Used for indentation. */ 050 private int indent; 051 052 /** Not publicly instantiable. */ 053 private TransitiveHull() { 054 } 055 056 /* Implementing VerifierFactoryObserver. */ 057 @Override 058 public void update(final String className) { 059 System.gc(); // avoid swapping if possible. 060 for (int i = 0; i < indent; i++) { 061 System.out.print(" "); 062 } 063 System.out.println(className); 064 indent += 1; 065 final Verifier v = VerifierFactory.getVerifier(className); 066 VerificationResult vr; 067 vr = v.doPass1(); 068 if (vr != VerificationResult.VR_OK) { 069 System.out.println("Pass 1:\n" + vr); 070 } 071 vr = v.doPass2(); 072 if (vr != VerificationResult.VR_OK) { 073 System.out.println("Pass 2:\n" + vr); 074 } 075 if (vr == VerificationResult.VR_OK) { 076 try { 077 final JavaClass jc = Repository.lookupClass(v.getClassName()); 078 for (int i = 0; i < jc.getMethods().length; i++) { 079 vr = v.doPass3a(i); 080 if (vr != VerificationResult.VR_OK) { 081 System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr); 082 } 083 vr = v.doPass3b(i); 084 if (vr != VerificationResult.VR_OK) { 085 System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['" + jc.getMethods()[i] + "']:\n" + vr); 086 } 087 } 088 } catch (final ClassNotFoundException e) { 089 System.err.println("Could not find class " + v.getClassName() + " in Repository"); 090 } 091 } 092 indent -= 1; 093 } 094}