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\"> \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(" "); + 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\"> </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]