    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 */
    017package org.apache.bcel.verifier;
    018
    019import java.util.HashMap;
    020import java.util.List;
    021import java.util.Map;
    022import java.util.Vector;
    023
    024/**
    025 * This class produces instances of the Verifier class. Its purpose is to make sure that they are singleton instances
    026 * with respect to the class name they operate on. That means, for every class (represented by a unique fully qualified
    027 * class name) there is exactly one Verifier.
    028 *
    029 * @see Verifier
    030 */
    031public class VerifierFactory {
    032
    033    /**
    034     * The HashMap that holds the data about the already-constructed Verifier instances.
    035     */
    036    private static final Map<String, Verifier> MAP = new HashMap<>();
    037
    038    /**
    039     * The VerifierFactoryObserver instances that observe the VerifierFactory.
    040     */
    041    private static final List<VerifierFactoryObserver> OBSVERVERS = new Vector<>();
    042
    043    /**
    044     * Adds the VerifierFactoryObserver o to the list of observers.
    045     */
    046    public static void attach(final VerifierFactoryObserver o) {
    047        OBSVERVERS.add(o);
    048    }
    049
    050    /**
    051     * Clears the factory.
    052     *
    053     * @since 6.6.2
    054     */
    055    public static void clear() {
    056        MAP.clear();
    057        OBSVERVERS.clear();
    058    }
    059
    060    /**
    061     * Removes the VerifierFactoryObserver o from the list of observers.
    062     */
    063    public static void detach(final VerifierFactoryObserver o) {
    064        OBSVERVERS.remove(o);
    065    }
    066
    067    /**
    068     * Returns the (only) verifier responsible for the class with the given name. Possibly a new Verifier object is
    069     * transparently created.
    070     *
    071     * @return the (only) verifier responsible for the class with the given name.
    072     */
    073    public static Verifier getVerifier(final String fullyQualifiedClassName) {
    074        return MAP.computeIfAbsent(fullyQualifiedClassName, k -> {
    075            final Verifier v = new Verifier(k);
    076            notify(k);
    077            return v;
    078        });
    079    }
    080
    081    /**
    082     * Returns all Verifier instances created so far. This is useful when a Verifier recursively lets the VerifierFactory
    083     * create other Verifier instances and if you want to verify the transitive hull of referenced class files.
    084     */
    085    public static Verifier[] getVerifiers() {
    086        return MAP.values().toArray(Verifier.EMPTY_ARRAY);
    087    }
    088
    089    /**
    090     * Notifies the observers of a newly generated Verifier.
    091     */
    092    private static void notify(final String fullyQualifiedClassName) {
    093        // notify the observers
    094        OBSVERVERS.forEach(vfo -> vfo.update(fullyQualifiedClassName));
    095    }
    096
    097    /**
    098     * The VerifierFactory is not instantiable.
    099     */
    100    private VerifierFactory() {
    101    }
    102}