    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    static void clear() {
    054        MAP.clear();
    055        OBSVERVERS.clear();
    056    }
    057
    058    /**
    059     * Removes the VerifierFactoryObserver o from the list of observers.
    060     */
    061    public static void detach(final VerifierFactoryObserver o) {
    062        OBSVERVERS.remove(o);
    063    }
    064
    065    /**
    066     * Returns the (only) verifier responsible for the class with the given name. Possibly a new Verifier object is
    067     * transparently created.
    068     *
    069     * @return the (only) verifier responsible for the class with the given name.
    070     */
    071    public static Verifier getVerifier(final String fullyQualifiedClassName) {
    072        return MAP.computeIfAbsent(fullyQualifiedClassName, k -> {
    073            final Verifier v = new Verifier(k);
    074            notify(k);
    075            return v;
    076        });
    077    }
    078
    079    /**
    080     * Returns all Verifier instances created so far. This is useful when a Verifier recursively lets the VerifierFactory
    081     * create other Verifier instances and if you want to verify the transitive hull of referenced class files.
    082     */
    083    public static Verifier[] getVerifiers() {
    084        return MAP.values().toArray(Verifier.EMPTY_ARRAY);
    085    }
    086
    087    /**
    088     * Notifies the observers of a newly generated Verifier.
    089     */
    090    private static void notify(final String fullyQualifiedClassName) {
    091        // notify the observers
    092        OBSVERVERS.forEach(vfo -> vfo.update(fullyQualifiedClassName));
    093    }
    094
    095    /**
    096     * The VerifierFactory is not instantiable.
    097     */
    098    private VerifierFactory() {
    099    }
    100}