VerifierFactory.java

  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. import java.util.HashMap;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Vector;

  22. /**
  23.  * This class produces instances of the Verifier class. Its purpose is to make sure that they are singleton instances
  24.  * with respect to the class name they operate on. That means, for every class (represented by a unique fully qualified
  25.  * class name) there is exactly one Verifier.
  26.  *
  27.  * @see Verifier
  28.  */
  29. public class VerifierFactory {

  30.     /**
  31.      * The HashMap that holds the data about the already-constructed Verifier instances.
  32.      */
  33.     private static final Map<String, Verifier> MAP = new HashMap<>();

  34.     /**
  35.      * The VerifierFactoryObserver instances that observe the VerifierFactory.
  36.      */
  37.     private static final List<VerifierFactoryObserver> OBSVERVERS = new Vector<>();

  38.     /**
  39.      * Adds the VerifierFactoryObserver o to the list of observers.
  40.      */
  41.     public static void attach(final VerifierFactoryObserver o) {
  42.         OBSVERVERS.add(o);
  43.     }

  44.     /**
  45.      * Clears the factory.
  46.      *
  47.      * @since 6.6.2
  48.      */
  49.     public static void clear() {
  50.         MAP.clear();
  51.         OBSVERVERS.clear();
  52.     }

  53.     /**
  54.      * Removes the VerifierFactoryObserver o from the list of observers.
  55.      */
  56.     public static void detach(final VerifierFactoryObserver o) {
  57.         OBSVERVERS.remove(o);
  58.     }

  59.     /**
  60.      * Returns the (only) verifier responsible for the class with the given name. Possibly a new Verifier object is
  61.      * transparently created.
  62.      *
  63.      * @return the (only) verifier responsible for the class with the given name.
  64.      */
  65.     public static Verifier getVerifier(final String fullyQualifiedClassName) {
  66.         return MAP.computeIfAbsent(fullyQualifiedClassName, k -> {
  67.             final Verifier v = new Verifier(k);
  68.             notify(k);
  69.             return v;
  70.         });
  71.     }

  72.     /**
  73.      * Returns all Verifier instances created so far. This is useful when a Verifier recursively lets the VerifierFactory
  74.      * create other Verifier instances and if you want to verify the transitive hull of referenced class files.
  75.      */
  76.     public static Verifier[] getVerifiers() {
  77.         return MAP.values().toArray(Verifier.EMPTY_ARRAY);
  78.     }

  79.     /**
  80.      * Notifies the observers of a newly generated Verifier.
  81.      */
  82.     private static void notify(final String fullyQualifiedClassName) {
  83.         // notify the observers
  84.         OBSVERVERS.forEach(vfo -> vfo.update(fullyQualifiedClassName));
  85.     }

  86.     /**
  87.      * The VerifierFactory is not instantiable.
  88.      */
  89.     private VerifierFactory() {
  90.     }
  91. }