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: *****************************************************************************/package org.picocontainer.lifecycle;
008:
009: import java.lang.reflect.Method;
010:
011: import org.picocontainer.ComponentMonitor;
012: import org.picocontainer.Disposable;
013: import org.picocontainer.Startable;
014:
015: /**
016: * Startable lifecycle strategy. Starts and stops component if Startable,
017: * and disposes it if Disposable.
018: *
019: * A subclass of this class can define other intrfaces for Startable/Disposable as well as other method names
020: * for start/stop/dispose
021: *
022: * @author Mauro Talevi
023: * @author Jörg Schaible
024: * @see Startable
025: * @see Disposable
026: */
027: public class StartableLifecycleStrategy extends
028: AbstractMonitoringLifecycleStrategy {
029:
030: /**
031: * Serialization UUID.
032: */
033: private static final long serialVersionUID = 4967544912924651398L;
034:
035: private transient Method start, stop, dispose;
036:
037: public StartableLifecycleStrategy(final ComponentMonitor monitor) {
038: super (monitor);
039: }
040:
041: private void doMethodsIfNotDone() {
042: try {
043: if (start == null) {
044: start = getStartableInterface().getMethod(
045: getStartMethodName());
046: }
047: if (stop == null) {
048: stop = getStartableInterface().getMethod(
049: getStopMethodName());
050: }
051: if (dispose == null) {
052: dispose = getDisposableInterface().getMethod(
053: getDisposeMethodName());
054: }
055: } catch (NoSuchMethodException e) {
056: }
057: }
058:
059: /**
060: * Retrieve the lifecycle method name that represents the dispose method.
061: * @return the dispose method name. ('dispose')
062: */
063: protected String getDisposeMethodName() {
064: return "dispose";
065: }
066:
067: /**
068: * Retrieve the lifecycle method name that represents the stop method.
069: * @return the stop method name ('stop')
070: */
071: protected String getStopMethodName() {
072: return "stop";
073: }
074:
075: /**
076: * Retrieve the lifecycle method name that represents the start method.
077: * @return the stop method name ('start')
078: */
079: protected String getStartMethodName() {
080: return "start";
081: }
082:
083: /** {@inheritDoc} **/
084: public void start(final Object component) {
085: doMethodsIfNotDone();
086: if (component != null
087: && getStartableInterface().isAssignableFrom(
088: component.getClass())) {
089: long str = System.currentTimeMillis();
090: currentMonitor().invoking(null, null, start, component);
091: try {
092: startComponent(component);
093: currentMonitor().invoked(null, null, start, component,
094: System.currentTimeMillis() - str);
095: } catch (RuntimeException cause) {
096: currentMonitor().lifecycleInvocationFailed(null, null,
097: start, component, cause); // may re-throw
098: }
099: }
100: }
101:
102: protected void startComponent(final Object component) {
103: ((Startable) component).start();
104: }
105:
106: protected void stopComponent(final Object component) {
107: ((Startable) component).stop();
108: }
109:
110: protected void disposeComponent(final Object component) {
111: ((Disposable) component).dispose();
112: }
113:
114: /** {@inheritDoc} **/
115: public void stop(final Object component) {
116: doMethodsIfNotDone();
117: if (component != null
118: && getStartableInterface().isAssignableFrom(
119: component.getClass())) {
120: long str = System.currentTimeMillis();
121: currentMonitor().invoking(null, null, stop, component);
122: try {
123: stopComponent(component);
124: currentMonitor().invoked(null, null, stop, component,
125: System.currentTimeMillis() - str);
126: } catch (RuntimeException cause) {
127: currentMonitor().lifecycleInvocationFailed(null, null,
128: stop, component, cause); // may re-throw
129: }
130: }
131: }
132:
133: /** {@inheritDoc} **/
134: public void dispose(final Object component) {
135: doMethodsIfNotDone();
136: if (component != null
137: && getDisposableInterface().isAssignableFrom(
138: component.getClass())) {
139: long str = System.currentTimeMillis();
140: currentMonitor().invoking(null, null, dispose, component);
141: try {
142: disposeComponent(component);
143: currentMonitor().invoked(null, null, dispose,
144: component, System.currentTimeMillis() - str);
145: } catch (RuntimeException cause) {
146: currentMonitor().lifecycleInvocationFailed(null, null,
147: dispose, component, cause); // may re-throw
148: }
149: }
150: }
151:
152: /** {@inheritDoc} **/
153: public boolean hasLifecycle(final Class<?> type) {
154: return getStartableInterface().isAssignableFrom(type)
155: || getDisposableInterface().isAssignableFrom(type);
156: }
157:
158: protected Class<Disposable> getDisposableInterface() {
159: return Disposable.class;
160: }
161:
162: protected Class<Startable> getStartableInterface() {
163: return Startable.class;
164: }
165: }
|