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 package org.picocontainer.lifecycle;
009
010 import java.lang.reflect.InvocationTargetException;
011 import java.lang.reflect.Method;
012 import java.lang.annotation.Annotation;
013
014 import org.picocontainer.ComponentMonitor;
015 import org.picocontainer.PicoLifecycleException;
016
017 import javax.annotation.PreDestroy;
018 import javax.annotation.PostConstruct;
019
020 /**
021 * Java EE 5 has some annotations PreDestroy and PostConstruct that map to start() and dispose() in our world
022 *
023 * @author Paul Hammant
024 */
025 @SuppressWarnings("serial")
026 public final class JavaEE5LifecycleStrategy extends AbstractMonitoringLifecycleStrategy {
027
028 /**
029 * Construct a JavaEE5LifecycleStrategy.
030 *
031 * @param monitor the monitor to use
032 * @throws NullPointerException if the monitor is <code>null</code>
033 */
034 public JavaEE5LifecycleStrategy(final ComponentMonitor monitor) {
035 super(monitor);
036 }
037
038 /** {@inheritDoc} **/
039 public void start(final Object component) {
040 doLifecycleMethod(component, PostConstruct.class);
041 }
042
043 /** {@inheritDoc} **/
044 public void stop(final Object component) {
045 }
046
047 /** {@inheritDoc} **/
048 public void dispose(final Object component) {
049 doLifecycleMethod(component, PreDestroy.class);
050 }
051
052 private void doLifecycleMethod(final Object component, Class<? extends Annotation> annotation) {
053 Method[] methods = component.getClass().getDeclaredMethods();
054 for (int i = 0; i < methods.length; i++) {
055 Method method = methods[i];
056 if (method.isAnnotationPresent(annotation)) {
057 try {
058 long str = System.currentTimeMillis();
059 currentMonitor().invoking(null, null, method, component, new Object[0]);
060 method.invoke(component);
061 currentMonitor().invoked(null, null, method, component, System.currentTimeMillis() - str, new Object[0], null);
062 } catch (IllegalAccessException e) {
063 throw new PicoLifecycleException(method, component, e);
064 } catch (InvocationTargetException e) {
065 throw new PicoLifecycleException(method, component, e);
066 }
067 }
068 }
069 }
070
071
072 /**
073 * {@inheritDoc} The component has a lifecycle PreDestroy or PostConstruct are on a method
074 */
075 public boolean hasLifecycle(final Class<?> type) {
076 Method[] methods = type.getDeclaredMethods();
077 for (int i = 0; i < methods.length; i++) {
078 Method method = methods[i];
079 if (method.isAnnotationPresent(PreDestroy.class) || method.isAnnotationPresent(PostConstruct.class)) {
080 return true;
081 }
082 }
083 return false;
084 }
085
086 }