package org.etk.kernel.container;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.Parameter;
import org.picocontainer.PicoContainer;
import org.picocontainer.PicoException;
import org.picocontainer.PicoRegistrationException;
import org.picocontainer.PicoVisitor;
import org.picocontainer.defaults.ComponentAdapterFactory;
import org.picocontainer.defaults.DuplicateComponentKeyRegistrationException;
public class CachingContainer extends ConcurrentContainer {
/**
* Serial Version UID
*/
private static final long serialVersionUID = 316388590860241305L;
private final ConcurrentMap<Class, ComponentAdapter> adapterByType = new ConcurrentHashMap<Class, ComponentAdapter>();
private final ConcurrentMap<Class, Object> instanceByType = new ConcurrentHashMap<Class, Object>();
private final ConcurrentMap<Object, Object> instanceByKey = new ConcurrentHashMap<Object, Object>();
private final ConcurrentMap<Class, List> adaptersByType = new ConcurrentHashMap<Class, List>();
private final ConcurrentMap<Class, List> instancesByType = new ConcurrentHashMap<Class, List>();
public CachingContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
super(componentAdapterFactory, parent);
}
public CachingContainer(PicoContainer parent) {
super(parent);
}
public CachingContainer(ComponentAdapterFactory componentAdapterFactory) {
super(componentAdapterFactory);
}
public CachingContainer() {
}
public ComponentAdapter getComponentAdapterOfType(Class componentType) {
ComponentAdapter adapter = adapterByType.get(componentType);
if (adapter == null) {
adapter = super.getComponentAdapterOfType(componentType);
if (adapter != null) {
adapterByType.put(componentType, adapter);
}
}
return adapter;
}
public List getComponentAdaptersOfType(Class componentType) {
List adapters = adaptersByType.get(componentType);
if (adapters == null) {
adapters = super.getComponentAdaptersOfType(componentType);
if (adapters != null) {
adaptersByType.put(componentType, adapters);
}
}
return adapters;
}
public List getComponentInstancesOfType(Class componentType) throws PicoException {
List instances = instancesByType.get(componentType);
if (instances == null) {
instances = super.getComponentInstancesOfType(componentType);
if (instances != null) {
instancesByType.put(componentType, instances);
}
}
return instances;
}
public Object getComponentInstance(Object componentKey) throws PicoException {
Object instance = instanceByKey.get(componentKey);
if (instance == null) {
instance = super.getComponentInstance(componentKey);
if (instance != null) {
instanceByKey.put(componentKey, instance);
}
}
return instance;
}
/**
*
*/
public Object getComponentInstanceOfType(Class componentType) {
Object instance = instanceByType.get(componentType);
if (instance == null) {
instance = super.getComponentInstanceOfType(componentType);
if (instance != null) {
instanceByType.put(componentType, instance);
}
}
return instance;
}
private static final PicoVisitor invalidator = new ContainerVisitor() {
public void visitContainer(PicoContainer pico) {
if (pico instanceof CachingContainer) {
CachingContainer caching = (CachingContainer) pico;
caching.adapterByType.clear();
caching.adaptersByType.clear();
caching.instanceByKey.clear();
caching.adaptersByType.clear();
caching.instancesByType.clear();
}
}
};
private void invalidate() {
accept(invalidator);
}
//
public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws DuplicateComponentKeyRegistrationException {
ComponentAdapter adapter = super.registerComponent(componentAdapter);
invalidate();
return adapter;
}
public ComponentAdapter unregisterComponent(Object componentKey) {
ComponentAdapter adapter = super.unregisterComponent(componentKey);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentInstance(Object component) throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentInstance(component);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentInstance(componentKey, componentInstance);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentImplementation(componentImplementation);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation)
throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentImplementation(componentKey, componentImplementation);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentImplementation(componentKey, componentImplementation, parameters);
invalidate();
return adapter;
}
public ComponentAdapter registerComponentImplementation(
Object componentKey, Class componentImplementation, List parameters)
throws PicoRegistrationException {
ComponentAdapter adapter = super.registerComponentImplementation(
componentKey, componentImplementation, parameters);
invalidate();
return adapter;
}
}