View Javadoc
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 }