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