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