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.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Vector; 024 025/** 026 * This class produces instances of the Verifier class. Its purpose is to make 027 * sure that they are singleton instances with respect to the class name they 028 * operate on. That means, for every class (represented by a unique fully qualified 029 * class name) there is exactly one Verifier. 030 * 031 * @see Verifier 032 */ 033public class VerifierFactory { 034 035 /** 036 * The HashMap that holds the data about the already-constructed Verifier instances. 037 */ 038 private static final Map<String, Verifier> hashMap = new HashMap<>(); 039 /** 040 * The VerifierFactoryObserver instances that observe the VerifierFactory. 041 */ 042 private static final List<VerifierFactoryObserver> observers = new Vector<>(); 043 044 045 /** 046 * The VerifierFactory is not instantiable. 047 */ 048 private VerifierFactory() { 049 } 050 051 052 /** 053 * Returns the (only) verifier responsible for the class with the given name. 054 * Possibly a new Verifier object is transparently created. 055 * @return the (only) verifier responsible for the class with the given name. 056 */ 057 public static Verifier getVerifier( final String fullyQualifiedClassName ) { 058 Verifier v = hashMap.get(fullyQualifiedClassName); 059 if (v == null) { 060 v = new Verifier(fullyQualifiedClassName); 061 hashMap.put(fullyQualifiedClassName, v); 062 notify(fullyQualifiedClassName); 063 } 064 return v; 065 } 066 067 068 /** 069 * Notifies the observers of a newly generated Verifier. 070 */ 071 private static void notify( final String fullyQualifiedClassName ) { 072 // notify the observers 073 for (final VerifierFactoryObserver vfo : observers) { 074 vfo.update(fullyQualifiedClassName); 075 } 076 } 077 078 079 /** 080 * Returns all Verifier instances created so far. 081 * This is useful when a Verifier recursively lets 082 * the VerifierFactory create other Verifier instances 083 * and if you want to verify the transitive hull of 084 * referenced class files. 085 */ 086 public static Verifier[] getVerifiers() { 087 final Verifier[] vs = new Verifier[hashMap.values().size()]; 088 return hashMap.values().toArray(vs); // Because vs is big enough, vs is used to store the values into and returned! 089 } 090 091 092 /** 093 * Adds the VerifierFactoryObserver o to the list of observers. 094 */ 095 public static void attach( final VerifierFactoryObserver o ) { 096 observers.add(o); 097 } 098 099 100 /** 101 * Removes the VerifierFactoryObserver o from the list of observers. 102 */ 103 public static void detach( final VerifierFactoryObserver o ) { 104 observers.remove(o); 105 } 106}