org.apache.wicket.util.collections.ClassMetaCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.ops4j.pax.wicket.service Show documentation
Show all versions of org.ops4j.pax.wicket.service Show documentation
Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and
unloading of Wicket components and pageSources.
/*
* 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.wicket.util.collections;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* This class wraps a WeakHashMap that holds one ConcurrentHashMap per ClassLoader. In the rare
* event of a previously unmapped ClassLoader, the WeakHashMap is replaced by a new one. This avoids
* any synchronization overhead, much like a {@link java.util.concurrent.CopyOnWriteArrayList}
*
* @param
* type of objects stored in cache
*/
public class ClassMetaCache
{
private volatile Map> cache = Collections.emptyMap();
/**
* Puts value into cache
*
* @param key
* @param value
* @return value previously stored in cache for this key, or {@code null} if none
*/
public T put(Class> key, T value)
{
ConcurrentHashMap container = getClassLoaderCache(key.getClassLoader(), true);
return container.put(key(key), value);
}
/**
* Gets value from cache or returns {@code null} if not in cache
*
* @param key
* @return value stored in cache or {@code null} if none
*/
public T get(Class> key)
{
ConcurrentHashMap container = getClassLoaderCache(key.getClassLoader(), false);
if (container == null)
{
return null;
}
else
{
return container.get(key(key));
}
}
/**
* @param classLoader
* @param create
* @return a {@link ConcurrentHashMap} mapping class names to injectable fields, never
* null
*/
private ConcurrentHashMap getClassLoaderCache(ClassLoader classLoader, boolean create)
{
ConcurrentHashMap container = cache.get(classLoader);
if (container == null)
{
if (!create)
{
return container;
}
// only lock in rare event of unknown ClassLoader
synchronized (this)
{
// check again inside lock
container = cache.get(classLoader);
if (container == null)
{
container = new ConcurrentHashMap();
/*
* don't write to current cache, copy instead
*/
Map> newCache = new WeakHashMap>(
cache);
newCache.put(classLoader, container);
cache = Collections.unmodifiableMap(newCache);
}
}
}
return container;
}
/**
* converts class into a key used by the cache
*
* @param clazz
*
* @return string representation of the clazz
*/
private static String key(Class> clazz)
{
return clazz.getName();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy