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 2019/07/30 13:08:52 UTC

[tomcat] 05/06: Refactor to remove duplicate code

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit e25eb1550f2d5df7b1fb8b0fc30a3e0923977fe1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Jul 29 21:30:19 2019 +0100

    Refactor to remove duplicate code
---
 .../apache/catalina/servlets/WebdavServlet.java    | 417 ++++++---------------
 1 file changed, 105 insertions(+), 312 deletions(-)

diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java b/java/org/apache/catalina/servlets/WebdavServlet.java
index 2b677d3..54ef218 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -2110,13 +2110,6 @@ public class WebdavServlet extends DefaultServlet {
             return;
         }
 
-        generatedXML.writeElement("D", "response", XMLWriter.OPENING);
-        String status = "HTTP/1.1 " + WebdavStatus.SC_OK + " " +
-                WebdavStatus.getStatusText(WebdavStatus.SC_OK);
-
-        // Generating href element
-        generatedXML.writeElement("D", "href", XMLWriter.OPENING);
-
         String href = req.getContextPath() + req.getServletPath();
         if ((href.endsWith("/")) && (path.startsWith("/")))
             href += path.substring(1);
@@ -2125,246 +2118,12 @@ public class WebdavServlet extends DefaultServlet {
         if ((cacheEntry.context != null) && (!href.endsWith("/")))
             href += "/";
 
-        generatedXML.writeText(rewriteUrl(href));
-
-        generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
-
-        String resourceName = path;
-        int lastSlash = path.lastIndexOf('/');
-        if (lastSlash != -1)
-            resourceName = resourceName.substring(lastSlash + 1);
-
-        switch (type) {
-
-        case FIND_ALL_PROP :
-
-            generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
-            generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
-
-            generatedXML.writeProperty("D", "creationdate",
-                    getISOCreationDate(cacheEntry.attributes.getCreation()));
-            generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
-            generatedXML.writeData(resourceName);
-            generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
-            if (cacheEntry.resource != null) {
-                generatedXML.writeProperty
-                    ("D", "getlastmodified", FastHttpDateFormat.formatDate
-                           (cacheEntry.attributes.getLastModified(), null));
-                generatedXML.writeProperty
-                    ("D", "getcontentlength",
-                     String.valueOf(cacheEntry.attributes.getContentLength()));
-                String contentType = getServletContext().getMimeType
-                    (cacheEntry.name);
-                if (contentType != null) {
-                    generatedXML.writeProperty("D", "getcontenttype",
-                            contentType);
-                }
-                generatedXML.writeProperty("D", "getetag",
-                        cacheEntry.attributes.getETag());
-                generatedXML.writeElement("D", "resourcetype",
-                        XMLWriter.NO_CONTENT);
-            } else {
-                generatedXML.writeElement("D", "resourcetype",
-                        XMLWriter.OPENING);
-                generatedXML.writeElement("D", "collection",
-                        XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "resourcetype",
-                        XMLWriter.CLOSING);
-            }
-
-            generatedXML.writeProperty("D", "source", "");
-
-            String supportedLocks = "<D:lockentry>"
-                + "<D:lockscope><D:exclusive/></D:lockscope>"
-                + "<D:locktype><D:write/></D:locktype>"
-                + "</D:lockentry>" + "<D:lockentry>"
-                + "<D:lockscope><D:shared/></D:lockscope>"
-                + "<D:locktype><D:write/></D:locktype>"
-                + "</D:lockentry>";
-            generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING);
-            generatedXML.writeText(supportedLocks);
-            generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING);
-
-            generateLockDiscovery(path, generatedXML);
-
-            generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "status", XMLWriter.OPENING);
-            generatedXML.writeText(status);
-            generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
-
-            break;
-
-        case FIND_PROPERTY_NAMES :
-
-            generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
-            generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
-
-            generatedXML.writeElement("D", "creationdate",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT);
-            if (cacheEntry.resource != null) {
-                generatedXML.writeElement("D", "getcontentlanguage",
-                        XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "getcontentlength",
-                        XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "getcontenttype",
-                        XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT);
-                generatedXML.writeElement("D", "getlastmodified",
-                        XMLWriter.NO_CONTENT);
-            }
-            generatedXML.writeElement("D", "resourcetype",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "lockdiscovery",
-                                      XMLWriter.NO_CONTENT);
-
-            generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "status", XMLWriter.OPENING);
-            generatedXML.writeText(status);
-            generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
-
-            break;
-
-        case FIND_BY_PROPERTY :
-
-            Vector<String> propertiesNotFound = new Vector<String>();
-
-            // Parse the list of properties
-
-            generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
-            generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
-
-            Enumeration<String> properties = propertiesVector.elements();
-
-            while (properties.hasMoreElements()) {
-
-                String property = properties.nextElement();
-
-                if (property.equals("creationdate")) {
-                    generatedXML.writeProperty
-                        ("D", "creationdate",
-                         getISOCreationDate(cacheEntry.attributes.getCreation()));
-                } else if (property.equals("displayname")) {
-                    generatedXML.writeElement
-                        ("D", "displayname", XMLWriter.OPENING);
-                    generatedXML.writeData(resourceName);
-                    generatedXML.writeElement
-                        ("D", "displayname", XMLWriter.CLOSING);
-                } else if (property.equals("getcontentlanguage")) {
-                    if (cacheEntry.context != null) {
-                        propertiesNotFound.addElement(property);
-                    } else {
-                        generatedXML.writeElement("D", "getcontentlanguage",
-                                                  XMLWriter.NO_CONTENT);
-                    }
-                } else if (property.equals("getcontentlength")) {
-                    if (cacheEntry.context != null) {
-                        propertiesNotFound.addElement(property);
-                    } else {
-                        generatedXML.writeProperty
-                            ("D", "getcontentlength",
-                             (String.valueOf(cacheEntry.attributes.getContentLength())));
-                    }
-                } else if (property.equals("getcontenttype")) {
-                    if (cacheEntry.context != null) {
-                        propertiesNotFound.addElement(property);
-                    } else {
-                        generatedXML.writeProperty
-                            ("D", "getcontenttype",
-                             getServletContext().getMimeType
-                             (cacheEntry.name));
-                    }
-                } else if (property.equals("getetag")) {
-                    if (cacheEntry.context != null) {
-                        propertiesNotFound.addElement(property);
-                    } else {
-                        generatedXML.writeProperty
-                            ("D", "getetag", cacheEntry.attributes.getETag());
-                    }
-                } else if (property.equals("getlastmodified")) {
-                    if (cacheEntry.context != null) {
-                        propertiesNotFound.addElement(property);
-                    } else {
-                        generatedXML.writeProperty
-                            ("D", "getlastmodified", FastHttpDateFormat.formatDate
-                                    (cacheEntry.attributes.getLastModified(), null));
-                    }
-                } else if (property.equals("resourcetype")) {
-                    if (cacheEntry.context != null) {
-                        generatedXML.writeElement("D", "resourcetype",
-                                XMLWriter.OPENING);
-                        generatedXML.writeElement("D", "collection",
-                                XMLWriter.NO_CONTENT);
-                        generatedXML.writeElement("D", "resourcetype",
-                                XMLWriter.CLOSING);
-                    } else {
-                        generatedXML.writeElement("D", "resourcetype",
-                                XMLWriter.NO_CONTENT);
-                    }
-                } else if (property.equals("source")) {
-                    generatedXML.writeProperty("D", "source", "");
-                } else if (property.equals("supportedlock")) {
-                    supportedLocks = "<D:lockentry>"
-                        + "<D:lockscope><D:exclusive/></D:lockscope>"
-                        + "<D:locktype><D:write/></D:locktype>"
-                        + "</D:lockentry>" + "<D:lockentry>"
-                        + "<D:lockscope><D:shared/></D:lockscope>"
-                        + "<D:locktype><D:write/></D:locktype>"
-                        + "</D:lockentry>";
-                    generatedXML.writeElement("D", "supportedlock",
-                            XMLWriter.OPENING);
-                    generatedXML.writeText(supportedLocks);
-                    generatedXML.writeElement("D", "supportedlock",
-                            XMLWriter.CLOSING);
-                } else if (property.equals("lockdiscovery")) {
-                    if (!generateLockDiscovery(path, generatedXML))
-                        propertiesNotFound.addElement(property);
-                } else {
-                    propertiesNotFound.addElement(property);
-                }
-
-            }
-
-            generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "status", XMLWriter.OPENING);
-            generatedXML.writeText(status);
-            generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
-            generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
-
-            Enumeration<String> propertiesNotFoundList =
-                propertiesNotFound.elements();
-
-            if (propertiesNotFoundList.hasMoreElements()) {
-
-                status = "HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND + " " +
-                        WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND);
-
-                generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
-                generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
-
-                while (propertiesNotFoundList.hasMoreElements()) {
-                    generatedXML.writeElement
-                        ("D", propertiesNotFoundList.nextElement(),
-                         XMLWriter.NO_CONTENT);
-                }
-
-                generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
-                generatedXML.writeElement("D", "status", XMLWriter.OPENING);
-                generatedXML.writeText(status);
-                generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
-                generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
-
-            }
-
-            break;
-
-        }
-
-        generatedXML.writeElement("D", "response", XMLWriter.CLOSING);
+        String rewrittenUrl = rewriteUrl(href);
 
+        generatePropFindResponse(generatedXML, rewrittenUrl, path, type, propertiesVector,
+                cacheEntry.context == null, false, cacheEntry.attributes.getCreation(), cacheEntry.attributes.getLastModified(),
+                cacheEntry.attributes.getContentLength(), getServletContext().getMimeType(cacheEntry.name),
+                cacheEntry.attributes.getETag());
     }
 
 
@@ -2393,22 +2152,33 @@ public class WebdavServlet extends DefaultServlet {
         if (lock == null)
             return;
 
-        generatedXML.writeElement("D", "response", XMLWriter.OPENING);
-        String status = "HTTP/1.1 " + WebdavStatus.SC_OK + " " +
-                WebdavStatus.getStatusText(WebdavStatus.SC_OK);
-
-        // Generating href element
-        generatedXML.writeElement("D", "href", XMLWriter.OPENING);
-
         String absoluteUri = req.getRequestURI();
         String relativePath = getRelativePath(req);
         String toAppend = path.substring(relativePath.length());
         if (!toAppend.startsWith("/"))
             toAppend = "/" + toAppend;
 
-        generatedXML.writeText(rewriteUrl(RequestUtil.normalize(
-                absoluteUri + toAppend)));
+        String rewrittenUrl = rewriteUrl(RequestUtil.normalize(
+                absoluteUri + toAppend));
+
+        generatePropFindResponse(generatedXML, rewrittenUrl, path, type, propertiesVector,
+                true, true, lock.creationDate.getTime(), lock.creationDate.getTime(),
+                0, "", "");
+    }
+
+
+    private void generatePropFindResponse(XMLWriter generatedXML, String rewrittenUrl,
+            String path, int propFindType, Vector<String> propertiesVector, boolean isFile,
+            boolean isLockNull, long created, long lastModified, long contentLength,
+            String contentType, String eTag) {
+
+        generatedXML.writeElement("D", "response", XMLWriter.OPENING);
+        String status = "HTTP/1.1 " + WebdavStatus.SC_OK + " " +
+                WebdavStatus.getStatusText(WebdavStatus.SC_OK);
 
+        // Generating href element
+        generatedXML.writeElement("D", "href", XMLWriter.OPENING);
+        generatedXML.writeText(rewrittenUrl);
         generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
 
         String resourceName = path;
@@ -2416,28 +2186,37 @@ public class WebdavServlet extends DefaultServlet {
         if (lastSlash != -1)
             resourceName = resourceName.substring(lastSlash + 1);
 
-        switch (type) {
+        switch (propFindType) {
 
         case FIND_ALL_PROP :
 
             generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
             generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
 
-            generatedXML.writeProperty("D", "creationdate",
-                    getISOCreationDate(lock.creationDate.getTime()));
+            generatedXML.writeProperty("D", "creationdate", getISOCreationDate(created));
             generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
             generatedXML.writeData(resourceName);
             generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
-            generatedXML.writeProperty("D", "getlastmodified",
-                                       FastHttpDateFormat.formatDate
-                                       (lock.creationDate.getTime(), null));
-            generatedXML.writeProperty("D", "getcontentlength",
-                    String.valueOf(0));
-            generatedXML.writeProperty("D", "getcontenttype", "");
-            generatedXML.writeProperty("D", "getetag", "");
-            generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
-            generatedXML.writeElement("D", "lock-null", XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
+            if (isFile) {
+                generatedXML.writeProperty("D", "getlastmodified",
+                        FastHttpDateFormat.formatDate(lastModified, null));
+                generatedXML.writeProperty("D", "getcontentlength", Long.toString(contentLength));
+                if (contentType != null) {
+                    generatedXML.writeProperty("D", "getcontenttype", contentType);
+                }
+                generatedXML.writeProperty("D", "getetag", eTag);
+                if (isLockNull) {
+                    generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
+                    generatedXML.writeElement("D", "lock-null", XMLWriter.NO_CONTENT);
+                    generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
+                } else {
+                    generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
+                }
+            } else {
+                generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
+                generatedXML.writeElement("D", "collection", XMLWriter.NO_CONTENT);
+                generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
+            }
 
             generatedXML.writeProperty("D", "source", "");
 
@@ -2467,23 +2246,18 @@ public class WebdavServlet extends DefaultServlet {
             generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
             generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
 
-            generatedXML.writeElement("D", "creationdate",
-                                      XMLWriter.NO_CONTENT);
+            generatedXML.writeElement("D", "creationdate", XMLWriter.NO_CONTENT);
             generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "getcontentlanguage",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "getcontentlength",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "getcontenttype",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "getlastmodified",
-                                      XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "resourcetype",
-                                      XMLWriter.NO_CONTENT);
+            if (isFile) {
+                generatedXML.writeElement("D", "getcontentlanguage", XMLWriter.NO_CONTENT);
+                generatedXML.writeElement("D", "getcontentlength", XMLWriter.NO_CONTENT);
+                generatedXML.writeElement("D", "getcontenttype", XMLWriter.NO_CONTENT);
+                generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT);
+                generatedXML.writeElement("D", "getlastmodified", XMLWriter.NO_CONTENT);
+            }
+            generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
             generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT);
-            generatedXML.writeElement("D", "lockdiscovery",
-                                      XMLWriter.NO_CONTENT);
+            generatedXML.writeElement("D", "lockdiscovery", XMLWriter.NO_CONTENT);
 
             generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
             generatedXML.writeElement("D", "status", XMLWriter.OPENING);
@@ -2509,36 +2283,58 @@ public class WebdavServlet extends DefaultServlet {
                 String property = properties.nextElement();
 
                 if (property.equals("creationdate")) {
-                    generatedXML.writeProperty("D", "creationdate",
-                            getISOCreationDate(lock.creationDate.getTime()));
+                    generatedXML.writeProperty("D", "creationdate", getISOCreationDate(created));
                 } else if (property.equals("displayname")) {
-                    generatedXML.writeElement("D", "displayname",
-                            XMLWriter.OPENING);
+                    generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
                     generatedXML.writeData(resourceName);
-                    generatedXML.writeElement("D", "displayname",
-                            XMLWriter.CLOSING);
+                    generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
                 } else if (property.equals("getcontentlanguage")) {
-                    generatedXML.writeElement("D", "getcontentlanguage",
-                            XMLWriter.NO_CONTENT);
+                    if (isFile) {
+                        generatedXML.writeElement("D", "getcontentlanguage",
+                                XMLWriter.NO_CONTENT);
+                    } else {
+                        propertiesNotFound.addElement(property);
+                    }
                 } else if (property.equals("getcontentlength")) {
-                    generatedXML.writeProperty("D", "getcontentlength",
-                            (String.valueOf(0)));
+                    if (isFile) {
+                        generatedXML.writeProperty("D", "getcontentlength",
+                                Long.toString(contentLength));
+                    } else {
+                        propertiesNotFound.addElement(property);
+                    }
                 } else if (property.equals("getcontenttype")) {
-                    generatedXML.writeProperty("D", "getcontenttype", "");
+                    if (isFile) {
+                        generatedXML.writeProperty("D", "getcontenttype", contentType);
+                    } else {
+                        propertiesNotFound.addElement(property);
+                    }
                 } else if (property.equals("getetag")) {
-                    generatedXML.writeProperty("D", "getetag", "");
+                    if (isFile) {
+                        generatedXML.writeProperty("D", "getetag", eTag);
+                    } else {
+                        propertiesNotFound.addElement(property);
+                    }
                 } else if (property.equals("getlastmodified")) {
-                    generatedXML.writeProperty
-                        ("D", "getlastmodified",
-                          FastHttpDateFormat.formatDate
-                         (lock.creationDate.getTime(), null));
+                    if (isFile) {
+                        generatedXML.writeProperty("D", "getlastmodified",
+                                FastHttpDateFormat.formatDate(lastModified, null));
+                    } else {
+                        propertiesNotFound.addElement(property);
+                    }
                 } else if (property.equals("resourcetype")) {
-                    generatedXML.writeElement("D", "resourcetype",
-                            XMLWriter.OPENING);
-                    generatedXML.writeElement("D", "lock-null",
-                            XMLWriter.NO_CONTENT);
-                    generatedXML.writeElement("D", "resourcetype",
-                            XMLWriter.CLOSING);
+                    if (isFile) {
+                        if(isLockNull) {
+                            generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
+                            generatedXML.writeElement("D", "lock-null", XMLWriter.NO_CONTENT);
+                            generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
+                        } else {
+                            generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
+                        }
+                    } else {
+                        generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
+                        generatedXML.writeElement("D", "collection", XMLWriter.NO_CONTENT);
+                        generatedXML.writeElement("D", "resourcetype",XMLWriter.CLOSING);
+                    }
                 } else if (property.equals("source")) {
                     generatedXML.writeProperty("D", "source", "");
                 } else if (property.equals("supportedlock")) {
@@ -2549,11 +2345,9 @@ public class WebdavServlet extends DefaultServlet {
                         + "<D:lockscope><D:shared/></D:lockscope>"
                         + "<D:locktype><D:write/></D:locktype>"
                         + "</D:lockentry>";
-                    generatedXML.writeElement("D", "supportedlock",
-                            XMLWriter.OPENING);
+                    generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING);
                     generatedXML.writeText(supportedLocks);
-                    generatedXML.writeElement("D", "supportedlock",
-                            XMLWriter.CLOSING);
+                    generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING);
                 } else if (property.equals("lockdiscovery")) {
                     if (!generateLockDiscovery(path, generatedXML))
                         propertiesNotFound.addElement(property);
@@ -2580,9 +2374,8 @@ public class WebdavServlet extends DefaultServlet {
                 generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
 
                 while (propertiesNotFoundList.hasMoreElements()) {
-                    generatedXML.writeElement
-                        ("D", propertiesNotFoundList.nextElement(),
-                         XMLWriter.NO_CONTENT);
+                    generatedXML.writeElement("D", propertiesNotFoundList.nextElement(),
+                            XMLWriter.NO_CONTENT);
                 }
 
                 generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);


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