remm        01/01/22 20:47:57

  Modified:    catalina/src/share/org/apache/catalina/servlets
                        DefaultServlet.java LocalStrings.properties
                        WebdavServlet.java
  Log:
  - Backport from 4.1.
  - Update DefaultServlet and WebdavServlet to use the directory contexts.
  
  Revision  Changes    Path
  1.20      +436 -69   
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java
  
  Index: DefaultServlet.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- DefaultServlet.java       2001/01/18 20:20:55     1.19
  +++ DefaultServlet.java       2001/01/23 04:47:57     1.20
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
 1.19 2001/01/18 20:20:55 remm Exp $
  - * $Revision: 1.19 $
  - * $Date: 2001/01/18 20:20:55 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
 1.20 2001/01/23 04:47:57 remm Exp $
  + * $Revision: 1.20 $
  + * $Date: 2001/01/23 04:47:57 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,8 @@
   
   
   import java.io.BufferedInputStream;
  +import java.io.ByteArrayOutputStream;
  +import java.io.ByteArrayInputStream;
   import java.io.File;
   import java.io.FileInputStream;
   import java.io.InputStream;
  @@ -76,6 +78,7 @@
   import java.io.Writer;
   import java.net.MalformedURLException;
   import java.net.URL;
  +import java.net.URLEncoder;
   import java.sql.Timestamp;
   import java.util.Date;
   import java.util.Enumeration;
  @@ -95,16 +98,19 @@
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  +import javax.naming.NamingException;
  +import javax.naming.InitialContext;
  +import javax.naming.Context;
  +import javax.naming.NamingEnumeration;
  +import javax.naming.NameClassPair;
  +import javax.naming.directory.DirContext;
  +import javax.naming.directory.Attribute;
  +import javax.naming.directory.Attributes;
  +import org.apache.naming.resources.Resource;
  +import org.apache.naming.resources.ResourceAttributes;
   import org.apache.catalina.Globals;
  -import org.apache.catalina.Resources;
  -import org.apache.catalina.core.ApplicationContext;
  -import org.apache.catalina.resources.ResourceBean;
  -import org.apache.catalina.resources.DirectoryBean;
   import org.apache.catalina.util.MD5Encoder;
   import org.apache.catalina.util.StringManager;
  -import org.apache.catalina.util.xml.SaxContext;
  -import org.apache.catalina.util.xml.XmlAction;
  -import org.apache.catalina.util.xml.XmlMapper;
   
   
   /**
  @@ -113,7 +119,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.19 $ $Date: 2001/01/18 20:20:55 $
  + * @version $Revision: 1.20 $ $Date: 2001/01/23 04:47:57 $
    */
   
   public class DefaultServlet
  @@ -201,6 +207,12 @@
   
   
       /**
  +     * JNDI resources name.
  +     */
  +    protected static final String RESOURCES_JNDI_NAME = "java:/comp/Resources";
  +
  +
  +    /**
        * The string manager for this package.
        */
       protected static StringManager sm =
  @@ -295,6 +307,38 @@
   
   
       /**
  +     * Get resources. This method will try to retrieve the resources through
  +     * JNDI first, then in the servlet context if JNDI has failed (it could be
  +     * disabled). It will return null.
  +     * 
  +     * @return A JNDI DirContext, or null.
  +     */
  +    protected DirContext getResources() {
  +
  +        // First : try JNDI
  +        try {
  +            return 
  +                (DirContext) new InitialContext().lookup(RESOURCES_JNDI_NAME);
  +        } catch (NamingException e) {
  +            // Failed
  +        } catch (ClassCastException e) {
  +            // Failed : Not the right type
  +        }
  +
  +        // If it has failed, try the servlet context
  +        try {
  +            return (DirContext) getServletContext()
  +                .getAttribute(Globals.RESOURCES_ATTR);
  +        } catch (ClassCastException e) {
  +            // Failed : Not the right type
  +        }
  +
  +        return null;
  +
  +    }
  +
  +
  +    /**
        * Show HTTP header information.
        */
       protected void showRequestInfo(HttpServletRequest req) {
  @@ -408,7 +452,7 @@
           if ((result == null) || (result.equals(""))) {
               result = "/";
           }
  -        return result;
  +        return normalize(result);
           
       }
   
  @@ -494,14 +538,30 @@
               resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
           }
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -        Resources resources = context.getResources();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  -        boolean exists = resources.exists(path);
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
           
  -        boolean result = resources.setResource(path, req.getInputStream());
  +        boolean exists = true;
  +        try {
  +            resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
           
  +        boolean result = true;
  +        try {
  +            Resource newResource = new Resource(req.getInputStream());
  +            // FIXME: Add attributes
  +            resources.bind(path, newResource);
  +        } catch(NamingException e) {
  +            result = false;
  +        }
  +        
           if (result) {
               if (exists) {
                   resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
  @@ -535,13 +595,28 @@
           String path = getRelativePath(req);
           
           // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -        Resources resources = context.getResources();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
  +        
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
           
  -        boolean exists = resources.exists(path);
  +        boolean exists = true;
  +        try {
  +            resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
           
           if (exists) {
  -            boolean result = resources.deleteResource(path);
  +            boolean result = true;
  +            try {
  +                resources.unbind(path);
  +            } catch (NamingException e) {
  +                result = false;
  +            }
               if (result) {
                   resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
               } else {
  @@ -744,6 +819,9 @@
        */
       protected String normalize(String path) {
   
  +        if (path == null)
  +            return null;
  +
        String normalized = path;
   
        // Resolve encoded characters in the normalized path,
  @@ -818,6 +896,29 @@
       }
   
   
  +    /**
  +     * URL rewriter.
  +     * 
  +     * @param path Path which has to be rewiten
  +     */
  +    protected String rewriteUrl(String path) {
  +        
  +        String normalized = path;
  +        
  +     // Replace " " with "%20"
  +        while (true) {
  +         int index = normalized.indexOf(" ");
  +         if (index < 0)
  +             break;
  +         normalized = normalized.substring(0, index) + "%20"
  +             + normalized.substring(index + 1);
  +     }
  +        
  +        return normalized;
  +        
  +    }
  +    
  +    
       // -------------------------------------------------------- Private Methods
   
   
  @@ -837,8 +938,7 @@
           IOException exception = null;
               
           // FIXME : i18n ?
  -        InputStream resourceInputStream = 
  -            resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +        InputStream resourceInputStream = resourceInfo.getStream();
           InputStream istream = new BufferedInputStream
               (resourceInputStream, input);
           
  @@ -874,8 +974,7 @@
   
           IOException exception = null;
               
  -        InputStream resourceInputStream = 
  -            resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +        InputStream resourceInputStream = resourceInfo.getStream();
           // FIXME : i18n ?
           Reader reader = new InputStreamReader(resourceInputStream);
           
  @@ -912,8 +1011,7 @@
           
           IOException exception = null;
           
  -        InputStream resourceInputStream = 
  -            resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +        InputStream resourceInputStream = resourceInfo.getStream();
           InputStream istream =
               new BufferedInputStream(resourceInputStream, input);
           exception = copyRange(istream, ostream, range.start, range.end);
  @@ -948,8 +1046,7 @@
           
           IOException exception = null;
           
  -        InputStream resourceInputStream = 
  -            resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +        InputStream resourceInputStream = resourceInfo.getStream();
           Reader reader = new InputStreamReader(resourceInputStream);
           exception = copyRange(reader, writer, range.start, range.end);
           
  @@ -986,8 +1083,7 @@
           
           while ( (exception == null) && (ranges.hasMoreElements()) ) {
               
  -            InputStream resourceInputStream = 
  -                resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +            InputStream resourceInputStream = resourceInfo.getStream();
               InputStream istream =    // FIXME: internationalization???????
                   new BufferedInputStream(resourceInputStream, input);
           
  @@ -1042,8 +1138,7 @@
           
           while ( (exception == null) && (ranges.hasMoreElements()) ) {
               
  -            InputStream resourceInputStream = 
  -                resourceInfo.resources.getResourceAsStream(resourceInfo.path);
  +            InputStream resourceInputStream = resourceInfo.getStream();
               Reader reader = new InputStreamReader(resourceInputStream);
           
               Range currentRange = (Range) ranges.nextElement();
  @@ -1262,7 +1357,7 @@
        * @param pathname Pathname of the file to be served
        */
       private ResourceInfo checkWelcomeFiles(String pathname, 
  -                                           Resources resources) {
  +                                           DirContext resources) {
           
           String collectionName = pathname;
           if (!pathname.endsWith("/")) {
  @@ -1323,17 +1418,15 @@
   
        // Exclude any resource in the /WEB-INF and /META-INF subdirectories
        // (the "toUpperCase()" avoids problems on Windows systems)
  -        String normalizedPath = normalize(path);
  -     if ((normalizedPath == null) ||
  -            normalizedPath.toUpperCase().startsWith("/WEB-INF") ||
  -         normalizedPath.toUpperCase().startsWith("/META-INF")) {
  +     if ((path == null) ||
  +            path.toUpperCase().startsWith("/WEB-INF") ||
  +         path.toUpperCase().startsWith("/META-INF")) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, path);
            return;
        }
   
           // Retrieve the Catalina context and Resources implementation
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -        Resources resources = context.getResources();
  +        DirContext resources = getResources();
           ResourceInfo resourceInfo = new ResourceInfo(path, resources);
   
           if (!resourceInfo.exists) {
  @@ -1366,18 +1459,12 @@
                   if ((contextPath != null) && (!contextPath.equals("/"))) {
                       redirectPath = contextPath + redirectPath;
                   }
  -                response.sendRedirect(redirectPath);
  +                response.sendRedirect(rewriteUrl(redirectPath));
                   return;
               }
               
           }
           
  -     if (!resourceInfo.exists()) {
  -         response.sendError(HttpServletResponse.SC_NOT_FOUND, 
  -                               resourceInfo.path);
  -         return;
  -     }
  -
           // Checking If headers
           if ( !checkIfHeaders(request, response, resourceInfo) ) {
               return;
  @@ -1402,18 +1489,20 @@
           // Parse range specifier
           Vector ranges = null;
           if (!resourceInfo.collection) {
  +            
               ranges = parseRange(request, response, resourceInfo);
  -        
  -            // Last-Modified header
  -            if (debug > 0)
  -                log("DefaultServlet.serveFile:  lastModified='" +
  -                    (new Timestamp(resourceInfo.date)).toString() + "'");
  -            response.setDateHeader("Last-Modified", resourceInfo.date);
               
               // ETag header
               response.setHeader("ETag", getETag(resourceInfo, true));
  +            
           }
           
  +        // Last-Modified header
  +        if (debug > 0)
  +            log("DefaultServlet.serveFile:  lastModified='" +
  +                (new Timestamp(resourceInfo.date)).toString() + "'");
  +        response.setDateHeader("Last-Modified", resourceInfo.date);
  +        
           ServletOutputStream ostream = null;
           PrintWriter writer = null;
           
  @@ -1436,8 +1525,9 @@
   
           }
           
  -        if ( ((ranges == null) || (ranges.isEmpty())) 
  -             && (request.getHeader("Range") == null) ) {
  +        if ( (resourceInfo.collection) || 
  +             ( ((ranges == null) || (ranges.isEmpty())) 
  +               && (request.getHeader("Range") == null) ) ) {
               
               // Set the appropriate output headers
               if (contentType != null) {
  @@ -1454,6 +1544,16 @@
                   response.setContentLength((int) contentLength);
               }
               
  +            if (resourceInfo.collection) {
  +                
  +                if (content) {
  +                    // Serve the directory browser
  +                    resourceInfo.setStream
  +                        (render(request.getContextPath(), resourceInfo));
  +                }
  +                
  +            }
  +            
               // Copy the input stream to our output stream (if requested)
               if (content) {
                   try {
  @@ -1667,6 +1767,184 @@
       }
   
   
  +    /**
  +     * Return an InputStream to an HTML representation of the contents
  +     * of this directory.
  +     *
  +     * @param contextPath Context path to which our internal paths are
  +     *  relative
  +     */
  +    private InputStream render(String contextPath, ResourceInfo resourceInfo) {
  +
  +        String name = resourceInfo.path;
  +
  +     // Number of characters to trim from the beginnings of filenames
  +     int trim = name.length();
  +     if (!name.endsWith("/"))
  +         trim += 1;
  +     if (name.equals("/"))
  +         trim = 1;
  +
  +     // Prepare a writer to a buffered area
  +     ByteArrayOutputStream stream = new ByteArrayOutputStream();
  +     PrintWriter writer = new PrintWriter(stream);
  +
  +     // FIXME - Currently pays no attention to the user's Locale
  +
  +     // Render the page header
  +     writer.print("<html>\r\n");
  +     writer.print("<head>\r\n");
  +     writer.print("<title>");
  +     writer.print(sm.getString("directory.title", name));
  +     writer.print("</title>\r\n</head>\r\n");
  +     writer.print("<body bgcolor=\"white\">\r\n");
  +     writer.print("<table width=\"90%\" cellspacing=\"0\"" +
  +                  " cellpadding=\"5\" align=\"center\">\r\n");
  +
  +     // Render the in-page title
  +     writer.print("<tr><td colspan=\"3\"><font size=\"+2\">\r\n<strong>");
  +     writer.print(sm.getString("directory.title", name));
  +     writer.print("</strong>\r\n</font></td></tr>\r\n");
  +
  +     // Render the link to our parent (if required)
  +        String parentDirectory = name;
  +        if (parentDirectory.endsWith("/")) {
  +            parentDirectory = 
  +                parentDirectory.substring(0, parentDirectory.length() - 1);
  +        }
  +     int slash = parentDirectory.lastIndexOf("/");
  +     if (slash >= 0) {
  +         String parent = name.substring(0, slash);
  +         writer.print("<tr><td colspan=\"3\" bgcolor=\"#ffffff\">\r\n");
  +         writer.print("<a href=\"");
  +         writer.print(rewriteUrl(contextPath));
  +            if (parent.equals(""))
  +                parent = "/";
  +            //if (contextPath.endsWith("/"))
  +            //parent = parent.substring(1);
  +         writer.print(rewriteUrl(parent));
  +            writer.print("\">");
  +         writer.print(sm.getString("directory.parent", parent));
  +         writer.print("</a>\r\n");
  +         writer.print("</td></tr>\r\n");
  +     }
  +
  +     // Render the column headings
  +     writer.print("<tr bgcolor=\"#cccccc\">\r\n");
  +     writer.print("<td align=\"left\"><font size=\"+1\"><strong>");
  +     writer.print(sm.getString("directory.filename"));
  +     writer.print("</strong></font></td>\r\n");
  +     writer.print("<td align=\"center\"><font size=\"+1\"><strong>");
  +     writer.print(sm.getString("directory.size"));
  +     writer.print("</strong></font></td>\r\n");
  +     writer.print("<td align=\"right\"><font size=\"+1\"><strong>");
  +     writer.print(sm.getString("directory.lastModified"));
  +     writer.print("</strong></font></td>\r\n");
  +     writer.print("</tr>\r\n");
  +
  +        try {
  +
  +            // Render the directory entries within this directory
  +            DirContext directory = resourceInfo.directory;
  +            NamingEnumeration enum = 
  +                resourceInfo.resources.list(resourceInfo.path);
  +            boolean shade = false;
  +            while (enum.hasMoreElements()) {
  +
  +                NameClassPair ncPair = (NameClassPair) enum.nextElement();
  +                String resourceName = ncPair.getName();
  +                ResourceInfo childResourceInfo = 
  +                    new ResourceInfo(resourceName, directory);
  +
  +                String trimmed = resourceName/*.substring(trim)*/;
  +                if (trimmed.equalsIgnoreCase("WEB-INF") ||
  +                    trimmed.equalsIgnoreCase("META-INF"))
  +                    continue;
  +
  +                writer.print("<tr");
  +                if (shade)
  +                    writer.print(" bgcolor=\"eeeeee\"");
  +                writer.print(">\r\n");
  +                shade = !shade;
  +
  +                writer.print("<td align=\"left\">&nbsp;&nbsp;\r\n");
  +                writer.print("<a href=\"");
  +                writer.print(rewriteUrl(contextPath));
  +                resourceName = rewriteUrl(name + resourceName);
  +                writer.print(resourceName);
  +                writer.print("\"><tt>");
  +                writer.print(trimmed);
  +
  +                if (childResourceInfo.collection)
  +                    writer.print("/");
  +                writer.print("</tt></a></td>\r\n");
  +
  +                writer.print("<td align=\"right\"><tt>");
  +                if (childResourceInfo.collection)
  +                    writer.print("&nbsp;");
  +                else
  +                    writer.print(renderSize(childResourceInfo.length));
  +                writer.print("</tt></td>\r\n");
  +
  +                writer.print("<td align=\"right\"><tt>");
  +                writer.print(renderLastModified(childResourceInfo.date));
  +                writer.print("</tt></td>\r\n");
  +
  +                writer.print("</tr>\r\n");
  +            }
  +
  +        } catch (NamingException e) {
  +            // Something went wrong
  +            e.printStackTrace();
  +        }
  +
  +     // Render the page footer
  +     writer.print("<tr><td colspan=\"3\">&nbsp;</td></tr>\r\n");
  +     writer.print("<tr><td colspan=\"3\" bgcolor=\"#cccccc\">");
  +     writer.print("<font size=\"-1\">");
  +     writer.print(Globals.SERVER_INFO);
  +     writer.print("</font></td></tr>\r\n");
  +     writer.print("</table>\r\n");
  +     writer.print("</body>\r\n");
  +     writer.print("</html>\r\n");
  +
  +     // Return an input stream to the underlying bytes
  +     writer.flush();
  +     return (new ByteArrayInputStream(stream.toByteArray()));
  +
  +    }
  +
  +
  +    /**
  +     * Render the last modified date and time for the specified timestamp.
  +     *
  +     * @param lastModified Last modified date and time, in milliseconds since
  +     *  the epoch
  +     */
  +    private String renderLastModified(long lastModified) {
  +
  +     return (formats[0].format(new Date(lastModified)));
  +
  +    }
  +
  +
  +    /**
  +     * Render the specified file size (in bytes).
  +     *
  +     * @param size File size (in bytes)
  +     */
  +    private String renderSize(long size) {
  +
  +     long leftSide = size / 1024;
  +     long rightSide = (size % 1024) / 103;   // Makes 1 digit
  +     if ((leftSide == 0) && (rightSide == 0) && (size > 0))
  +         rightSide = 1;
  +
  +     return ("" + leftSide + "." + rightSide + " kb");
  +
  +    }
  +
  +
       // ------------------------------------------------------ Range Inner Class
   
   
  @@ -1684,6 +1962,12 @@
                        && (start <= end) && (end < length) );
           }
           
  +        public void recycle() {
  +            start = 0;
  +            end = 0;
  +            length = 0;
  +        }
  +        
       }
   
   
  @@ -1698,22 +1982,15 @@
            * 
            * @param pathname Path name of the file
            */
  -        public ResourceInfo(String path, Resources resources) {
  -            
  -            this.path = path;
  -            this.resources = resources;
  -            this.exists = resources.exists(path);
  -            if (exists) {
  -                this.creationDate = resources.getResourceCreated(path);
  -                this.date = resources.getResourceModified(path);
  -                this.httpDate = formats[0].format(new Date(date));
  -                this.length = resources.getResourceLength(path);
  -                this.collection = resources.isCollection(path);
  -            }
  -
  +        public ResourceInfo(String path, DirContext resources) {
  +            set(path, resources);
           }
   
   
  +        public Object object;
  +        public DirContext directory;
  +        public Resource file;
  +        public Attributes attributes;
           public String path;
           public long creationDate;
           public String httpDate;
  @@ -1721,7 +1998,75 @@
           public long length;
           public boolean collection;
           public boolean exists;
  -        public Resources resources;
  +        public DirContext resources;
  +        protected InputStream is;
  +
  +
  +        public void recycle() {
  +            object = null;
  +            directory = null;
  +            file = null;
  +            attributes = null;
  +            path = null;
  +            creationDate = 0;
  +            httpDate = null;
  +            date = 0;
  +            length = -1;
  +            collection = true;
  +            exists = false;
  +            resources = null;
  +            is = null;
  +        }
  +
  +
  +        public void set(String path, DirContext resources) {
  +            
  +            recycle();
  +            
  +            this.path = path;
  +            this.resources = resources;
  +            exists = true;
  +            try {
  +                object = resources.lookup(path);
  +                if (object instanceof Resource) {
  +                    file = (Resource) object;
  +                    collection = false;
  +                } else if (object instanceof DirContext) {
  +                    directory = (DirContext) object;
  +                    collection = true;
  +                } else {
  +                    // Don't know how to serve another object type
  +                    exists = false;
  +                }
  +            } catch (NamingException e) {
  +                exists = false;
  +            }
  +            if (exists) {
  +                try {
  +                    attributes = resources.getAttributes(path);
  +                    if (attributes instanceof ResourceAttributes) {
  +                        ResourceAttributes tempAttrs =
  +                            (ResourceAttributes) attributes;
  +                        Date tempDate = tempAttrs.getCreationDate();
  +                        if (tempDate != null)
  +                            creationDate = tempDate.getTime();
  +                        tempDate = tempAttrs.getLastModified();
  +                        if (tempDate != null) {
  +                            date = tempDate.getTime();
  +                            httpDate = formats[0].format(tempDate);
  +                        } else {
  +                            httpDate = formats[0].format(new Date());
  +                        }
  +                        length = tempAttrs.getContentLength();
  +                    }
  +                } catch (NamingException e) {
  +                    // Shouldn't happen, the implementation of the DirContext
  +                    // is probably broken
  +                    exists = false;
  +                }
  +            }
  +            
  +        }
   
   
           /**
  @@ -1737,6 +2082,28 @@
            */
           public String toString() {
               return path;
  +        }
  +
  +
  +        /**
  +         * Set IS.
  +         */
  +        public void setStream(InputStream is) {
  +            this.is = is;
  +        }
  +
  +
  +        /**
  +         * Get IS from resource.
  +         */
  +        public InputStream getStream()
  +            throws IOException {
  +            if (is != null)
  +                return is;
  +            if (file != null)
  +                return (file.streamContent());
  +            else
  +                return null;
           }
   
   
  
  
  
  1.4       +6 -0      
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LocalStrings.properties   2000/11/10 01:19:17     1.3
  +++ LocalStrings.properties   2001/01/23 04:47:57     1.4
  @@ -19,3 +19,9 @@
   managerServlet.reloaded=OK - Reloaded application at context path {0}
   managerServlet.undeployed=OK - Undeployed application at context path {0}
   webdavservlet.jaxpfailed=JAXP initialization failed
  +directory.filename=Filename
  +directory.lastModified=Last Modified
  +directory.parent=Up To {0}
  +directory.size=Size
  +directory.title=Directory Listing For {0}
  +directory.version=Tomcat Catalina version 4.1
  \ No newline at end of file
  
  
  
  1.10      +254 -101  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java
  
  Index: WebdavServlet.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- WebdavServlet.java        2001/01/18 18:57:37     1.9
  +++ WebdavServlet.java        2001/01/23 04:47:57     1.10
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java,v
 1.9 2001/01/18 18:57:37 remm Exp $
  - * $Revision: 1.9 $
  - * $Date: 2001/01/18 18:57:37 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java,v
 1.10 2001/01/23 04:47:57 remm Exp $
  + * $Revision: 1.10 $
  + * $Date: 2001/01/23 04:47:57 $
    *
    * ====================================================================
    *
  @@ -88,6 +88,11 @@
   import java.text.SimpleDateFormat;
   import java.security.MessageDigest;
   import java.security.NoSuchAlgorithmException;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.NodeList;
  +import org.w3c.dom.Element;
  +import org.w3c.dom.Document;
  +import org.xml.sax.InputSource;
   import javax.servlet.RequestDispatcher;
   import javax.servlet.ServletException;
   import javax.servlet.ServletContext;
  @@ -95,25 +100,23 @@
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  -import org.w3c.dom.Node;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.Document;
  -import org.xml.sax.InputSource;
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
   import javax.xml.parsers.ParserConfigurationException;
  -import org.apache.catalina.Resources;
  -import org.apache.catalina.core.ApplicationContext;
  -import org.apache.catalina.resources.ResourceBean;
  -import org.apache.catalina.resources.DirectoryBean;
  +import javax.naming.NamingException;
  +import javax.naming.InitialContext;
  +import javax.naming.Context;
  +import javax.naming.NamingEnumeration;
  +import javax.naming.NameClassPair;
  +import javax.naming.directory.DirContext;
  +import javax.naming.directory.Attribute;
  +import javax.naming.directory.Attributes;
  +import org.apache.naming.resources.Resource;
  +import org.apache.naming.resources.ResourceAttributes;
   import org.apache.catalina.util.MD5Encoder;
   import org.apache.catalina.util.StringManager;
   import org.apache.catalina.util.XMLWriter;
   import org.apache.catalina.util.DOMWriter;
  -import org.apache.catalina.util.xml.SaxContext;
  -import org.apache.catalina.util.xml.XmlAction;
  -import org.apache.catalina.util.xml.XmlMapper;
   
   
   /**
  @@ -121,7 +124,7 @@
    * are handled by the DefaultServlet.
    *
    * @author Remy Maucherat
  - * @version $Revision: 1.9 $ $Date: 2001/01/18 18:57:37 $
  + * @version $Revision: 1.10 $ $Date: 2001/01/23 04:47:57 $
    */
   
   public class WebdavServlet
  @@ -351,12 +354,23 @@
        resp.addHeader("DAV", "1,2");
           String methodsAllowed = null;
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  -        Resources resources = context.getResources();
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
           
  -     if (!resources.exists(path)) {
  +        boolean exists = true;
  +        Object object = null;
  +        try {
  +            object = resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
  +
  +     if (!exists) {
            methodsAllowed = "OPTIONS, MKCOL, PUT, LOCK";
               resp.addHeader("Allow", methodsAllowed);
               return;
  @@ -364,7 +378,7 @@
           
           methodsAllowed = "OPTIONS, GET, HEAD, POST, DELETE, TRACE, " 
               + "PROPFIND, PROPPATCH, COPY, MOVE, LOCK, UNLOCK";
  -        if (!resources.isCollection(path)) {
  +        if (!(object instanceof DirContext)) {
               methodsAllowed += ", PUT";
           }
           
  @@ -469,12 +483,23 @@
               
           }
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -
  -        Resources resources = context.getResources();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
  +        
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
  +        
  +        boolean exists = true;
  +        Object object = null;
  +        try {
  +            object = resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
           
  -     if (!resources.exists(path)) {
  +     if (!exists) {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
            return;
        }
  @@ -488,7 +513,7 @@
           generatedXML.writeElement(null, "multistatus" 
                                     + generateNamespaceDeclarations(), 
                                     XMLWriter.OPENING);
  -        
  +
           if (depth == 0) {
               parseProperties(req, resources, generatedXML, path, type, 
                               properties);
  @@ -506,14 +531,29 @@
                   parseProperties(req, resources, generatedXML, currentPath, 
                                   type, properties);
                   
  -                if (resources.isCollection(currentPath)) {
  -                    String[] children = 
  -                        resources.getCollectionMembers(currentPath);
  -                    
  -                    if (children != null) {
  -                        for (int i=0; i<children.length; i++) {
  -                            stackBelow.push(children[i]);
  +                try {
  +                    object = resources.lookup(currentPath);
  +                } catch (NamingException e) {
  +                    continue;
  +                }
  +                if (object instanceof DirContext) {
  +                    try {
  +                        NamingEnumeration enum = resources.list(currentPath);
  +                        while (enum.hasMoreElements()) {
  +                            NameClassPair ncPair = 
  +                                (NameClassPair) enum.nextElement();
  +                            String newPath = currentPath;
  +                            if (!newPath.equals("/"))
  +                                newPath += "/";
  +                            newPath += ncPair.getName();
  +                            stackBelow.push(newPath);
                           }
  +                    } catch (NamingException e) {
  +                        e.printStackTrace();
  +                        resp.sendError
  +                            (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
  +                             path);
  +                        return;
                       }
                       
                       if (depth > 0) {
  @@ -543,7 +583,7 @@
                   
               }
           }
  -        
  +
           generatedXML.writeElement(null, "multistatus", 
                                     XMLWriter.CLOSING);
           
  @@ -594,19 +634,35 @@
           
           String path = getRelativePath(req);
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -
  -        Resources resources = context.getResources();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
  +        
  +        boolean exists = true;
  +        Object object = null;
  +        try {
  +            object = resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
  +
        // Can't create a collection if a resource already exists at the given
           // path
  -     if (resources.exists(path)) {
  +     if (exists) {
            resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
            return;
        }
   
  -        boolean result = resources.createCollection(path);
  +        boolean result = true;
  +        try {
  +            resources.createSubcontext(path);
  +        } catch (NamingException e) {
  +            result = false;
  +        }
           
           if (!result) {
               resp.sendError(WebdavStatus.SC_CONFLICT,
  @@ -914,11 +970,22 @@
           
           lock.path = path;
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  -        Resources resources = context.getResources();
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return;
  +        }
           
  +        boolean exists = true;
  +        Object object = null;
  +        try {
  +            object = resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
  +        
           Enumeration locksList = null;
           
           if (lockRequestType == LOCK_CREATION) {
  @@ -932,7 +999,7 @@
               String lockToken = 
                   md5Encoder.encode(md5Helper.digest(lockTokenStr.getBytes()));
               
  -            if ( (resources.exists(path)) && (resources.isCollection(path)) && 
  +            if ( (exists) && (object instanceof DirContext) && 
                    (lock.depth == INFINITY) ) {
                   
                   // Locking a collection (and all its member resources)
  @@ -1058,7 +1125,7 @@
                   LockInfo presentLock = (LockInfo) resourceLocks.get(lock.path);
                   if (presentLock != null) {
                       
  -                    if ( (presentLock.isExclusive()) || (lock.isExclusive()) ) {
  +                    if ((presentLock.isExclusive()) || (lock.isExclusive())) {
                           // If either lock is exclusive, the lock can't be 
                           // granted
                           resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED);
  @@ -1074,7 +1141,13 @@
                       resourceLocks.put(lock.path, lock);
                       
                       // Checking if a resource exists at this path
  -                    if (!resources.exists(lock.path)) {
  +                    exists = true;
  +                    try {
  +                        object = resources.lookup(path);
  +                    } catch (NamingException e) {
  +                        exists = false;
  +                    }
  +                    if (!exists) {
                           
                           // "Creating" a lock-null resource
                           int slash = lock.path.lastIndexOf('/');
  @@ -1417,15 +1490,25 @@
           
           // Overwriting the destination
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  -        Resources resources = context.getResources();
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return false;
  +        }
           
  +        boolean exists = true;
  +        try {
  +            resources.lookup(destinationPath);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
  +        
           if (overwrite) {
               
               // Delete destination resource, if it exists
  -            if (resources.exists(destinationPath)) {
  +            if (exists) {
                   if (!deleteResource(destinationPath, req, resp)) {
                       return false;
                   } else {
  @@ -1438,7 +1521,7 @@
           } else {
               
               // If the destination exists, then it's a conflict
  -            if (resources.exists(destinationPath)) {
  +            if (exists) {
                   resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED);
                   return false;
               }
  @@ -1477,28 +1560,60 @@
        * @param source Path of the resource to be copied
        * @param dest Destination path
        */
  -    private boolean copyResource(Resources resources, Hashtable errorList,
  +    private boolean copyResource(DirContext resources, Hashtable errorList,
                                    String source, String dest) {
  +
  +        if (debug > 1)
  +            System.out.println("Copy: " + source + " To: " + dest);
           
  -        if (resources.isCollection(source)) {
  +        Object object = null;
  +        try {
  +            object = resources.lookup(source);
  +        } catch (NamingException e) {
  +        }
  +        
  +        if (object instanceof DirContext) {
               
  -            if (!resources.createCollection(dest)) {
  +            try {
  +                resources.createSubcontext(dest);
  +            } catch (NamingException e) {
                   errorList.put
  -                    (dest, 
  -                     new Integer(WebdavStatus.SC_CONFLICT));
  +                    (dest, new Integer(WebdavStatus.SC_CONFLICT));
                   return false;
               }
  -            String[] members = resources.getCollectionMembers(source);
  -            for (int i=0; i<members.length; i++) {
  -                String childDest = dest + 
  -                    members[i].substring(source.length());
  -                copyResource(resources, errorList, members[i], childDest);
  +            
  +            try {
  +                NamingEnumeration enum = resources.list(source);
  +                while (enum.hasMoreElements()) {
  +                    NameClassPair ncPair = (NameClassPair) enum.nextElement();
  +                    String childDest = dest;
  +                    if (!childDest.equals("/"))
  +                        childDest += "/";
  +                    childDest += ncPair.getName();
  +                    String childSrc = source;
  +                    if (!childSrc.equals("/"))
  +                        childSrc += "/";
  +                    childSrc += ncPair.getName();
  +                    copyResource(resources, errorList, childSrc, childDest);
  +                }
  +            } catch (NamingException e) {
  +                errorList.put
  +                    (dest, new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +                return false;
               }
               
           } else {
               
  -            InputStream is = resources.getResourceAsStream(source);
  -            if (!resources.setResource(dest, is)) {
  +            if (object instanceof Resource) {
  +                try {
  +                    resources.bind(dest, object);
  +                } catch (NamingException e) {
  +                    errorList.put
  +                        (source, 
  +                         new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +                    return false;
  +                }
  +            } else {
                   errorList.put
                       (source, 
                        new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  @@ -1554,20 +1669,33 @@
               return false;
           }
           
  -        // Retrieve the Catalina context
  -        ApplicationContext context = (ApplicationContext) getServletContext();
  -
  -        Resources resources = context.getResources();
  +        // Retrieve the resources
  +        DirContext resources = getResources();
           
  -     if (!resources.exists(path)) {
  +        if (resources == null) {
  +            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +            return false;
  +        }
  +        
  +        boolean exists = true;
  +        Object object = null;
  +        try {
  +            object = resources.lookup(path);
  +        } catch (NamingException e) {
  +            exists = false;
  +        }
  +        
  +     if (!exists) {
               resp.sendError(WebdavStatus.SC_NOT_FOUND);
            return false;
        }
           
  -        boolean collection = resources.isCollection(path);
  +        boolean collection = (object instanceof DirContext);
           
           if (!collection) {
  -            if (!resources.deleteResource(path)) {
  +            try {
  +                resources.unbind(path);
  +            } catch (NamingException e) {
                   resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                   return false;
               }
  @@ -1576,7 +1704,12 @@
               Hashtable errorList = new Hashtable();
               
               deleteCollection(req, resources, path, errorList);
  -            resources.deleteResource(path);
  +            try {
  +                resources.unbind(path);
  +            } catch (NamingException e) {
  +                errorList.put(path, new Integer
  +                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +            }
               
               if (!errorList.isEmpty()) {
                   
  @@ -1600,7 +1733,8 @@
        * @param path Path to the collection to be deleted
        * @param errorList Contains the list of the errors which occured
        */
  -    private void deleteCollection(HttpServletRequest req, Resources resources, 
  +    private void deleteCollection(HttpServletRequest req, 
  +                                  DirContext resources, 
                                     String path, Hashtable errorList) {
           
           String ifHeader = req.getHeader("If");
  @@ -1611,31 +1745,50 @@
           if (lockTokenHeader == null)
               lockTokenHeader = "";
           
  -        String[] members = resources.getCollectionMembers(path);
  +        Enumeration enum = null;
  +        try {
  +            enum = resources.list(path);
  +        } catch (NamingException e) {
  +            errorList.put(path, new Integer
  +                (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +            return;
  +        }
           
  -        for (int i=0; i<members.length; i++) {
  +        while (enum.hasMoreElements()) {
  +            NameClassPair ncPair = (NameClassPair) enum.nextElement();
  +            String childName = path;
  +            if (!childName.equals("/"))
  +                childName += "/";
  +            childName += ncPair.getName();
               
  -            if (isLocked(members[i], ifHeader + lockTokenHeader)) {
  +            if (isLocked(childName, ifHeader + lockTokenHeader)) {
                   
  -                errorList.put(members[i], new Integer(WebdavStatus.SC_LOCKED));
  +                errorList.put(childName, new Integer(WebdavStatus.SC_LOCKED));
                   
               } else {
  -                
  -                if (resources.isCollection(members[i])) {
  -                    deleteCollection(req, resources, members[i], errorList);
  -                }
                   
  -                boolean result = resources.deleteResource(members[i]);
  -                if (!result) {
  -                    if (!resources.isCollection(members[i])) {
  -                        // If it's not a collection, then it's an unknown
  -                        // error
  -                        errorList.put
  -                            (members[i], new Integer
  -                                (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +                try {
  +                    Object object = resources.lookup(childName);
  +                    if (object instanceof DirContext) {
  +                        deleteCollection(req, resources, childName, errorList);
  +                    }
  +                    
  +                    try {
  +                        resources.unbind(childName);
  +                    } catch (NamingException e) {
  +                        if (!(object instanceof DirContext)) {
  +                            // If it's not a collection, then it's an unknown
  +                            // error
  +                            errorList.put
  +                                (childName, new Integer
  +                                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
  +                        }
                       }
  +                } catch (NamingException e) {
  +                    errorList.put
  +                        (childName, new Integer
  +                            (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
                   }
  -                
               }
               
           }
  @@ -1711,7 +1864,7 @@
        * name, then this Vector contains those properties
        */
       private void parseProperties(HttpServletRequest req,
  -                                 Resources resources, XMLWriter generatedXML,
  +                                 DirContext resources, XMLWriter generatedXML,
                                    String path, int type, 
                                    Vector propertiesVector) {
           
  @@ -1731,15 +1884,15 @@
           // Generating href element
           generatedXML.writeElement(null, "href", XMLWriter.OPENING);
           
  -        String absoluteUri = req.getRequestURI();
  -        String relativePath = normalize(getRelativePath(req));
  -        String toAppend = path.substring(relativePath.length());
  -        if ((!toAppend.startsWith("/")) && (!absoluteUri.endsWith("/")))
  -            toAppend = "/" + toAppend;
  -        if (toAppend.equals("/"))
  -            toAppend = "";
  +        String href = req.getContextPath();
  +        if ((href.endsWith("/")) && (path.startsWith("/")))
  +            href += path.substring(1);
  +        else
  +            href += path;
  +        if ((resourceInfo.collection) && (!href.endsWith("/")))
  +            href += "/";
           
  -        generatedXML.writeText(absoluteUri + toAppend);
  +        generatedXML.writeText(rewriteUrl(href));
           
           generatedXML.writeElement(null, "href", XMLWriter.CLOSING);
           
  @@ -2004,9 +2157,9 @@
           if (!toAppend.startsWith("/"))
               toAppend = "/" + toAppend;
           
  -        generatedXML.writeText(absoluteUri + toAppend);
  +        generatedXML.writeText(rewriteUrl(absoluteUri + toAppend));
           
  -        generatedXML.writeElement("d", "href", XMLWriter.CLOSING);
  +        generatedXML.writeElement(null, "href", XMLWriter.CLOSING);
           
           switch (type) {
               
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to