- Add web.xml style annotations (run as, roles declarations, etc).
authorremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Thu, 6 Apr 2006 23:47:05 +0000 (23:47 +0000)
committerremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Thu, 6 Apr 2006 23:47:05 +0000 (23:47 +0000)
- 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

java/org/apache/catalina/startup/ContextConfig.java
java/org/apache/catalina/startup/WebAnnotationSet.java [new file with mode: 0644]

index 676898c..c43fc89 100644 (file)
@@ -75,7 +75,7 @@ public class ContextConfig
     // ----------------------------------------------------- Instance Variables\r
 \r
 \r
-    /*\r
+    /**\r
      * Custom mappings of login methods to authenticators\r
      */\r
     protected Map customAuthenticators;\r
@@ -287,6 +287,23 @@ public class ContextConfig
 \r
 \r
     /**\r
+     * Process the application classes annotations, if it exists.\r
+     */\r
+    protected void applicationAnnotationsConfig() {\r
+        \r
+        long t1=System.currentTimeMillis();\r
+        \r
+        WebAnnotationSet.loadApplicationAnnotations(context);\r
+        \r
+        long t2=System.currentTimeMillis();\r
+        if (context instanceof StandardContext) {\r
+            ((StandardContext) context).setStartupTime(t2-t1+\r
+                    ((StandardContext) context).getStartupTime());\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
      * Process the application configuration file, if it exists.\r
      */\r
     protected void applicationWebConfig() {\r
@@ -1032,6 +1049,9 @@ public class ContextConfig
         // Process the default and application web.xml files\r
         defaultWebConfig();\r
         applicationWebConfig();\r
+        if (!context.getIgnoreAnnotations()) {\r
+            applicationAnnotationsConfig();\r
+        }\r
         if (ok) {\r
             validateSecurityRoles();\r
         }\r
diff --git a/java/org/apache/catalina/startup/WebAnnotationSet.java b/java/org/apache/catalina/startup/WebAnnotationSet.java
new file mode 100644 (file)
index 0000000..8ed63de
--- /dev/null
@@ -0,0 +1,368 @@
+/*\r
+ * Copyright 2006 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
+\r
+package org.apache.catalina.startup;\r
+\r
+\r
+import javax.annotation.Resource;\r
+import javax.annotation.Resources;\r
+import javax.annotation.security.DeclaresRoles;\r
+import javax.annotation.security.RunAs;\r
+\r
+import org.apache.catalina.Container;\r
+import org.apache.catalina.Context;\r
+import org.apache.catalina.core.StandardWrapper;\r
+import org.apache.catalina.deploy.ContextEnvironment;\r
+import org.apache.catalina.deploy.ContextResource;\r
+import org.apache.catalina.deploy.ContextResourceEnvRef;\r
+import org.apache.catalina.deploy.ContextService;\r
+import org.apache.catalina.deploy.FilterDef;\r
+import org.apache.catalina.deploy.MessageDestinationRef;\r
+\r
+//import javax.ejb.EJB;\r
+//import javax.xml.ws.WebServiceRef;\r
+\r
+/**\r
+ * <p><strong>AnnotationSet</strong> for processing the annotations of the web application\r
+ * classes (<code>/WEB-INF/classes</code> and <code>/WEB-INF/lib</code>).</p>\r
+ *\r
+ * @author Fabien Carrion\r
+ * @version $Revision: 304108 $ $Date: 2006-03-01 10:39:15 -0700 (Wed, 03 Mar 2006) $\r
+ */\r
+\r
+public class WebAnnotationSet {\r
+    \r
+    \r
+    // --------------------------------------------------------- Public Methods\r
+    \r
+    \r
+    /**\r
+     * Process the annotations on a context.\r
+     */\r
+    public static void loadApplicationAnnotations(Context context) {\r
+        \r
+        loadApplicationListenerAnnotations(context);\r
+        loadApplicationFilterAnnotations(context);\r
+        loadApplicationServletAnnotations(context);\r
+        \r
+        \r
+    }\r
+    \r
+    \r
+    // -------------------------------------------------------- protected Methods\r
+    \r
+    \r
+    /**\r
+     * Process the annotations for the listeners.\r
+     */\r
+    protected static void loadApplicationListenerAnnotations(Context context) {\r
+        String[] applicationListeners = context.findApplicationListeners();\r
+        for (int i = 0; i < applicationListeners.length; i++) {\r
+            loadClassAnnotation(context, applicationListeners[i]);\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Process the annotations for the filters.\r
+     */\r
+    protected static void loadApplicationFilterAnnotations(Context context) {\r
+        FilterDef[] filterDefs = context.findFilterDefs();\r
+        for (int i = 0; i < filterDefs.length; i++) {\r
+            loadClassAnnotation(context, (filterDefs[i]).getFilterClass());\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Process the annotations for the servlets.\r
+     */\r
+    protected static void loadApplicationServletAnnotations(Context context) {\r
+        \r
+        ClassLoader classLoader = context.getLoader().getClassLoader();\r
+        StandardWrapper wrapper = null;\r
+        Class classClass = null;\r
+        \r
+        Container[] children = context.findChildren();\r
+        for (int i = 0; i < children.length; i++) {\r
+            if (children[i] instanceof StandardWrapper) {\r
+                \r
+                wrapper = (StandardWrapper) children[i];\r
+                try {\r
+                    classClass = classLoader.loadClass(wrapper.getServletClass());\r
+                } catch (ClassNotFoundException e) {\r
+                    // We do nothing\r
+                } catch (NoClassDefFoundError e) {\r
+                    // We do nothing\r
+                }\r
+                \r
+                if (classClass == null) {\r
+                    continue;\r
+                }\r
+                \r
+                loadClassAnnotation(context, wrapper.getServletClass());\r
+                /* Process RunAs annotation which can be only on servlets.\r
+                 * Ref JSR 250, equivalent to the run-as element in\r
+                 * the deployment descriptor\r
+                 */\r
+                if (classClass.isAnnotationPresent(RunAs.class)) {\r
+                    RunAs annotation = (RunAs) \r
+                        classClass.getAnnotation(RunAs.class);\r
+                    wrapper.setRunAs(annotation.value());\r
+                }\r
+            }\r
+        }\r
+        \r
+        \r
+    }\r
+    \r
+    \r
+    /**\r
+     * Process the annotations on a context for a given className.\r
+     */\r
+    protected static void loadClassAnnotation(Context context, String fileString) {\r
+        \r
+        ClassLoader classLoader = context.getLoader().getClassLoader();\r
+        Class classClass = null;\r
+        \r
+        try {\r
+            classClass = classLoader.loadClass(fileString);\r
+        } catch (ClassNotFoundException e) {\r
+            // We do nothing\r
+        } catch (NoClassDefFoundError e) {\r
+            // We do nothing\r
+        }\r
+        \r
+        if (classClass == null) {\r
+            return;\r
+        }\r
+        \r
+        // Initialize the annotations\r
+        \r
+        if (classClass.isAnnotationPresent(Resource.class)) {\r
+            Resource annotation = (Resource) \r
+                classClass.getAnnotation(Resource.class);\r
+            addResource(context, annotation);\r
+        }\r
+        /* Process Resources annotation.\r
+         * Ref JSR 250\r
+         */\r
+        if (classClass.isAnnotationPresent(Resources.class)) {\r
+            Resources annotation = (Resources) \r
+                classClass.getAnnotation(Resources.class);\r
+            for (int i = 0; annotation.value() != null && i < annotation.value().length; i++) {\r
+                addResource(context, annotation.value()[i]);\r
+            }\r
+        }\r
+        /* Process EJB annotation.\r
+         * Ref JSR 224, equivalent to the ejb-ref or ejb-local-ref\r
+         * element in the deployment descriptor.\r
+        if (classClass.isAnnotationPresent(EJB.class)) {\r
+            EJB annotation = (EJB) \r
+            classClass.getAnnotation(EJB.class);\r
+            \r
+            if ((annotation.mappedName().length() == 0) ||\r
+                    annotation.mappedName().equals("Local")) {\r
+                \r
+                ContextLocalEjb ejb = new ContextLocalEjb();\r
+                \r
+                ejb.setName(annotation.name());\r
+                ejb.setType(annotation.beanInterface().getCanonicalName());\r
+                ejb.setDescription(annotation.description());\r
+                \r
+                ejb.setHome(annotation.beanName());\r
+                \r
+                context.getNamingResources().addLocalEjb(ejb);\r
+                \r
+            } else if (annotation.mappedName().equals("Remote")) {\r
+                \r
+                ContextEjb ejb = new ContextEjb();\r
+                \r
+                ejb.setName(annotation.name());\r
+                ejb.setType(annotation.beanInterface().getCanonicalName());\r
+                ejb.setDescription(annotation.description());\r
+                \r
+                ejb.setHome(annotation.beanName());\r
+                \r
+                context.getNamingResources().addEjb(ejb);\r
+                \r
+            }\r
+            \r
+        }\r
+         */\r
+        /* Process WebServiceRef annotation.\r
+         * Ref JSR 224, equivalent to the service-ref element in \r
+         * the deployment descriptor.\r
+         * The service-ref registration is not implemented\r
+        if (classClass.isAnnotationPresent(WebServiceRef.class)) {\r
+            WebServiceRef annotation = (WebServiceRef) \r
+            classClass.getAnnotation(WebServiceRef.class);\r
+            \r
+            ContextService service = new ContextService();\r
+            \r
+            service.setName(annotation.name());\r
+            service.setWsdlfile(annotation.wsdlLocation());\r
+            \r
+            service.setType(annotation.type().getCanonicalName());\r
+            \r
+            if (annotation.value() == null)\r
+                service.setServiceinterface(annotation.type().getCanonicalName());\r
+            \r
+            if (annotation.type().getCanonicalName().equals("Service"))\r
+                service.setServiceinterface(annotation.type().getCanonicalName());\r
+            \r
+            if (annotation.value().getCanonicalName().equals("Endpoint"))\r
+                service.setServiceendpoint(annotation.type().getCanonicalName());\r
+            \r
+            service.setPortlink(annotation.type().getCanonicalName());\r
+            \r
+            context.getNamingResources().addService(service);\r
+            \r
+            \r
+        }\r
+         */\r
+        /* Process DeclareRoles annotation.\r
+         * Ref JSR 250, equivalent to the security-role element in\r
+         * the deployment descriptor\r
+         */\r
+        if (classClass.isAnnotationPresent(DeclaresRoles.class)) {\r
+            DeclaresRoles annotation = (DeclaresRoles) \r
+                classClass.getAnnotation(DeclaresRoles.class);\r
+            for (int i = 0; annotation.value() != null && i < annotation.value().length; i++) {\r
+                context.addSecurityRole(annotation.value()[i]);\r
+            }\r
+        }\r
+        \r
+        \r
+    }\r
+    \r
+    \r
+    /**\r
+     * Process a Resource annotation to set up a Resource.\r
+     * Ref JSR 250, equivalent to the resource-ref,\r
+     * message-destination-ref, env-ref, resource-env-ref\r
+     * or service-ref element in the deployment descriptor.\r
+     */\r
+    protected static void addResource(Context context, Resource annotation) {\r
+        \r
+        if (annotation.type().getCanonicalName().equals("java.lang.String") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Character") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Integer") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Boolean") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Double") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Byte") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Short") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Long") ||\r
+                annotation.type().getCanonicalName().equals("java.lang.Float")) {\r
+            \r
+            // env-ref element\r
+            ContextEnvironment resource = new ContextEnvironment();\r
+            \r
+            resource.setName(annotation.name());\r
+            resource.setType(annotation.type().getCanonicalName());\r
+            \r
+            resource.setDescription(annotation.description());\r
+            \r
+            resource.setValue(annotation.mappedName());\r
+            \r
+            context.getNamingResources().addEnvironment(resource);\r
+            \r
+        } else if (annotation.type().getCanonicalName().equals("javax.xml.rpc.Service")) {\r
+            \r
+            // service-ref element\r
+            ContextService service = new ContextService();\r
+            \r
+            service.setName(annotation.name());\r
+            service.setWsdlfile(annotation.mappedName());\r
+            \r
+            service.setType(annotation.type().getCanonicalName());\r
+            service.setDescription(annotation.description());\r
+            \r
+            context.getNamingResources().addService(service);\r
+            \r
+        } else if (annotation.type().getCanonicalName().equals("javax.sql.DataSource") ||\r
+                annotation.type().getCanonicalName().equals("javax.jms.ConnectionFactory") ||\r
+                annotation.type().getCanonicalName()\r
+                .equals("javax.jms.QueueConnectionFactory") ||\r
+                annotation.type().getCanonicalName()\r
+                .equals("javax.jms.TopicConnectionFactory") ||\r
+                annotation.type().getCanonicalName().equals("javax.mail.Session") ||\r
+                annotation.type().getCanonicalName().equals("java.net.URL") ||\r
+                annotation.type().getCanonicalName()\r
+                .equals("javax.resource.cci.ConnectionFactory") ||\r
+                annotation.type().getCanonicalName().equals("org.omg.CORBA_2_3.ORB") ||\r
+                annotation.type().getCanonicalName().endsWith("ConnectionFactory")) {\r
+            \r
+            // resource-ref element\r
+            ContextResource resource = new ContextResource();\r
+            \r
+            resource.setName(annotation.name());\r
+            resource.setType(annotation.type().getCanonicalName());\r
+            \r
+            if (annotation.authenticationType()\r
+                    == Resource.AuthenticationType.CONTAINER) {\r
+                resource.setAuth("Container");\r
+            }\r
+            else if (annotation.authenticationType()\r
+                    == Resource.AuthenticationType.APPLICATION) {\r
+                resource.setAuth("Application");\r
+            }\r
+            \r
+            resource.setScope(annotation.shareable() ? "Shareable" : "Unshareable");\r
+            resource.setProperty("mappedName", annotation.mappedName());\r
+            resource.setDescription(annotation.description());\r
+            \r
+            context.getNamingResources().addResource(resource);\r
+            \r
+        } else if (annotation.type().getCanonicalName().equals("javax.jms.Queue") ||\r
+                annotation.type().getCanonicalName().equals("javax.jms.Topic")) {\r
+            \r
+            // message-destination-ref\r
+            MessageDestinationRef resource = new MessageDestinationRef();\r
+            \r
+            resource.setName(annotation.name());\r
+            resource.setType(annotation.type().getCanonicalName());\r
+            \r
+            resource.setUsage(annotation.mappedName());\r
+            resource.setDescription(annotation.description());\r
+            \r
+            context.getNamingResources().addMessageDestinationRef(resource);\r
+            \r
+        } else if (annotation.type().getCanonicalName()\r
+                .equals("javax.resource.cci.InteractionSpec") ||\r
+                annotation.type().getCanonicalName()\r
+                .equals("javax.transaction.UserTransaction") ||\r
+                true) {\r
+            \r
+            // resource-env-ref\r
+            ContextResourceEnvRef resource = new ContextResourceEnvRef();\r
+            \r
+            resource.setName(annotation.name());\r
+            resource.setType(annotation.type().getCanonicalName());\r
+            \r
+            resource.setProperty("mappedName", annotation.mappedName());\r
+            resource.setDescription(annotation.description());\r
+            \r
+            context.getNamingResources().addResourceEnvRef(resource);\r
+            \r
+        }\r
+        \r
+        \r
+    }\r
+    \r
+    \r
+}\r