All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.discovery.tools.EnvironmentCache Maven / Gradle / Ivy

Go to download

Its an port to fix bugs in OSGi support. ... The Apache Commons Discovery 0.5 component is about discovering, or finding, implementations for pluggable interfaces.

There is a newer version: 7.4.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.discovery.tools;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.discovery.jdk.JDKHooks;

/**
 * Cache by a 'key' unique to the environment:
 *
 * - ClassLoader::groupContext::Object Cache
 *         Cache : HashMap
 *         Key   : Thread Context Class Loader (ClassLoader)
 *         Value : groupContext::SPI Cache (HashMap)
 *
 * //- groupContext::Object Cache
 * //         Cache : HashMap
 * //         Key   : groupContext (String)
 * //        Value : Object
 *
 * When we 'release', it is expected that the caller of the 'release'
 * have the same thread context class loader... as that will be used
 * to identify cached entries to be released.
 */
public class EnvironmentCache {

    /**
     * Allows null key, important as default groupContext is null.
     *
     * We will manage synchronization directly, so all caches are implemented
     * as HashMap (unsynchronized).
     */
    private static final Map> root_cache =
        new HashMap>();

    /**
     * Initial hash size for SPI's, default just seem TO big today..
     */
    public static final int smallHashSize = 13;

    /**
     * Get object keyed by classLoader.
     *
     * @param classLoader The class loader key
     * @return The SPI name/instance cache
     */
    public static synchronized Map get(ClassLoader classLoader) {
        /*
         * 'null' (bootstrap/system class loader) thread context class loader
         * is ok...  Until we learn otherwise.
         */
        return root_cache.get(classLoader);
    }

    /**
     * Put service keyed by spi & classLoader.
     *
     * @param classLoader The class loader key
     * @param spis The SPI name/instance cache
     */
    public static synchronized void put(ClassLoader classLoader, Map spis) {
        /*
         * 'null' (bootstrap/system class loader) thread context class loader
         * is ok...  Until we learn otherwise.
         */
        if (spis != null) {
            root_cache.put(classLoader, spis);
        }
    }

    /********************** CACHE-MANAGEMENT SUPPORT **********************/

    /**
     * Release all internal references to previously created service
     * instances associated with the current thread context class loader.
     * The release() method is called for service instances that
     * implement the Service interface.
     *
     * This is useful in environments like servlet containers,
     * which implement application reloading by throwing away a ClassLoader.
     * Dangling references to objects in that class loader would prevent
     * garbage collection.
     */
    public static synchronized void release() {
        /*
         * 'null' (bootstrap/system class loader) thread context class loader
         * is ok...  Until we learn otherwise.
         */
        root_cache.remove(JDKHooks.getJDKHooks().getThreadContextClassLoader());
    }

    /**
     * Release any internal references to a previously created service
     * instance associated with the current thread context class loader.
     * If the SPI instance implements Service, then call
     * release().
     *
     * @param classLoader The class loader key
     */
    public static synchronized void release(ClassLoader classLoader) {
        /*
         * 'null' (bootstrap/system class loader) thread context class loader
         * is ok...  Until we learn otherwise.
         */
        root_cache.remove(classLoader);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy