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 * @see Verifier 045 * @see #verify() 046 */ 047public abstract class PassVerifier { 048 049 /** The (warning) messages. */ 050 private final List<String> messages = new ArrayList<>(); 051 /** The VerificationResult cache. */ 052 private VerificationResult verificationResult = null; 053 054 055 /** 056 * This method runs a verification pass conforming to the 057 * Java Virtual Machine Specification, 2nd edition, on a 058 * class file. 059 * PassVerifier instances perform caching; 060 * i.e. if the verify() method once determined a VerificationResult, 061 * then this result may be returned after every invocation of this 062 * method instead of running the verification pass anew; likewise with 063 * the result of getMessages(). 064 * 065 * @see #getMessages() 066 * @see #addMessage(String) 067 */ 068 public VerificationResult verify() { 069 if (verificationResult == null) { 070 verificationResult = do_verify(); 071 } 072 return verificationResult; 073 } 074 075 076 /** Does the real verification work, uncached. */ 077 public abstract VerificationResult do_verify(); 078 079 080 /** 081 * This method adds a (warning) message to the message pool of this 082 * PassVerifier. This method is normally only internally used by 083 * BCEL's class file verifier "JustIce" and should not be used from 084 * the outside. 085 * 086 * @see #getMessages() 087 */ 088 public void addMessage( final String message ) { 089 messages.add(message); 090 } 091 092 093 /** 094 * Returns the (warning) messages that this PassVerifier accumulated 095 * during its do_verify()ing work. 096 * 097 * @see #addMessage(String) 098 * @see #do_verify() 099 */ 100 public String[] getMessages() { 101 verify(); // create messages if not already done (cached!) 102 return messages.toArray(new String[messages.size()]); 103 } 104}