Author: remm Date: Wed Aug 2 04:21:46 2006 New Revision: 427955 URL: http://svn.apache.org/viewvc?rev=427955&view=rev Log: - Now use an interface and a pluggable mechanism for annotation processing. - I'm using the org.apache package due to the need to use this stuff in Jasper ...
Added: tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java (with props) tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java (with props) Removed: tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/AnnotationProcessor.java Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml Added: tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java?rev=427955&view=auto ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java (added) +++ tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java Wed Aug 2 04:21:46 2006 @@ -0,0 +1,36 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache; + +import java.lang.reflect.InvocationTargetException; + +import javax.naming.NamingException; + +/** + * Comment + * + * @author <a href="mailto:[EMAIL PROTECTED]">Bill Burke</a> + * @version $Revision: 1.17 $ + */ +public interface AnnotationProcessor { + public void postConstruct(Object instance) + throws IllegalAccessException, InvocationTargetException; + public void preDestroy(Object instance) + throws IllegalAccessException, InvocationTargetException; + public void processAnnotations(Object instance) + throws IllegalAccessException, InvocationTargetException, NamingException; +} Propchange: tomcat/tc6.0.x/trunk/java/org/apache/AnnotationProcessor.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java?rev=427955&r1=427954&r2=427955&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java Wed Aug 2 04:21:46 2006 @@ -88,6 +88,14 @@ /** + * The servlet context attribute under which we store the annotation + * processor that is used by the JSP engine. + */ + public static final String ANNOTATION_PROCESSOR_ATTR = + "org.apache.catalina.annotation_processor"; + + + /** * The request attribute under which we forward a Java exception * (as an object of type Throwable) to an error page. */ Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java?rev=427955&r1=427954&r2=427955&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java Wed Aug 2 04:21:46 2006 @@ -30,10 +30,10 @@ import javax.servlet.ServletContext; import javax.servlet.ServletException; +import org.apache.AnnotationProcessor; import org.apache.catalina.Context; import org.apache.catalina.deploy.FilterDef; import org.apache.catalina.security.SecurityUtil; -import org.apache.catalina.util.AnnotationProcessor; import org.apache.catalina.util.Enumerator; import org.apache.tomcat.util.log.SystemLogHandler; @@ -217,12 +217,11 @@ Class clazz = classLoader.loadClass(filterClass); this.filter = (Filter) clazz.newInstance(); if (!context.getIgnoreAnnotations()) { - if (context instanceof StandardContext - && ((StandardContext) context).getNamingContextListener() != null) { - AnnotationProcessor.injectNamingResources - (((StandardContext) context).getNamingContextListener().getEnvContext(), this.filter); + if (context instanceof StandardContext) { + AnnotationProcessor processor = ((StandardContext)context).getAnnotationProcessor(); + processor.processAnnotations(this.filter); + processor.postConstruct(this.filter); } - AnnotationProcessor.postConstruct(this.filter); } if (context instanceof StandardContext && ((StandardContext) context).getSwallowOutput()) { @@ -240,6 +239,7 @@ } return (this.filter); + } @@ -259,7 +259,8 @@ */ void release() { - if (this.filter != null){ + if (this.filter != null) + { if (System.getSecurityManager() != null) { try { SecurityUtil.doAsPrivilege("destroy", filter); @@ -272,7 +273,7 @@ } if (!context.getIgnoreAnnotations()) { try { - AnnotationProcessor.preDestroy(this.filter); + ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter); } catch (Exception e) { context.getLogger().error("ApplicationFilterConfig.preDestroy", e); } @@ -322,7 +323,7 @@ } if (!context.getIgnoreAnnotations()) { try { - AnnotationProcessor.preDestroy(this.filter); + ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter); } catch (Exception e) { context.getLogger().error("ApplicationFilterConfig.preDestroy", e); } Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?rev=427955&r1=427954&r2=427955&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Wed Aug 2 04:21:46 2006 @@ -33,7 +33,6 @@ import java.util.Stack; import java.util.TreeMap; -import javax.management.AttributeNotFoundException; import javax.management.ListenerNotFoundException; import javax.management.MBeanNotificationInfo; import javax.management.MBeanRegistrationException; @@ -58,6 +57,7 @@ import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionListener; +import org.apache.AnnotationProcessor; import org.apache.catalina.Container; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; @@ -85,8 +85,8 @@ import org.apache.catalina.session.StandardManager; import org.apache.catalina.startup.ContextConfig; import org.apache.catalina.startup.TldConfig; -import org.apache.catalina.util.AnnotationProcessor; import org.apache.catalina.util.CharsetMapper; +import org.apache.catalina.util.DefaultAnnotationProcessor; import org.apache.catalina.util.ExtensionValidator; import org.apache.catalina.util.RequestUtil; import org.apache.catalina.util.URLEncoder; @@ -172,6 +172,12 @@ /** + * Annotation processor. + */ + private AnnotationProcessor annotationProcessor = null; + + + /** * Associated host name. */ private String hostName; @@ -671,6 +677,16 @@ // ----------------------------------------------------- Context Properties + public AnnotationProcessor getAnnotationProcessor() { + return annotationProcessor; + } + + + public void setAnnotationProcessor(AnnotationProcessor annotationProcessor) { + this.annotationProcessor = annotationProcessor; + } + + public String getEncodedPath() { return encodedPath; } @@ -3735,11 +3751,8 @@ results[i] = clazz.newInstance(); // Annotation processing if (!getIgnoreAnnotations()) { - if (getNamingContextListener() != null) { - AnnotationProcessor.injectNamingResources - (getNamingContextListener().getEnvContext(), results[i]); - } - AnnotationProcessor.postConstruct(results[i]); + getAnnotationProcessor().processAnnotations(results[i]); + getAnnotationProcessor().postConstruct(results[i]); } } catch (Throwable t) { getLogger().error @@ -3843,7 +3856,7 @@ // Annotation processing if (!getIgnoreAnnotations()) { try { - AnnotationProcessor.preDestroy(listeners[j]); + getAnnotationProcessor().preDestroy(listeners[j]); } catch (Throwable t) { getLogger().error (sm.getString("standardContext.listenerStop", @@ -3862,7 +3875,7 @@ if (listeners[j] == null) continue; try { - AnnotationProcessor.preDestroy(listeners[j]); + getAnnotationProcessor().preDestroy(listeners[j]); } catch (Throwable t) { getLogger().error (sm.getString("standardContext.listenerStop", @@ -4153,6 +4166,18 @@ addLifecycleListener(namingContextListener); } } + + // Initialize annotation processor + if (ok && !getIgnoreAnnotations() && annotationProcessor == null) { + if (isUseNaming() && namingContextListener != null) { + annotationProcessor = + new DefaultAnnotationProcessor(namingContextListener.getEnvContext()); + } else { + annotationProcessor = new DefaultAnnotationProcessor(null); + } + } + getServletContext().setAttribute + (Globals.ANNOTATION_PROCESSOR_ATTR, annotationProcessor); // Standard container startup if (log.isDebugEnabled()) Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java?rev=427955&r1=427954&r2=427955&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java Wed Aug 2 04:21:46 2006 @@ -56,7 +56,6 @@ import org.apache.catalina.Loader; import org.apache.catalina.Wrapper; import org.apache.catalina.security.SecurityUtil; -import org.apache.catalina.util.AnnotationProcessor; import org.apache.catalina.util.Enumerator; import org.apache.catalina.util.InstanceSupport; import org.apache.tomcat.util.IntrospectionUtils; @@ -1082,12 +1081,10 @@ servlet = (Servlet) classClass.newInstance(); // Annotation processing if (!((Context) getParent()).getIgnoreAnnotations()) { - if (getParent() instanceof StandardContext - && ((StandardContext) getParent()).getNamingContextListener() != null) { - AnnotationProcessor.injectNamingResources - (((StandardContext) getParent()).getNamingContextListener().getEnvContext(), servlet); + if (getParent() instanceof StandardContext) { + ((StandardContext)getParent()).getAnnotationProcessor().processAnnotations(servlet); + ((StandardContext)getParent()).getAnnotationProcessor().postConstruct(servlet); } - AnnotationProcessor.postConstruct(servlet); } } catch (ClassCastException e) { unavailable(null); @@ -1367,7 +1364,7 @@ // Annotation processing if (!((Context) getParent()).getIgnoreAnnotations()) { - AnnotationProcessor.preDestroy(instance); + ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(instance); } } catch (Throwable t) { @@ -1410,7 +1407,7 @@ } // Annotation processing if (!((Context) getParent()).getIgnoreAnnotations()) { - AnnotationProcessor.preDestroy(s); + ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(s); } } } catch (Throwable t) { Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml?rev=427955&r1=427954&r2=427955&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml Wed Aug 2 04:21:46 2006 @@ -25,6 +25,10 @@ is="true" type="boolean"/> + <attribute name="annotationProcessor" + description="Object that processes things like injection annotations" + type="org.apache.AnnotationProcessor" /> + <attribute name="antiJARLocking" description="Take care to not lock jar files" type="boolean" /> @@ -133,10 +137,6 @@ description="Name of the object" type="java.lang.String"/> - <attribute name="originalDocBase" - description="The original document root for this web application" - type="java.lang.String"/> - <attribute name="override" description="The DefaultContext override flag for this web application" type="boolean"/> Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java?rev=427955&view=auto ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java (added) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java Wed Aug 2 04:21:46 2006 @@ -0,0 +1,243 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.catalina.util; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.naming.NamingException; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceUnit; +import javax.xml.ws.WebServiceRef; + +import org.apache.AnnotationProcessor; + + +/** + * Verify the annotation and Process it. + * + * @author Fabien Carrion + * @author Remy Maucherat + * @version $Revision: 303236 $, $Date: 2006-03-09 16:46:52 -0600 (Thu, 09 Mar 2006) $ + */ +public class DefaultAnnotationProcessor implements AnnotationProcessor { + + protected javax.naming.Context context = null; + + public DefaultAnnotationProcessor(javax.naming.Context context) { + this.context = context; + } + + + /** + * Call postConstruct method on the specified instance. + */ + public void postConstruct(Object instance) + throws IllegalAccessException, InvocationTargetException { + + Method[] methods = instance.getClass().getDeclaredMethods(); + Method postConstruct = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(PostConstruct.class)) { + if ((postConstruct != null) + || (methods[i].getParameterTypes().length != 0) + || (Modifier.isStatic(methods[i].getModifiers())) + || (methods[i].getExceptionTypes().length > 0) + || (!methods[i].getReturnType().getName().equals("void"))) { + throw new IllegalArgumentException("Invalid PostConstruct annotation"); + } + postConstruct = methods[i]; + } + } + + // At the end the postconstruct annotated + // method is invoked + if (postConstruct != null) { + boolean accessibility = postConstruct.isAccessible(); + postConstruct.setAccessible(true); + postConstruct.invoke(instance); + postConstruct.setAccessible(accessibility); + } + + } + + + /** + * Call preDestroy method on the specified instance. + */ + public void preDestroy(Object instance) + throws IllegalAccessException, InvocationTargetException { + + Method[] methods = instance.getClass().getDeclaredMethods(); + Method preDestroy = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(PreDestroy.class)) { + if ((preDestroy != null) + || (methods[i].getParameterTypes().length != 0) + || (Modifier.isStatic(methods[i].getModifiers())) + || (methods[i].getExceptionTypes().length > 0) + || (!methods[i].getReturnType().getName().equals("void"))) { + throw new IllegalArgumentException("Invalid PreDestroy annotation"); + } + preDestroy = methods[i]; + } + } + + // At the end the postconstruct annotated + // method is invoked + if (preDestroy != null) { + boolean accessibility = preDestroy.isAccessible(); + preDestroy.setAccessible(true); + preDestroy.invoke(instance); + preDestroy.setAccessible(accessibility); + } + + } + + + /** + * Inject resources in specified instance. + */ + public void processAnnotations(Object instance) + throws IllegalAccessException, InvocationTargetException, NamingException { + + if (context == null) { + // No resource injection + return; + } + + // Initialize fields annotations + Field[] fields = instance.getClass().getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].isAnnotationPresent(Resource.class)) { + Resource annotation = (Resource) fields[i].getAnnotation(Resource.class); + lookupFieldResource(context, instance, fields[i], annotation.name()); + } + if (fields[i].isAnnotationPresent(EJB.class)) { + EJB annotation = (EJB) fields[i].getAnnotation(EJB.class); + lookupFieldResource(context, instance, fields[i], annotation.name()); + } + if (fields[i].isAnnotationPresent(WebServiceRef.class)) { + WebServiceRef annotation = + (WebServiceRef) fields[i].getAnnotation(WebServiceRef.class); + lookupFieldResource(context, instance, fields[i], annotation.name()); + } + if (fields[i].isAnnotationPresent(PersistenceContext.class)) { + PersistenceContext annotation = + (PersistenceContext) fields[i].getAnnotation(PersistenceContext.class); + lookupFieldResource(context, instance, fields[i], annotation.name()); + } + if (fields[i].isAnnotationPresent(PersistenceUnit.class)) { + PersistenceUnit annotation = + (PersistenceUnit) fields[i].getAnnotation(PersistenceUnit.class); + lookupFieldResource(context, instance, fields[i], annotation.name()); + } + } + + // Initialize methods annotations + Method[] methods = instance.getClass().getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(Resource.class)) { + Resource annotation = (Resource) methods[i].getAnnotation(Resource.class); + lookupMethodResource(context, instance, methods[i], annotation.name()); + } + if (methods[i].isAnnotationPresent(EJB.class)) { + EJB annotation = (EJB) methods[i].getAnnotation(EJB.class); + lookupMethodResource(context, instance, methods[i], annotation.name()); + } + if (methods[i].isAnnotationPresent(WebServiceRef.class)) { + WebServiceRef annotation = + (WebServiceRef) methods[i].getAnnotation(WebServiceRef.class); + lookupMethodResource(context, instance, methods[i], annotation.name()); + } + if (methods[i].isAnnotationPresent(PersistenceContext.class)) { + PersistenceContext annotation = + (PersistenceContext) methods[i].getAnnotation(PersistenceContext.class); + lookupMethodResource(context, instance, methods[i], annotation.name()); + } + if (methods[i].isAnnotationPresent(PersistenceUnit.class)) { + PersistenceUnit annotation = + (PersistenceUnit) methods[i].getAnnotation(PersistenceUnit.class); + lookupMethodResource(context, instance, methods[i], annotation.name()); + } + } + + } + + + /** + * Inject resources in specified field. + */ + protected static void lookupFieldResource(javax.naming.Context context, + Object instance, Field field, String name) + throws NamingException, IllegalAccessException { + + Object lookedupResource = null; + boolean accessibility = false; + + if ((name != null) && + (name.length() > 0)) { + lookedupResource = context.lookup(name); + } else { + lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName()); + } + + accessibility = field.isAccessible(); + field.setAccessible(true); + field.set(instance, lookedupResource); + field.setAccessible(accessibility); + } + + + /** + * Inject resources in specified method. + */ + protected static void lookupMethodResource(javax.naming.Context context, + Object instance, Method method, String name) + throws NamingException, IllegalAccessException, InvocationTargetException { + + if (!method.getName().startsWith("set") + || method.getParameterTypes().length != 1 + || !method.getReturnType().getName().equals("void")) { + throw new IllegalArgumentException("Invalid method resource injection annotation"); + } + + Object lookedupResource = null; + boolean accessibility = false; + + if ((name != null) && + (name.length() > 0)) { + lookedupResource = context.lookup(name); + } else { + lookedupResource = + context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3)); + } + + accessibility = method.isAccessible(); + method.setAccessible(true); + method.invoke(instance, lookedupResource); + method.setAccessible(accessibility); + } + + +} Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/util/DefaultAnnotationProcessor.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]