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