You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2009/12/07 15:18:30 UTC

svn commit: r887929 - in /tomcat/trunk/java/org/apache/catalina/startup: ContextConfig.java LocalStrings.properties

Author: markt
Date: Mon Dec  7 14:18:29 2009
New Revision: 887929

URL: http://svn.apache.org/viewvc?rev=887929&view=rev
Log:
Add annotation support for WebServlet

Modified:
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties

Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=887929&r1=887928&r2=887929&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Mon Dec  7 14:18:29 2009
@@ -29,6 +29,7 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -40,6 +41,14 @@
 
 import javax.servlet.ServletContext;
 
+import org.apache.tomcat.util.bcel.classfile.AnnotationElementValue;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.ArrayElementValue;
+import org.apache.tomcat.util.bcel.classfile.ClassFormatException;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.ElementValuePair;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
 import org.apache.catalina.Authenticator;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
@@ -61,6 +70,7 @@
 import org.apache.catalina.deploy.FilterMap;
 import org.apache.catalina.deploy.LoginConfig;
 import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.catalina.deploy.ServletDef;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.naming.resources.DirContextURLConnection;
@@ -1586,8 +1596,8 @@
             dcUrlConn = (DirContextURLConnection) urlConn;
             dcUrlConn.setUseCaches(false);
             
-            String ct = dcUrlConn.getContentType();
-            if (ResourceAttributes.COLLECTION_TYPE.equals(ct)) {
+            String type = dcUrlConn.getHeaderField(ResourceAttributes.TYPE);
+            if (ResourceAttributes.COLLECTION_TYPE.equals(type)) {
                 // Collection
                 Enumeration<String> dirs = dcUrlConn.list();
                 while (dirs.hasMoreElements()) {
@@ -1618,7 +1628,7 @@
                 }
             }
         } catch (IOException e) {
-            log.error(sm.getString("contextConfig.jarFile", url), e);
+            log.error(sm.getString("contextConfig.jndiUrl", url), e);
         }
     }
     
@@ -1651,10 +1661,123 @@
     }
 
 
-    protected void processAnnotationsStream(InputStream is, WebXml fragment) {
-        // TODO SERVLET 3
+    protected void processAnnotationsStream(InputStream is, WebXml fragment)
+            throws ClassFormatException, IOException {
+        
+        ClassParser parser = new ClassParser(is, null);
+        JavaClass clazz = parser.parse();
+        String className = clazz.getClassName();
+        AnnotationEntry[] annotationsEntries = clazz.getAnnotationEntries();
+        
+        for (AnnotationEntry ae : annotationsEntries) {
+            String type = ae.getAnnotationType();
+            if ("Ljavax/servlet/annotation/WebServlet;".equals(type)) {
+                processAnnotationWebServlet(className, ae, fragment);
+            } else {
+                // TODO SERVLET 3 - Other annotations
+                // Unknown annotation - ignore
+            }
+        }
+    }
+
+    protected void processAnnotationWebServlet(String className,
+            AnnotationEntry ae, WebXml fragment) {
+        if (fragment.getServlets().containsKey(className)) {
+            // Skip this annotation. Entry in web.xml takes priority
+            return;
+        }
+        boolean mappingSet = false;
+        ServletDef servletDef = new ServletDef();
+        servletDef.setServletName(className);
+        servletDef.setServletClass(className);
+        String[] mappings = null;
+
+        ElementValuePair[] evps = ae.getElementValuePairs();
+        for (ElementValuePair evp : evps) {
+            String name = evp.getNameString();
+            if ("value".equals(name) || "urlPatterns".equals(name)) {
+                if (mappingSet) {
+                    throw new IllegalArgumentException(sm.getString(
+                            "contextConfig.urlPatternValue", className));
+                }
+                mappingSet = true;
+                mappings = processAnnotationsUrlPatterns(evp.getValue());
+            } else if ("name".equals(name)) {
+                servletDef.setServletName(evp.getValue().stringifyValue());
+            } else if ("description".equals(name)) {
+                servletDef.setDescription(evp.getValue().stringifyValue());
+            } else if ("displayName".equals(name)) {
+                servletDef.setDisplayName(evp.getValue().stringifyValue());
+            } else if ("largeIcon".equals(name)) {
+                servletDef.setLargeIcon(evp.getValue().stringifyValue());
+            } else if ("smallIcon".equals(name)) {
+                servletDef.setSmallIcon(evp.getValue().stringifyValue());
+            } else if ("asyncSupported".equals(name)) {
+                servletDef.setAsyncSupported(evp.getValue().stringifyValue());
+            } else if ("loadOnStartup".equals(name)) {
+                servletDef.setLoadOnStartup(evp.getValue().stringifyValue());
+            } else if ("initParams".equals(name)) {
+                Map<String,String> initParams =
+                    processAnnotationWebInitParams(evp.getValue());
+                for (String paramName : initParams.keySet()) {
+                    servletDef.addInitParameter(paramName,
+                            initParams.get(paramName));
+                }
+            } else {
+                // Ignore
+            }
+        }
+        if (mappings != null) {
+            fragment.addServlet(servletDef);
+            for (String mapping : mappings) {
+                fragment.addServletMapping(mapping,
+                        servletDef.getServletName());
+            }
+        }
     }
 
+    protected String[] processAnnotationsUrlPatterns(ElementValue ev) {
+        ArrayList<String> values = new ArrayList<String>();
+        if (ev instanceof ArrayElementValue) {
+            ElementValue[] arrayValues =
+                ((ArrayElementValue) ev).getElementValuesArray();
+            for (ElementValue value : arrayValues) {
+                values.add(value.stringifyValue());
+            }
+        } else {
+            values.add(ev.stringifyValue());
+        }
+        String[] result = new String[values.size()];
+        return values.toArray(result);
+    }
+    
+    protected Map<String,String> processAnnotationWebInitParams(
+            ElementValue ev) {
+        Map<String, String> result = new HashMap<String,String>();
+        if (ev instanceof ArrayElementValue) {
+            ElementValue[] arrayValues =
+                ((ArrayElementValue) ev).getElementValuesArray();
+            for (ElementValue value : arrayValues) {
+                if (value instanceof AnnotationElementValue) {
+                    ElementValuePair[] evps = ((AnnotationElementValue)
+                            value).getAnnotationEntry().getElementValuePairs();
+                    String initParamName = null;
+                    String initParamValue = null;
+                    for (ElementValuePair evp : evps) {
+                        if ("name".equals(evp.getNameString())) {
+                            initParamName = evp.getValue().stringifyValue();
+                        } else if ("value".equals(evp.getNameString())) {
+                            initParamValue = evp.getValue().stringifyValue();
+                        } else {
+                            // Ignore
+                        }
+                    }
+                    result.put(initParamName, initParamValue);
+                }
+            }
+        }
+        return result;
+    }
     
     private class FragmentJarScannerCallback implements JarScannerCallback {
 

Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=887929&r1=887928&r2=887929&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Mon Dec  7 14:18:29 2009
@@ -39,7 +39,7 @@
 contextConfig.inputStreamFile=Unable to process file [{0}] for annotations
 contextConfig.inputStreamJar=Unable to process Jar entry [{0}] from Jar [{1}] for annotations
 contextConfig.inputStreamJndi=Unable to process resource element [{0}] for annotations
-contextConfig.jarFile=Unable to process Jar [{0}] for annotations
+contextConfig.jndiUrl=Unable to process JNDI URL [{0}] for annotations
 contextConfig.jarUrl=The connection created for URL [{0}] was not a JarUrlConnection
 contextConfig.jar=Unable to process resource [{0}] for annotations
 contextConfig.jndiUrl=The connection created for URL [{0}] was not a DirContextURLConnection
@@ -51,6 +51,7 @@
 contextConfig.stop=ContextConfig: Processing STOP
 contextConfig.unavailable=Marking this application unavailable due to previous error(s)
 contextConfig.unknownUrlProtocol=The URL protocol [{0}] was not recognised during annotation processing. URL [{1}] was ignored.
+contextConfig.urlPatternValue=Both the UrlPattern and value attribute were set for the WebServlet annotation on class [{0}]
 contextConfig.webinfClassesUrl=Unable to determine URL for WEB-INF/classes
 contextConfig.xmlSettings=Context [{0}] will parse web.xml and web-fragment.xml files with validation:{1} and namespaceAware:{2}
 embedded.alreadyStarted=Embedded service has already been started



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org