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 * @version $Id: VerifierFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ 032 * @see Verifier 033 */ 034public class VerifierFactory { 035 036 /** 037 * The HashMap that holds the data about the already-constructed Verifier instances. 038 */ 039 private static final Map<String, Verifier> hashMap = new HashMap<>(); 040 /** 041 * The VerifierFactoryObserver instances that observe the VerifierFactory. 042 */ 043 private static final List<VerifierFactoryObserver> observers = new Vector<>(); 044 045 046 /** 047 * The VerifierFactory is not instantiable. 048 */ 049 private VerifierFactory() { 050 } 051 052 053 /** 054 * Returns the (only) verifier responsible for the class with the given name. 055 * Possibly a new Verifier object is transparently created. 056 * @return the (only) verifier responsible for the class with the given name. 057 */ 058 public static Verifier getVerifier( final String fully_qualified_classname ) { 059 Verifier v = hashMap.get(fully_qualified_classname); 060 if (v == null) { 061 v = new Verifier(fully_qualified_classname); 062 hashMap.put(fully_qualified_classname, v); 063 notify(fully_qualified_classname); 064 } 065 return v; 066 } 067 068 069 /** 070 * Notifies the observers of a newly generated Verifier. 071 */ 072 private static void notify( final String fully_qualified_classname ) { 073 // notify the observers 074 for (final VerifierFactoryObserver vfo : observers) { 075 vfo.update(fully_qualified_classname); 076 } 077 } 078 079 080 /** 081 * Returns all Verifier instances created so far. 082 * This is useful when a Verifier recursively lets 083 * the VerifierFactory create other Verifier instances 084 * and if you want to verify the transitive hull of 085 * referenced class files. 086 */ 087 public static Verifier[] getVerifiers() { 088 final Verifier[] vs = new Verifier[hashMap.values().size()]; 089 return hashMap.values().toArray(vs); // Because vs is big enough, vs is used to store the values into and returned! 090 } 091 092 093 /** 094 * Adds the VerifierFactoryObserver o to the list of observers. 095 */ 096 public static void attach( final VerifierFactoryObserver o ) { 097 observers.add(o); 098 } 099 100 101 /** 102 * Removes the VerifierFactoryObserver o from the list of observers. 103 */ 104 public static void detach( final VerifierFactoryObserver o ) { 105 observers.remove(o); 106 } 107}