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 }