001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 021 package org.apache.geronimo.naming.deployment; 022 023 import java.lang.reflect.Method; 024 import java.util.HashMap; 025 import java.util.List; 026 import java.util.Map; 027 028 import javax.annotation.PostConstruct; 029 import javax.annotation.PreDestroy; 030 031 import org.apache.geronimo.common.DeploymentException; 032 import org.apache.geronimo.gbean.GBeanInfo; 033 import org.apache.geronimo.gbean.GBeanInfoBuilder; 034 import org.apache.geronimo.j2ee.annotation.Holder; 035 import org.apache.geronimo.j2ee.annotation.LifecycleMethod; 036 import org.apache.geronimo.j2ee.deployment.Module; 037 import org.apache.geronimo.j2ee.deployment.NamingBuilder; 038 import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedApp; 039 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 040 import org.apache.geronimo.kernel.config.ConfigurationModuleType; 041 import org.apache.geronimo.xbeans.javaee.FullyQualifiedClassType; 042 import org.apache.geronimo.xbeans.javaee.JavaIdentifierType; 043 import org.apache.geronimo.xbeans.javaee.LifecycleCallbackType; 044 import org.apache.xbean.finder.ClassFinder; 045 import org.apache.xmlbeans.QNameSet; 046 import org.apache.xmlbeans.XmlObject; 047 048 /** 049 * @version $Rev: 541492 $ $Date: 2007-05-24 20:09:32 -0400 (Thu, 24 May 2007) $ 050 */ 051 public class LifecycleMethodBuilder extends AbstractNamingBuilder { 052 public void buildNaming(XmlObject specDD, XmlObject plan, Module module, Map componentContext) throws DeploymentException { 053 // skip ejb modules... they have alreayd been processed 054 if (module.getType() == ConfigurationModuleType.EJB) { 055 return; 056 } 057 058 ClassFinder classFinder = module.getClassFinder(); 059 AnnotatedApp annotatedApp = module.getAnnotatedApp(); 060 if (annotatedApp == null) { 061 throw new NullPointerException("No AnnotatedApp supplied"); 062 } 063 Map<String, LifecycleCallbackType> postConstructMap = mapLifecycleCallbacks(annotatedApp.getPostConstructArray(), annotatedApp.getComponentType()); 064 Map<String, LifecycleCallbackType> preDestroyMap = mapLifecycleCallbacks(annotatedApp.getPreDestroyArray(), annotatedApp.getComponentType()); 065 if (module.getClassFinder() != null) { 066 List<Method> postConstructs = classFinder.findAnnotatedMethods(PostConstruct.class); 067 for (Method m : postConstructs) { 068 String methodName = m.getName(); 069 String className = m.getDeclaringClass().getName(); 070 if (!postConstructMap.containsKey(className)) { 071 LifecycleCallbackType callback = annotatedApp.addPostConstruct(); 072 FullyQualifiedClassType classType = callback.addNewLifecycleCallbackClass(); 073 classType.setStringValue(className); 074 JavaIdentifierType method = callback.addNewLifecycleCallbackMethod(); 075 method.setStringValue(methodName); 076 postConstructMap.put(className, callback); 077 } 078 } 079 List<Method> preDestroys = classFinder.findAnnotatedMethods(PreDestroy.class); 080 for (Method m : preDestroys) { 081 String methodName = m.getName(); 082 String className = m.getDeclaringClass().getName(); 083 if (!preDestroyMap.containsKey(className)) { 084 LifecycleCallbackType callback = annotatedApp.addPreDestroy(); 085 FullyQualifiedClassType classType = callback.addNewLifecycleCallbackClass(); 086 classType.setStringValue(className); 087 JavaIdentifierType method = callback.addNewLifecycleCallbackMethod(); 088 method.setStringValue(methodName); 089 preDestroyMap.put(className, callback); 090 } 091 } 092 } 093 Map<String, LifecycleMethod> postConstructs = map(postConstructMap); 094 Map<String, LifecycleMethod> preDestroys = map(preDestroyMap); 095 Holder holder = NamingBuilder.INJECTION_KEY.get(componentContext); 096 holder.addPostConstructs(postConstructs); 097 holder.addPreDestroys(preDestroys); 098 } 099 100 private Map<String, LifecycleMethod> map(Map<String, LifecycleCallbackType> lifecycleCallbackTypes) { 101 if (lifecycleCallbackTypes.isEmpty()) { 102 return null; 103 } 104 Map<String, LifecycleMethod> map = new HashMap<String, LifecycleMethod>(); 105 for (Map.Entry<String, LifecycleCallbackType> entry : lifecycleCallbackTypes.entrySet()) { 106 String className = entry.getKey(); 107 LifecycleCallbackType callback = entry.getValue(); 108 LifecycleMethod method = new LifecycleMethod(className, callback.getLifecycleCallbackMethod().getStringValue().trim()); 109 map.put(className, method); 110 } 111 return map; 112 } 113 114 private Map<String, LifecycleCallbackType> mapLifecycleCallbacks(LifecycleCallbackType[] callbackArray, String componentType) throws DeploymentException { 115 Map<String, LifecycleCallbackType> map = new HashMap<String, LifecycleCallbackType>(); 116 for (LifecycleCallbackType callback : callbackArray) { 117 String className; 118 if (callback.isSetLifecycleCallbackClass()) { 119 className = callback.getLifecycleCallbackClass().getStringValue().trim(); 120 } else { 121 if (componentType == null) { 122 throw new DeploymentException("No component type available and none in lifecycle callback"); 123 } 124 className = componentType; 125 } 126 map.put(className, callback); 127 } 128 return map; 129 } 130 131 public QNameSet getSpecQNameSet() { 132 return QNameSet.EMPTY; 133 } 134 135 public QNameSet getPlanQNameSet() { 136 return QNameSet.EMPTY; 137 } 138 139 public static final GBeanInfo GBEAN_INFO; 140 141 static { 142 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(LifecycleMethodBuilder.class, NameFactory.MODULE_BUILDER); 143 144 GBEAN_INFO = infoBuilder.getBeanInfo(); 145 } 146 147 public static GBeanInfo getGBeanInfo() { 148 return GBEAN_INFO; 149 } 150 }