001: package org.picocontainer.behaviors;
002:
003: import org.picocontainer.ComponentAdapter;
004: import org.picocontainer.LifecycleStrategy;
005: import org.picocontainer.ObjectReference;
006: import org.picocontainer.PicoCompositionException;
007: import org.picocontainer.PicoContainer;
008:
009: /**
010: * behaviour for all behaviours wishing to store
011: * their component in "awkward places" ( object references )
012: * @author Konstantin Pribluda
013: *
014: * @param <T>
015: */
016: public class Stored<T> extends AbstractBehavior<T> {
017:
018: /**
019: * Serialization UUID.
020: */
021: private static final long serialVersionUID = -155678172730744032L;
022:
023: protected final boolean delegateHasLifecylce;
024: protected boolean disposed;
025: protected final ObjectReference<T> instanceReference;
026:
027: protected boolean started;
028:
029: public Stored(ComponentAdapter<T> delegate,
030: ObjectReference<T> reference) {
031: super (delegate);
032: instanceReference = reference;
033: this .disposed = false;
034: this .started = false;
035: this .delegateHasLifecylce = delegate instanceof LifecycleStrategy
036: && ((LifecycleStrategy) delegate).hasLifecycle(delegate
037: .getComponentImplementation());
038:
039: }
040:
041: public boolean componentHasLifecycle() {
042: return delegateHasLifecylce;
043: }
044:
045: /**
046: * Disposes the cached component instance
047: * {@inheritDoc}
048: */
049: public void dispose(PicoContainer container) {
050: if (delegateHasLifecylce) {
051: if (disposed)
052: throw new IllegalStateException("Already disposed");
053: dispose(getComponentInstance(container));
054: disposed = true;
055: }
056: }
057:
058: /**
059: * Retrieves the stored reference. May be null if it has
060: * never been set, or possibly if the reference has been
061: * flushed.
062: * @return the stored object or null.
063: */
064: public T getStoredObject() {
065: return instanceReference.get();
066: }
067:
068: /**
069: * Flushes the cache.
070: * If the component instance is started is will stop and dispose it before
071: * flushing the cache.
072: */
073: public void flush() {
074: Object instance = instanceReference.get();
075: if (instance != null && delegateHasLifecylce && started) {
076: stop(instance);
077: dispose(instance);
078: }
079: instanceReference.set(null);
080: }
081:
082: public T getComponentInstance(PicoContainer container)
083: throws PicoCompositionException {
084: T instance = instanceReference.get();
085: if (instance == null) {
086: instance = super .getComponentInstance(container);
087: instanceReference.set(instance);
088: }
089: return instance;
090: }
091:
092: public String getDescriptor() {
093: return "Stored";
094: }
095:
096: /**
097: * Starts the cached component instance
098: * {@inheritDoc}
099: */
100: public void start(PicoContainer container) {
101: if (delegateHasLifecylce) {
102: if (disposed)
103: throw new IllegalStateException("Already disposed");
104: if (started)
105: throw new IllegalStateException("Already started");
106: start(getComponentInstance(container));
107: started = true;
108: }
109: }
110:
111: /**
112: * Stops the cached component instance
113: * {@inheritDoc}
114: */
115: public void stop(PicoContainer container) {
116: if (delegateHasLifecylce) {
117: if (disposed)
118: throw new IllegalStateException("Already disposed");
119: if (!started)
120: throw new IllegalStateException("Not started");
121: stop(getComponentInstance(container));
122: started = false;
123: }
124: }
125:
126: }
|