1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.bcel.verifier; 18 19 import java.util.HashMap; 20 import java.util.List; 21 import java.util.Map; 22 import java.util.Vector; 23 24 /** 25 * This class produces instances of the Verifier class. Its purpose is to make sure that they are singleton instances 26 * with respect to the class name they operate on. That means, for every class (represented by a unique fully qualified 27 * class name) there is exactly one Verifier. 28 * 29 * @see Verifier 30 */ 31 public class VerifierFactory { 32 33 /** 34 * The HashMap that holds the data about the already-constructed Verifier instances. 35 */ 36 private static final Map<String, Verifier> MAP = new HashMap<>(); 37 38 /** 39 * The VerifierFactoryObserver instances that observe the VerifierFactory. 40 */ 41 private static final List<VerifierFactoryObserver> OBSVERVERS = new Vector<>(); 42 43 /** 44 * Adds the VerifierFactoryObserver o to the list of observers. 45 */ 46 public static void attach(final VerifierFactoryObserver o) { 47 OBSVERVERS.add(o); 48 } 49 50 /** 51 * Clears the factory. 52 * 53 * @since 6.6.2 54 */ 55 public static void clear() { 56 MAP.clear(); 57 OBSVERVERS.clear(); 58 } 59 60 /** 61 * Removes the VerifierFactoryObserver o from the list of observers. 62 */ 63 public static void detach(final VerifierFactoryObserver o) { 64 OBSVERVERS.remove(o); 65 } 66 67 /** 68 * Returns the (only) verifier responsible for the class with the given name. Possibly a new Verifier object is 69 * transparently created. 70 * 71 * @return the (only) verifier responsible for the class with the given name. 72 */ 73 public static Verifier getVerifier(final String fullyQualifiedClassName) { 74 return MAP.computeIfAbsent(fullyQualifiedClassName, k -> { 75 final Verifier v = new Verifier(k); 76 notify(k); 77 return v; 78 }); 79 } 80 81 /** 82 * Returns all Verifier instances created so far. This is useful when a Verifier recursively lets the VerifierFactory 83 * create other Verifier instances and if you want to verify the transitive hull of referenced class files. 84 */ 85 public static Verifier[] getVerifiers() { 86 return MAP.values().toArray(Verifier.EMPTY_ARRAY); 87 } 88 89 /** 90 * Notifies the observers of a newly generated Verifier. 91 */ 92 private static void notify(final String fullyQualifiedClassName) { 93 // notify the observers 94 OBSVERVERS.forEach(vfo -> vfo.update(fullyQualifiedClassName)); 95 } 96 97 /** 98 * The VerifierFactory is not instantiable. 99 */ 100 private VerifierFactory() { 101 } 102 }