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 java.util.ArrayList; 021import java.util.List; 022 023/** 024 * A PassVerifier actually verifies a class file; it is instantiated 025 * by a Verifier. 026 * The verification should conform with a certain pass as described 027 * in The Java Virtual Machine Specification, 2nd edition. 028 * This book describes four passes. Pass one means loading the 029 * class and verifying a few static constraints. Pass two actually 030 * verifies some other constraints that could enforce loading in 031 * referenced class files. Pass three is the first pass that actually 032 * checks constraints in the code array of a method in the class file; 033 * it has two parts with the first verifying static constraints and 034 * the second part verifying structural constraints (where a data flow 035 * analysis is used for). The fourth pass, finally, performs checks 036 * that can only be done at run-time. 037 * JustIce does not have a run-time pass, but certain constraints that 038 * are usually delayed until run-time for performance reasons are also 039 * checked during the second part of pass three. 040 * PassVerifier instances perform caching. 041 * That means, if you really want a new verification run of a certain 042 * pass you must use a new instance of a given PassVerifier. 043 * 044 * @version $Id: PassVerifier.java 1747278 2016-06-07 17:28:43Z britter $ 045 * @see Verifier 046 * @see #verify() 047 */ 048public abstract class PassVerifier { 049 050 /** The (warning) messages. */ 051 private final List<String> messages = new ArrayList<>(); 052 /** The VerificationResult cache. */ 053 private VerificationResult verificationResult = null; 054 055 056 /** 057 * This method runs a verification pass conforming to the 058 * Java Virtual Machine Specification, 2nd edition, on a 059 * class file. 060 * PassVerifier instances perform caching; 061 * i.e. if the verify() method once determined a VerificationResult, 062 * then this result may be returned after every invocation of this 063 * method instead of running the verification pass anew; likewise with 064 * the result of getMessages(). 065 * 066 * @see #getMessages() 067 * @see #addMessage(String) 068 */ 069 public VerificationResult verify() { 070 if (verificationResult == null) { 071 verificationResult = do_verify(); 072 } 073 return verificationResult; 074 } 075 076 077 /** Does the real verification work, uncached. */ 078 public abstract VerificationResult do_verify(); 079 080 081 /** 082 * This method adds a (warning) message to the message pool of this 083 * PassVerifier. This method is normally only internally used by 084 * BCEL's class file verifier "JustIce" and should not be used from 085 * the outside. 086 * 087 * @see #getMessages() 088 */ 089 public void addMessage( final String message ) { 090 messages.add(message); 091 } 092 093 094 /** 095 * Returns the (warning) messages that this PassVerifier accumulated 096 * during its do_verify()ing work. 097 * 098 * @see #addMessage(String) 099 * @see #do_verify() 100 */ 101 public String[] getMessages() { 102 verify(); // create messages if not already done (cached!) 103 return messages.toArray(new String[messages.size()]); 104 } 105}