From: remm Date: Thu, 6 Apr 2006 23:47:05 +0000 (+0000) Subject: - Add web.xml style annotations (run as, roles declarations, etc). X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=30921ecd6d207d8bcf94a088e669b85cd5beb30a;p=tomcat7.0 - Add web.xml style annotations (run as, roles declarations, etc). - Note: commented out EJB and web services (similarly, the Persistence* annotations were not there). - Submitted by Fabien Carrion. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@392123 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/startup/ContextConfig.java b/java/org/apache/catalina/startup/ContextConfig.java index 676898cce..c43fc89bf 100644 --- a/java/org/apache/catalina/startup/ContextConfig.java +++ b/java/org/apache/catalina/startup/ContextConfig.java @@ -75,7 +75,7 @@ public class ContextConfig // ----------------------------------------------------- Instance Variables - /* + /** * Custom mappings of login methods to authenticators */ protected Map customAuthenticators; @@ -287,6 +287,23 @@ public class ContextConfig /** + * Process the application classes annotations, if it exists. + */ + protected void applicationAnnotationsConfig() { + + long t1=System.currentTimeMillis(); + + WebAnnotationSet.loadApplicationAnnotations(context); + + long t2=System.currentTimeMillis(); + if (context instanceof StandardContext) { + ((StandardContext) context).setStartupTime(t2-t1+ + ((StandardContext) context).getStartupTime()); + } + } + + + /** * Process the application configuration file, if it exists. */ protected void applicationWebConfig() { @@ -1032,6 +1049,9 @@ public class ContextConfig // Process the default and application web.xml files defaultWebConfig(); applicationWebConfig(); + if (!context.getIgnoreAnnotations()) { + applicationAnnotationsConfig(); + } if (ok) { validateSecurityRoles(); } diff --git a/java/org/apache/catalina/startup/WebAnnotationSet.java b/java/org/apache/catalina/startup/WebAnnotationSet.java new file mode 100644 index 000000000..8ed63de74 --- /dev/null +++ b/java/org/apache/catalina/startup/WebAnnotationSet.java @@ -0,0 +1,368 @@ +/* + * 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.startup; + + +import javax.annotation.Resource; +import javax.annotation.Resources; +import javax.annotation.security.DeclaresRoles; +import javax.annotation.security.RunAs; + +import org.apache.catalina.Container; +import org.apache.catalina.Context; +import org.apache.catalina.core.StandardWrapper; +import org.apache.catalina.deploy.ContextEnvironment; +import org.apache.catalina.deploy.ContextResource; +import org.apache.catalina.deploy.ContextResourceEnvRef; +import org.apache.catalina.deploy.ContextService; +import org.apache.catalina.deploy.FilterDef; +import org.apache.catalina.deploy.MessageDestinationRef; + +//import javax.ejb.EJB; +//import javax.xml.ws.WebServiceRef; + +/** + *

AnnotationSet for processing the annotations of the web application + * classes (/WEB-INF/classes and /WEB-INF/lib).

+ * + * @author Fabien Carrion + * @version $Revision: 304108 $ $Date: 2006-03-01 10:39:15 -0700 (Wed, 03 Mar 2006) $ + */ + +public class WebAnnotationSet { + + + // --------------------------------------------------------- Public Methods + + + /** + * Process the annotations on a context. + */ + public static void loadApplicationAnnotations(Context context) { + + loadApplicationListenerAnnotations(context); + loadApplicationFilterAnnotations(context); + loadApplicationServletAnnotations(context); + + + } + + + // -------------------------------------------------------- protected Methods + + + /** + * Process the annotations for the listeners. + */ + protected static void loadApplicationListenerAnnotations(Context context) { + String[] applicationListeners = context.findApplicationListeners(); + for (int i = 0; i < applicationListeners.length; i++) { + loadClassAnnotation(context, applicationListeners[i]); + } + } + + + /** + * Process the annotations for the filters. + */ + protected static void loadApplicationFilterAnnotations(Context context) { + FilterDef[] filterDefs = context.findFilterDefs(); + for (int i = 0; i < filterDefs.length; i++) { + loadClassAnnotation(context, (filterDefs[i]).getFilterClass()); + } + } + + + /** + * Process the annotations for the servlets. + */ + protected static void loadApplicationServletAnnotations(Context context) { + + ClassLoader classLoader = context.getLoader().getClassLoader(); + StandardWrapper wrapper = null; + Class classClass = null; + + Container[] children = context.findChildren(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof StandardWrapper) { + + wrapper = (StandardWrapper) children[i]; + try { + classClass = classLoader.loadClass(wrapper.getServletClass()); + } catch (ClassNotFoundException e) { + // We do nothing + } catch (NoClassDefFoundError e) { + // We do nothing + } + + if (classClass == null) { + continue; + } + + loadClassAnnotation(context, wrapper.getServletClass()); + /* Process RunAs annotation which can be only on servlets. + * Ref JSR 250, equivalent to the run-as element in + * the deployment descriptor + */ + if (classClass.isAnnotationPresent(RunAs.class)) { + RunAs annotation = (RunAs) + classClass.getAnnotation(RunAs.class); + wrapper.setRunAs(annotation.value()); + } + } + } + + + } + + + /** + * Process the annotations on a context for a given className. + */ + protected static void loadClassAnnotation(Context context, String fileString) { + + ClassLoader classLoader = context.getLoader().getClassLoader(); + Class classClass = null; + + try { + classClass = classLoader.loadClass(fileString); + } catch (ClassNotFoundException e) { + // We do nothing + } catch (NoClassDefFoundError e) { + // We do nothing + } + + if (classClass == null) { + return; + } + + // Initialize the annotations + + if (classClass.isAnnotationPresent(Resource.class)) { + Resource annotation = (Resource) + classClass.getAnnotation(Resource.class); + addResource(context, annotation); + } + /* Process Resources annotation. + * Ref JSR 250 + */ + if (classClass.isAnnotationPresent(Resources.class)) { + Resources annotation = (Resources) + classClass.getAnnotation(Resources.class); + for (int i = 0; annotation.value() != null && i < annotation.value().length; i++) { + addResource(context, annotation.value()[i]); + } + } + /* Process EJB annotation. + * Ref JSR 224, equivalent to the ejb-ref or ejb-local-ref + * element in the deployment descriptor. + if (classClass.isAnnotationPresent(EJB.class)) { + EJB annotation = (EJB) + classClass.getAnnotation(EJB.class); + + if ((annotation.mappedName().length() == 0) || + annotation.mappedName().equals("Local")) { + + ContextLocalEjb ejb = new ContextLocalEjb(); + + ejb.setName(annotation.name()); + ejb.setType(annotation.beanInterface().getCanonicalName()); + ejb.setDescription(annotation.description()); + + ejb.setHome(annotation.beanName()); + + context.getNamingResources().addLocalEjb(ejb); + + } else if (annotation.mappedName().equals("Remote")) { + + ContextEjb ejb = new ContextEjb(); + + ejb.setName(annotation.name()); + ejb.setType(annotation.beanInterface().getCanonicalName()); + ejb.setDescription(annotation.description()); + + ejb.setHome(annotation.beanName()); + + context.getNamingResources().addEjb(ejb); + + } + + } + */ + /* Process WebServiceRef annotation. + * Ref JSR 224, equivalent to the service-ref element in + * the deployment descriptor. + * The service-ref registration is not implemented + if (classClass.isAnnotationPresent(WebServiceRef.class)) { + WebServiceRef annotation = (WebServiceRef) + classClass.getAnnotation(WebServiceRef.class); + + ContextService service = new ContextService(); + + service.setName(annotation.name()); + service.setWsdlfile(annotation.wsdlLocation()); + + service.setType(annotation.type().getCanonicalName()); + + if (annotation.value() == null) + service.setServiceinterface(annotation.type().getCanonicalName()); + + if (annotation.type().getCanonicalName().equals("Service")) + service.setServiceinterface(annotation.type().getCanonicalName()); + + if (annotation.value().getCanonicalName().equals("Endpoint")) + service.setServiceendpoint(annotation.type().getCanonicalName()); + + service.setPortlink(annotation.type().getCanonicalName()); + + context.getNamingResources().addService(service); + + + } + */ + /* Process DeclareRoles annotation. + * Ref JSR 250, equivalent to the security-role element in + * the deployment descriptor + */ + if (classClass.isAnnotationPresent(DeclaresRoles.class)) { + DeclaresRoles annotation = (DeclaresRoles) + classClass.getAnnotation(DeclaresRoles.class); + for (int i = 0; annotation.value() != null && i < annotation.value().length; i++) { + context.addSecurityRole(annotation.value()[i]); + } + } + + + } + + + /** + * Process a Resource annotation to set up a Resource. + * Ref JSR 250, equivalent to the resource-ref, + * message-destination-ref, env-ref, resource-env-ref + * or service-ref element in the deployment descriptor. + */ + protected static void addResource(Context context, Resource annotation) { + + if (annotation.type().getCanonicalName().equals("java.lang.String") || + annotation.type().getCanonicalName().equals("java.lang.Character") || + annotation.type().getCanonicalName().equals("java.lang.Integer") || + annotation.type().getCanonicalName().equals("java.lang.Boolean") || + annotation.type().getCanonicalName().equals("java.lang.Double") || + annotation.type().getCanonicalName().equals("java.lang.Byte") || + annotation.type().getCanonicalName().equals("java.lang.Short") || + annotation.type().getCanonicalName().equals("java.lang.Long") || + annotation.type().getCanonicalName().equals("java.lang.Float")) { + + // env-ref element + ContextEnvironment resource = new ContextEnvironment(); + + resource.setName(annotation.name()); + resource.setType(annotation.type().getCanonicalName()); + + resource.setDescription(annotation.description()); + + resource.setValue(annotation.mappedName()); + + context.getNamingResources().addEnvironment(resource); + + } else if (annotation.type().getCanonicalName().equals("javax.xml.rpc.Service")) { + + // service-ref element + ContextService service = new ContextService(); + + service.setName(annotation.name()); + service.setWsdlfile(annotation.mappedName()); + + service.setType(annotation.type().getCanonicalName()); + service.setDescription(annotation.description()); + + context.getNamingResources().addService(service); + + } else if (annotation.type().getCanonicalName().equals("javax.sql.DataSource") || + annotation.type().getCanonicalName().equals("javax.jms.ConnectionFactory") || + annotation.type().getCanonicalName() + .equals("javax.jms.QueueConnectionFactory") || + annotation.type().getCanonicalName() + .equals("javax.jms.TopicConnectionFactory") || + annotation.type().getCanonicalName().equals("javax.mail.Session") || + annotation.type().getCanonicalName().equals("java.net.URL") || + annotation.type().getCanonicalName() + .equals("javax.resource.cci.ConnectionFactory") || + annotation.type().getCanonicalName().equals("org.omg.CORBA_2_3.ORB") || + annotation.type().getCanonicalName().endsWith("ConnectionFactory")) { + + // resource-ref element + ContextResource resource = new ContextResource(); + + resource.setName(annotation.name()); + resource.setType(annotation.type().getCanonicalName()); + + if (annotation.authenticationType() + == Resource.AuthenticationType.CONTAINER) { + resource.setAuth("Container"); + } + else if (annotation.authenticationType() + == Resource.AuthenticationType.APPLICATION) { + resource.setAuth("Application"); + } + + resource.setScope(annotation.shareable() ? "Shareable" : "Unshareable"); + resource.setProperty("mappedName", annotation.mappedName()); + resource.setDescription(annotation.description()); + + context.getNamingResources().addResource(resource); + + } else if (annotation.type().getCanonicalName().equals("javax.jms.Queue") || + annotation.type().getCanonicalName().equals("javax.jms.Topic")) { + + // message-destination-ref + MessageDestinationRef resource = new MessageDestinationRef(); + + resource.setName(annotation.name()); + resource.setType(annotation.type().getCanonicalName()); + + resource.setUsage(annotation.mappedName()); + resource.setDescription(annotation.description()); + + context.getNamingResources().addMessageDestinationRef(resource); + + } else if (annotation.type().getCanonicalName() + .equals("javax.resource.cci.InteractionSpec") || + annotation.type().getCanonicalName() + .equals("javax.transaction.UserTransaction") || + true) { + + // resource-env-ref + ContextResourceEnvRef resource = new ContextResourceEnvRef(); + + resource.setName(annotation.name()); + resource.setType(annotation.type().getCanonicalName()); + + resource.setProperty("mappedName", annotation.mappedName()); + resource.setDescription(annotation.description()); + + context.getNamingResources().addResourceEnvRef(resource); + + } + + + } + + +}