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