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.
/*
* 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);
}
}