001: /*****************************************************************************
002: * Copyright (c) PicoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant *
009: *****************************************************************************/package org.picocontainer.behaviors;
010:
011: import org.picocontainer.ComponentAdapter;
012: import org.picocontainer.Parameter;
013: import org.picocontainer.PicoCompositionException;
014: import org.picocontainer.Characteristics;
015: import org.picocontainer.ComponentMonitor;
016: import org.picocontainer.LifecycleStrategy;
017: import org.picocontainer.references.ThreadLocalMapObjectReference;
018:
019: import java.io.Serializable;
020: import java.util.Properties;
021: import java.util.HashMap;
022: import java.util.Map;
023: import java.util.Collections;
024:
025: /**
026: * @author Paul Hammant
027: */
028: public class Storing extends AbstractBehaviorFactory {
029:
030: private final StoreThreadLocal mapThreadLocalObjectReference = new StoreThreadLocal();
031:
032: public <T> ComponentAdapter<T> createComponentAdapter(
033: ComponentMonitor componentMonitor,
034: LifecycleStrategy lifecycleStrategy,
035: Properties componentProperties, final Object componentKey,
036: Class<T> componentImplementation, Parameter... parameters)
037:
038: throws PicoCompositionException {
039: if (removePropertiesIfPresent(componentProperties,
040: Characteristics.NO_CACHE)) {
041: return super .createComponentAdapter(componentMonitor,
042: lifecycleStrategy, componentProperties,
043: componentKey, componentImplementation, parameters);
044: }
045: removePropertiesIfPresent(componentProperties,
046: Characteristics.CACHE);
047: return new Stored<T>(super .createComponentAdapter(
048: componentMonitor, lifecycleStrategy,
049: componentProperties, componentKey,
050: componentImplementation, parameters),
051: new ThreadLocalMapObjectReference(
052: mapThreadLocalObjectReference, componentKey));
053:
054: }
055:
056: public <T> ComponentAdapter<T> addComponentAdapter(
057: ComponentMonitor componentMonitor,
058: LifecycleStrategy lifecycleStrategy,
059: Properties componentProperties,
060: final ComponentAdapter<T> adapter) {
061: if (removePropertiesIfPresent(componentProperties,
062: Characteristics.NO_CACHE)) {
063: return super .addComponentAdapter(componentMonitor,
064: lifecycleStrategy, componentProperties, adapter);
065: }
066: removePropertiesIfPresent(componentProperties,
067: Characteristics.CACHE);
068:
069: return new Stored<T>(super .addComponentAdapter(
070: componentMonitor, lifecycleStrategy,
071: componentProperties, adapter),
072: new ThreadLocalMapObjectReference(
073: mapThreadLocalObjectReference, adapter
074: .getComponentKey()));
075: }
076:
077: public StoreWrapper getCacheForThread() {
078: StoreWrapper wrappedMap = new StoreWrapper();
079: wrappedMap.wrapped = (Map) mapThreadLocalObjectReference.get();
080: return wrappedMap;
081: }
082:
083: public void putCacheForThread(StoreWrapper wrappedMap) {
084: mapThreadLocalObjectReference.set(wrappedMap.wrapped);
085: }
086:
087: public Map resetCacheForThread() {
088: HashMap map = new HashMap();
089: mapThreadLocalObjectReference.set(map);
090: return map;
091: }
092:
093: public void invalidateCacheForThread() {
094: mapThreadLocalObjectReference.set(Collections
095: .unmodifiableMap(Collections.emptyMap()));
096: }
097:
098: public static class StoreThreadLocal extends ThreadLocal {
099: protected Object initialValue() {
100: return new HashMap();
101: }
102: }
103:
104: public static class StoreWrapper implements Serializable {
105: private Map wrapped;
106: }
107:
108: }
|