\r
\r
import java.io.Serializable;\r
+import java.lang.reflect.InvocationTargetException;\r
import java.util.ArrayList;\r
import java.util.Enumeration;\r
import java.util.Map;\r
\r
+import javax.naming.NamingException;\r
import javax.servlet.Filter;\r
import javax.servlet.FilterConfig;\r
import javax.servlet.ServletContext;\r
import org.apache.catalina.Context;\r
import org.apache.catalina.deploy.FilterDef;\r
import org.apache.catalina.security.SecurityUtil;\r
+import org.apache.catalina.util.AnnotationProcessor;\r
import org.apache.catalina.util.Enumerator;\r
import org.apache.tomcat.util.log.SystemLogHandler;\r
\r
* @exception InstantiationException if an exception occurs while\r
* instantiating the filter object\r
* @exception ServletException if thrown by the filter's init() method\r
+ * @throws NamingException \r
+ * @throws InvocationTargetException \r
*/\r
public ApplicationFilterConfig(Context context, FilterDef filterDef)\r
throws ClassCastException, ClassNotFoundException,\r
IllegalAccessException, InstantiationException,\r
- ServletException {\r
+ ServletException, InvocationTargetException, NamingException {\r
\r
super();\r
this.context = context;\r
* @exception InstantiationException if an exception occurs while\r
* instantiating the filter object\r
* @exception ServletException if thrown by the filter's init() method\r
+ * @throws NamingException \r
+ * @throws InvocationTargetException \r
*/\r
Filter getFilter() throws ClassCastException, ClassNotFoundException,\r
- IllegalAccessException, InstantiationException, ServletException {\r
+ IllegalAccessException, InstantiationException, ServletException, \r
+ InvocationTargetException, NamingException {\r
\r
// Return the existing filter instance, if any\r
if (this.filter != null)\r
// Instantiate a new instance of this filter and return it\r
Class clazz = classLoader.loadClass(filterClass);\r
this.filter = (Filter) clazz.newInstance();\r
+ if (!context.getIgnoreAnnotations()) {\r
+ if (context instanceof StandardContext \r
+ && ((StandardContext) context).getNamingContextListener() != null) {\r
+ AnnotationProcessor.injectNamingResources\r
+ (((StandardContext) context).getNamingContextListener().getEnvContext(), this.filter);\r
+ }\r
+ AnnotationProcessor.postConstruct(this.filter);\r
+ }\r
if (context instanceof StandardContext &&\r
- ((StandardContext)context).getSwallowOutput()) {\r
+ ((StandardContext) context).getSwallowOutput()) {\r
try {\r
SystemLogHandler.startCapture();\r
filter.init(this);\r
void release() {\r
\r
if (this.filter != null){\r
- if( System.getSecurityManager() != null) {\r
- try{\r
+ if (System.getSecurityManager() != null) {\r
+ try {\r
SecurityUtil.doAsPrivilege("destroy", filter); \r
} catch(java.lang.Exception ex){ \r
context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);\r
} else { \r
filter.destroy();\r
}\r
+ if (!context.getIgnoreAnnotations()) {\r
+ try {\r
+ AnnotationProcessor.preDestroy(this.filter);\r
+ } catch (Exception e) {\r
+ context.getLogger().error("ApplicationFilterConfig.preDestroy", e);\r
+ }\r
+ }\r
}\r
this.filter = null;\r
\r
* @exception InstantiationException if an exception occurs while\r
* instantiating the filter object\r
* @exception ServletException if thrown by the filter's init() method\r
+ * @throws NamingException \r
+ * @throws InvocationTargetException \r
*/\r
void setFilterDef(FilterDef filterDef)\r
throws ClassCastException, ClassNotFoundException,\r
IllegalAccessException, InstantiationException,\r
- ServletException {\r
+ ServletException, InvocationTargetException, NamingException {\r
\r
this.filterDef = filterDef;\r
if (filterDef == null) {\r
\r
// Release any previously allocated filter instance\r
if (this.filter != null){\r
- if( System.getSecurityManager() != null) {\r
+ if( System.getSecurityManager() != null) {\r
try{\r
SecurityUtil.doAsPrivilege("destroy", filter); \r
} catch(java.lang.Exception ex){ \r
} else { \r
filter.destroy();\r
}\r
+ if (!context.getIgnoreAnnotations()) {\r
+ try {\r
+ AnnotationProcessor.preDestroy(this.filter);\r
+ } catch (Exception e) {\r
+ context.getLogger().error("ApplicationFilterConfig.preDestroy", e);\r
+ }\r
+ }\r
}\r
this.filter = null;\r
\r
log.debug( "setName " + name);\r
}\r
\r
+ \r
+ /**\r
+ * Return the env context.\r
+ */\r
+ public javax.naming.Context getEnvContext() {\r
+ return this.envCtx;\r
+ }\r
+ \r
\r
/**\r
* Return the associated naming context.\r
import org.apache.catalina.session.StandardManager;\r
import org.apache.catalina.startup.ContextConfig;\r
import org.apache.catalina.startup.TldConfig;\r
+import org.apache.catalina.util.AnnotationProcessor;\r
import org.apache.catalina.util.CharsetMapper;\r
import org.apache.catalina.util.ExtensionValidator;\r
import org.apache.catalina.util.RequestUtil;\r
try {\r
Class clazz = loader.loadClass(listeners[i]);\r
results[i] = clazz.newInstance();\r
+ // Annotation processing\r
+ if (!getIgnoreAnnotations()) {\r
+ if (getNamingContextListener() != null) {\r
+ AnnotationProcessor.injectNamingResources\r
+ (getNamingContextListener().getEnvContext(), results[i]);\r
+ }\r
+ AnnotationProcessor.postConstruct(results[i]);\r
+ }\r
} catch (Throwable t) {\r
getLogger().error\r
(sm.getString("standardContext.applicationListener",\r
\r
boolean ok = true;\r
Object listeners[] = getApplicationLifecycleListeners();\r
- if (listeners == null)\r
- return (ok);\r
- ServletContextEvent event =\r
- new ServletContextEvent(getServletContext());\r
- for (int i = 0; i < listeners.length; i++) {\r
- int j = (listeners.length - 1) - i;\r
- if (listeners[j] == null)\r
- continue;\r
- if (!(listeners[j] instanceof ServletContextListener))\r
- continue;\r
- ServletContextListener listener =\r
- (ServletContextListener) listeners[j];\r
- try {\r
- fireContainerEvent("beforeContextDestroyed", listener);\r
- listener.contextDestroyed(event);\r
- fireContainerEvent("afterContextDestroyed", listener);\r
- } catch (Throwable t) {\r
- fireContainerEvent("afterContextDestroyed", listener);\r
- getLogger().error\r
- (sm.getString("standardContext.listenerStop",\r
- listeners[j].getClass().getName()), t);\r
- ok = false;\r
+ if (listeners != null) {\r
+ ServletContextEvent event =\r
+ new ServletContextEvent(getServletContext());\r
+ for (int i = 0; i < listeners.length; i++) {\r
+ int j = (listeners.length - 1) - i;\r
+ if (listeners[j] == null)\r
+ continue;\r
+ if (listeners[j] instanceof ServletContextListener) {\r
+ ServletContextListener listener =\r
+ (ServletContextListener) listeners[j];\r
+ try {\r
+ fireContainerEvent("beforeContextDestroyed", listener);\r
+ listener.contextDestroyed(event);\r
+ fireContainerEvent("afterContextDestroyed", listener);\r
+ } catch (Throwable t) {\r
+ fireContainerEvent("afterContextDestroyed", listener);\r
+ getLogger().error\r
+ (sm.getString("standardContext.listenerStop",\r
+ listeners[j].getClass().getName()), t);\r
+ ok = false;\r
+ }\r
+ }\r
+ // Annotation processing\r
+ if (!getIgnoreAnnotations()) {\r
+ try {\r
+ AnnotationProcessor.preDestroy(listeners[j]);\r
+ } catch (Throwable t) {\r
+ getLogger().error\r
+ (sm.getString("standardContext.listenerStop",\r
+ listeners[j].getClass().getName()), t);\r
+ ok = false;\r
+ }\r
+ }\r
}\r
}\r
\r
+ // Annotation processing\r
+ listeners = getApplicationEventListeners();\r
+ if (!getIgnoreAnnotations() && listeners != null) {\r
+ for (int i = 0; i < listeners.length; i++) {\r
+ int j = (listeners.length - 1) - i;\r
+ if (listeners[j] == null)\r
+ continue;\r
+ try {\r
+ AnnotationProcessor.preDestroy(listeners[j]);\r
+ } catch (Throwable t) {\r
+ getLogger().error\r
+ (sm.getString("standardContext.listenerStop",\r
+ listeners[j].getClass().getName()), t);\r
+ ok = false;\r
+ }\r
+ }\r
+ }\r
+ \r
setApplicationEventListeners(null);\r
setApplicationLifecycleListeners(null);\r
\r
return namingContextName;\r
}\r
\r
+ \r
+ /**\r
+ * Naming context listener accessor.\r
+ */\r
+ public NamingContextListener getNamingContextListener() {\r
+ return namingContextListener;\r
+ }\r
+ \r
\r
/**\r
* Return the request processing paused flag for this Context.\r
import org.apache.catalina.Loader;\r
import org.apache.catalina.Wrapper;\r
import org.apache.catalina.security.SecurityUtil;\r
+import org.apache.catalina.util.AnnotationProcessor;\r
import org.apache.catalina.util.Enumerator;\r
import org.apache.catalina.util.InstanceSupport;\r
import org.apache.tomcat.util.IntrospectionUtils;\r
// Instantiate and initialize an instance of the servlet class itself\r
try {\r
servlet = (Servlet) classClass.newInstance();\r
+ // Annotation processing\r
+ if (!((Context) getParent()).getIgnoreAnnotations()) {\r
+ if (getParent() instanceof StandardContext \r
+ && ((StandardContext) getParent()).getNamingContextListener() != null) {\r
+ AnnotationProcessor.injectNamingResources\r
+ (((StandardContext) getParent()).getNamingContextListener().getEnvContext(), servlet);\r
+ }\r
+ AnnotationProcessor.postConstruct(servlet);\r
+ }\r
} catch (ClassCastException e) {\r
unavailable(null);\r
// Restore the context ClassLoader\r
} else {\r
instance.destroy();\r
}\r
-\r
+ \r
instanceSupport.fireInstanceEvent\r
(InstanceEvent.AFTER_DESTROY_EVENT, instance);\r
+\r
+ // Annotation processing\r
+ if (!((Context) getParent()).getIgnoreAnnotations()) {\r
+ AnnotationProcessor.preDestroy(instance);\r
+ }\r
+\r
} catch (Throwable t) {\r
instanceSupport.fireInstanceEvent\r
(InstanceEvent.AFTER_DESTROY_EVENT, instance, t);\r
try {\r
Thread.currentThread().setContextClassLoader(classLoader);\r
while (!instancePool.isEmpty()) {\r
- if( System.getSecurityManager() != null) {\r
- SecurityUtil.doAsPrivilege("destroy",\r
- ((Servlet) instancePool.pop()));\r
+ Servlet s = (Servlet) instancePool.pop();\r
+ if (System.getSecurityManager() != null) {\r
+ SecurityUtil.doAsPrivilege("destroy", s);\r
SecurityUtil.remove(instance); \r
} else {\r
- ((Servlet) instancePool.pop()).destroy();\r
+ s.destroy();\r
+ }\r
+ // Annotation processing\r
+ if (!((Context) getParent()).getIgnoreAnnotations()) {\r
+ AnnotationProcessor.preDestroy(s);\r
}\r
}\r
} catch (Throwable t) {\r
--- /dev/null
+/*\r
+ * Copyright 1999,2004 The Apache Software Foundation.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.apache.catalina.util;\r
+\r
+import java.lang.reflect.Field;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
+import java.lang.reflect.Modifier;\r
+\r
+import javax.annotation.PostConstruct;\r
+import javax.annotation.Resource;\r
+import javax.naming.NamingException;\r
+\r
+import org.apache.tomcat.util.IntrospectionUtils;\r
+\r
+\r
+/**\r
+ * Verify the annotation and Process it.\r
+ *\r
+ * @author Fabien Carrion\r
+ * @version $Revision: 303236 $, $Date: 2006-03-09 16:46:52 -0600 (Thu, 09 Mar 2006) $\r
+ */\r
+public class AnnotationProcessor {\r
+ \r
+\r
+ /**\r
+ * Call postConstruct method on the specified instance.\r
+ */\r
+ public static void postConstruct(Object instance)\r
+ throws IllegalAccessException, InvocationTargetException {\r
+ \r
+ Method[] methods = IntrospectionUtils.findMethods(instance.getClass());\r
+ Method postConstruct = null;\r
+ for (int i = 0; i < methods.length; i++) {\r
+ if (methods[i].isAnnotationPresent(PostConstruct.class)) {\r
+ if ((postConstruct != null) \r
+ || (methods[i].getParameterTypes().length != 0)\r
+ || (Modifier.isStatic(methods[i].getModifiers())) \r
+ || (methods[i].getExceptionTypes().length > 0)\r
+ || (!methods[i].getReturnType().getName().equals("void"))) {\r
+ throw new IllegalArgumentException("Invalid PostConstruct annotation");\r
+ }\r
+ postConstruct = methods[i];\r
+ }\r
+ }\r
+\r
+ // At the end the postconstruct annotated \r
+ // method is invoked\r
+ if (postConstruct != null) {\r
+ boolean accessibility = postConstruct.isAccessible();\r
+ postConstruct.setAccessible(true);\r
+ postConstruct.invoke(instance);\r
+ postConstruct.setAccessible(accessibility);\r
+ }\r
+ \r
+ }\r
+ \r
+ \r
+ /**\r
+ * Call preDestroy method on the specified instance.\r
+ */\r
+ public static void preDestroy(Object instance)\r
+ throws IllegalAccessException, InvocationTargetException {\r
+ \r
+ Method[] methods = IntrospectionUtils.findMethods(instance.getClass());\r
+ Method preDestroy = null;\r
+ for (int i = 0; i < methods.length; i++) {\r
+ if (methods[i].isAnnotationPresent(PostConstruct.class)) {\r
+ if ((preDestroy != null) \r
+ || (methods[i].getParameterTypes().length != 0)\r
+ || (Modifier.isStatic(methods[i].getModifiers())) \r
+ || (methods[i].getExceptionTypes().length > 0)\r
+ || (!methods[i].getReturnType().getName().equals("void"))) {\r
+ throw new IllegalArgumentException("Invalid PreDestroy annotation");\r
+ }\r
+ preDestroy = methods[i];\r
+ }\r
+ }\r
+\r
+ // At the end the postconstruct annotated \r
+ // method is invoked\r
+ if (preDestroy != null) {\r
+ boolean accessibility = preDestroy.isAccessible();\r
+ preDestroy.setAccessible(true);\r
+ preDestroy.invoke(instance);\r
+ preDestroy.setAccessible(accessibility);\r
+ }\r
+ \r
+ }\r
+ \r
+ \r
+ /**\r
+ * Inject resources in specified instance.\r
+ */\r
+ public static void injectNamingResources(javax.naming.Context context, Object instance)\r
+ throws IllegalAccessException, InvocationTargetException, NamingException {\r
+ \r
+ // Initialize fields annotations\r
+ Field[] fields = instance.getClass().getFields();\r
+ for (int i = 0; i < fields.length; i++) {\r
+ if (fields[i].isAnnotationPresent(Resource.class)) {\r
+ Resource annotation = (Resource) fields[i].getAnnotation(Resource.class);\r
+ lookupFieldResource(context, instance, fields[i], annotation.name());\r
+ }\r
+ /*\r
+ if (f.isAnnotationPresent(EJB.class)) {\r
+ EJB annotation = (EJB) f.getAnnotation(EJB.class);\r
+ lookupOnFieldResource(f, annotation.name());\r
+ }\r
+ \r
+ if (f.isAnnotationPresent(WebServiceRef.class)) {\r
+ WebServiceRef annotation = (WebServiceRef) \r
+ f.getAnnotation(WebServiceRef.class);\r
+ lookupOnFieldResource(f, annotation.name());\r
+ }\r
+ */\r
+ }\r
+ \r
+ // Initialize methods annotations\r
+ Method[] methods = IntrospectionUtils.findMethods(instance.getClass());\r
+ for (int i = 0; i < methods.length; i++) {\r
+ if (methods[i].isAnnotationPresent(Resource.class)) {\r
+ Resource annotation = (Resource) methods[i].getAnnotation(Resource.class);\r
+ lookupMethodResource(context, instance, methods[i], annotation.name());\r
+ }\r
+ /*\r
+ if (m.isAnnotationPresent(EJB.class)) {\r
+ EJB annotation = (EJB) m.getAnnotation(EJB.class);\r
+ lookupOnMethodResource(m, annotation.name());\r
+ }\r
+ if (m.isAnnotationPresent(WebServiceRef.class)) {\r
+ WebServiceRef annotation = (WebServiceRef) \r
+ m.getAnnotation(WebServiceRef.class);\r
+ lookupOnMethodResource(m, annotation.name());\r
+ }\r
+ */\r
+ } \r
+\r
+ }\r
+ \r
+ \r
+ protected static void lookupFieldResource(javax.naming.Context context, \r
+ Object instance, Field f, String name)\r
+ throws NamingException, IllegalAccessException {\r
+ \r
+ Object lookedupResource = null;\r
+ boolean accessibility = false;\r
+ \r
+ if ((name != null) &&\r
+ (name.length() > 0)) {\r
+ lookedupResource = context.lookup(name);\r
+ } else {\r
+ lookedupResource = context.lookup(instance.getClass().getName() + "/" + f.getName());\r
+ }\r
+ \r
+ accessibility = f.isAccessible();\r
+ f.setAccessible(true);\r
+ f.set(instance, lookedupResource);\r
+ f.setAccessible(accessibility);\r
+ }\r
+\r
+\r
+ protected static void lookupMethodResource(javax.naming.Context context, \r
+ Object instance, Method method, String name)\r
+ throws NamingException, IllegalAccessException, InvocationTargetException {\r
+ \r
+ if (!method.getName().startsWith("set") \r
+ || method.getParameterTypes().length != 1\r
+ || !method.getReturnType().getName().equals("void")) {\r
+ throw new IllegalArgumentException("Invalid method resource injection annotation");\r
+ }\r
+ \r
+ Object lookedupResource = null;\r
+ boolean accessibility = false;\r
+ \r
+ if ((name != null) &&\r
+ (name.length() > 0)) {\r
+ lookedupResource = context.lookup(name);\r
+ } else {\r
+ lookedupResource = \r
+ context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3));\r
+ }\r
+ \r
+ accessibility = method.isAccessible();\r
+ method.setAccessible(true);\r
+ method.invoke(instance, lookedupResource);\r
+ method.setAccessible(accessibility);\r
+ }\r
+ \r
+\r
+}\r