You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by re...@locus.apache.org on 2000/11/22 07:20:48 UTC
cvs commit: jakarta-slide/src/webdav/server/org/apache/slide/webdav/method CopyMethod.java DeleteMethod.java GetMethod.java HeadMethod.java LockMethod.java MkcolMethod.java MoveMethod.java OptionsMethod.java PostMethod.java PropFindMethod.java PropPatchMethod.java PutMethod.java UnlockMethod.java WebdavMethod.java
remm 00/11/21 22:20:47
Added: src/webdav/server/org/apache/slide/webdav
WebdavException.java WebdavServlet.java
src/webdav/server/org/apache/slide/webdav/common
WebdavStatus.java WebdavXMLPrinter.java
src/webdav/server/org/apache/slide/webdav/method
CopyMethod.java DeleteMethod.java GetMethod.java
HeadMethod.java LockMethod.java MkcolMethod.java
MoveMethod.java OptionsMethod.java PostMethod.java
PropFindMethod.java PropPatchMethod.java
PutMethod.java UnlockMethod.java WebdavMethod.java
Log:
- Move the DAV servlet to src/webdav/server.
Revision Changes Path
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/WebdavException.java
Index: WebdavException.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/WebdavException.java,v 1.1 2000/11/22 06:20:45 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:45 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav;
import java.io.Writer;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.SlideException;
import org.apache.slide.webdav.common.WebdavStatus;
/**
* Webdav exception class.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class WebdavException extends SlideException {
// ----------------------------------------------------- Instance Variables
/**
* HTTP status code associated with the exception.
*/
protected int statusCode;
// ----------------------------------------------------------- Constructors
/**
* Constructor.
*
* @param statusCode Exception status code
*/
public WebdavException(int statusCode) {
super(WebdavStatus.getStatusText(statusCode));
this.statusCode = statusCode;
}
// --------------------------------------------------------- Public Methods
/**
* Returns an HTTP formatted error page.
*
* @param resp HTTP servlet response
*/
public void writeErrorPage(HttpServletResponse resp) {
try {
Writer writer = resp.getWriter();
} catch (IOException e) {
}
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/WebdavServlet.java
Index: WebdavServlet.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/WebdavServlet.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav;
import java.io.*;
import java.util.*;
import java.security.Principal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import org.apache.slide.webdav.method.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.structure.*;
import org.apache.slide.common.*;
import org.apache.slide.util.conf.*;
import org.apache.slide.authenticate.SecurityToken;
/**
* WebDAV Servlet.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class WebdavServlet extends HttpServlet {
// -------------------------------------------------------------- Constants
/**
* HTTP Date format pattern (RFC 2068, 822, 1123).
*/
public static final String DATE_FORMAT = "EEE, d MMM yyyy kk:mm:ss z";
/**
* Date formatter.
*/
private static final DateFormat formatter =
new SimpleDateFormat(DATE_FORMAT);
// ----------------------------------------------------- Instance Variables
/**
* Access token to the namespace.
*/
NamespaceAccessToken token;
// -------------------------------------------------------- Private Methods
/**
* Show HTTP header information.
*/
private void showRequestInfo(HttpServletRequest req) {
System.out.println();
System.out.println("SlideDAV Request Info");
System.out.println();
// Show generic info
System.out.println("Encoding : " + req.getCharacterEncoding());
System.out.println("Length : " + req.getContentLength());
System.out.println("Type : " + req.getContentType());
System.out.println();
System.out.println("Parameters");
Enumeration parameters = req.getParameterNames();
while (parameters.hasMoreElements()) {
String paramName = (String) parameters.nextElement();
String[] values = req.getParameterValues(paramName);
System.out.print(paramName + " : ");
for (int i = 0; i < values.length; i++) {
System.out.print(values[i] + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("Protocol : " + req.getProtocol());
System.out.println("Address : " + req.getRemoteAddr());
System.out.println("Host : " + req.getRemoteHost());
System.out.println("Scheme : " + req.getScheme());
System.out.println("Server Name : " + req.getServerName());
System.out.println("Server Port : " + req.getServerPort());
System.out.println();
System.out.println("Attributes");
Enumeration attributes = req.getAttributeNames();
while (attributes.hasMoreElements()) {
String attributeName = (String) attributes.nextElement();
System.out.print(attributeName + " : ");
System.out.println(req.getAttribute(attributeName).toString());
}
System.out.println();
// Show HTTP info
System.out.println();
System.out.println("HTTP Header Info");
System.out.println();
System.out.println("Authentication Type : " + req.getAuthType());
System.out.println("HTTP Method : " + req.getMethod());
System.out.println("Path Info : " + req.getPathInfo());
System.out.println("Path translated : " + req.getPathTranslated());
System.out.println("Query string : " + req.getQueryString());
System.out.println("Remote user : " + req.getRemoteUser());
System.out.println("Requested session id : "
+ req.getRequestedSessionId());
System.out.println("Request URI : " + req.getRequestURI());
System.out.println("Context path : " + req.getContextPath());
System.out.println("Servlet path : " + req.getServletPath());
System.out.println("User principal : " + req.getUserPrincipal());
System.out.println();
System.out.println("Headers : ");
Enumeration headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
String headerName = (String) headers.nextElement();
System.out.print(headerName + " : ");
System.out.println(req.getHeader(headerName));
}
// Show session info
HttpSession session = req.getSession(false);
System.out.println();
System.out.println("End Request Info");
System.out.println();
System.out.println();
}
/**
* Create Slide Method form the HTTP Method.
*
* @return WebdavMethod
* @exception WebdavException
*/
private WebdavMethod createWebdavMethod
(HttpServletRequest req, HttpServletResponse resp)
throws WebdavException {
String methodName = req.getMethod();
WebdavMethod resultMethod = null;
if (methodName.equalsIgnoreCase("GET")) {
resultMethod = new GetMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("PROPFIND")) {
resultMethod = new PropFindMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("HEAD")) {
resultMethod = new HeadMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("LOCK")) {
resultMethod = new LockMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("UNLOCK")) {
resultMethod = new UnlockMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("OPTIONS")) {
resultMethod = new OptionsMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("PUT")) {
resultMethod = new PutMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("MKCOL")) {
resultMethod = new MkcolMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("POST")) {
resultMethod = new PostMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("COPY")) {
resultMethod = new CopyMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("MOVE")) {
resultMethod = new MoveMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("DELETE")) {
resultMethod = new DeleteMethod(this, token, req, resp);
} else if (methodName.equalsIgnoreCase("PROPPATCH")) {
resultMethod = new PropPatchMethod(this, token, req, resp);
}
if (resultMethod == null) {
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
return resultMethod;
}
// -------------------------------------------------------- Servlet Methods
protected void service (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//showRequestInfo(req);
resp.setStatus(WebdavStatus.SC_OK);
WebdavMethod method = null;
try {
//System.out.println(System.currentTimeMillis"Parsing request");
method = createWebdavMethod(req, resp);
method.run();
} catch (WebdavException e) {
// There has been an error somewhere ...
// TODO : Show error page.
System.out.println(e.getMessage());
} catch (Throwable e) {
// If something goes really wrong ...
e.printStackTrace();
}
}
/**
* Manages some initialization stuff on the server.
*/
public void init()
throws ServletException {
String namespaceName = "webdav";
String domainConfigFile = "/Domain.xml";
String managerServletPath = "/manager/";
String value = null;
try {
value = getServletConfig().getInitParameter("namespace");
if (value != null)
namespaceName = value;
} catch (Throwable t) {
;
}
try {
value = getServletConfig().getInitParameter("domain");
if (value != null)
domainConfigFile = value;
} catch (Throwable t) {
;
}
try {
value = getServletConfig().getInitParameter("manager");
if (value != null)
managerServletPath = value;
} catch (Throwable t) {
;
}
WebdavMethod.init(managerServletPath);
if (!Domain.isInitialized()) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
InputStream is =
getServletContext().getResourceAsStream(domainConfigFile);
if (is == null)
throw new ServletException("Can't find init file");
Populate pop = new Populate();
Configuration slideConfiguration =
new ConfigurationElement(pop.load(new InputSource(is),
parser.getParser()));
Domain.init(slideConfiguration);
} catch (Throwable t) {
t.printStackTrace();
throw new ServletException(t.getMessage());
}
}
token = Domain.accessNamespace(new SecurityToken(this), namespaceName);
}
/**
* Destroy servlet.
*/
public void destroy() {
Domain.closeNamespace(token);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/WebdavStatus.java
Index: WebdavStatus.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/WebdavStatus.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.common;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import org.apache.slide.common.*;
/**
* Extended HTTP protocols used by WebDAV.
*
* @author Marc Eaddy
* @version $Revision: 1.1 $
*/
public class WebdavStatus {
/**
* This Hashtable contains the mapping of HTTP and WebDAV
* status codes to descriptive text. This is a static
* variable.
*/
private static Hashtable mapStatusCodes = new Hashtable();
/**
* Adds a new status code -> status text mapping. This is a static
* method because the mapping is a static variable.
*
* @param nKey [IN] HTTP or WebDAV status code
* @param strVal [IN] HTTP status text
*/
private static void addStatusCodeMap(int nKey, String strVal) {
mapStatusCodes.put(new Integer(nKey), strVal);
}
/**
* Returns the HTTP status text for the HTTP or WebDav status code
* specified by looking it up in the static mapping. This is a
* static function.
*
* @param nHttpStatusCode [IN] HTTP or WebDAV status code
* @return A string with a short descriptive phrase for the
* HTTP status code (e.g., "OK").
*/
public static String getStatusText(int nHttpStatusCode) {
Integer intKey = new Integer(nHttpStatusCode);
if (!mapStatusCodes.containsKey(intKey)) {
// DANGER!!! - RECURSIVE!!!
return getStatusText(SC_INTERNAL_SERVER_ERROR);
} else {
return (String) mapStatusCodes.get(intKey);
}
}
/*
* HTTP 1.0 Server status codes; see RFC 1945.
*/
/**
* Status code (200) indicating the request succeeded normally.
*/
public static final int SC_OK = HttpServletResponse.SC_OK;
/**
* Status code (201) indicating the request succeeded and created
* a new resource on the server.
*/
public static final int SC_CREATED = HttpServletResponse.SC_CREATED;
/**
* Status code (202) indicating that a request was accepted for
* processing, but was not completed.
*/
public static final int SC_ACCEPTED = HttpServletResponse.SC_ACCEPTED;
/**
* Status code (204) indicating that the request succeeded but that
* there was no new information to return.
*/
public static final int SC_NO_CONTENT = HttpServletResponse.SC_NO_CONTENT;
/**
* Status code (301) indicating that the resource has permanently
* moved to a new location, and that future references should use a
* new URI with their requests.
*/
public static final int SC_MOVED_PERMANENTLY = HttpServletResponse.SC_MOVED_PERMANENTLY;
/**
* Status code (302) indicating that the resource has temporarily
* moved to another location, but that future references should
* still use the original URI to access the resource.
*/
public static final int SC_MOVED_TEMPORARILY = HttpServletResponse.SC_MOVED_TEMPORARILY;
/**
* Status code (304) indicating that a conditional GET operation
* found that the resource was available and not modified.
*/
public static final int SC_NOT_MODIFIED = HttpServletResponse.SC_NOT_MODIFIED;
/**
* Status code (400) indicating the request sent by the client was
* syntactically incorrect.
*/
public static final int SC_BAD_REQUEST = HttpServletResponse.SC_BAD_REQUEST;
/**
* Status code (401) indicating that the request requires HTTP
* authentication.
*/
public static final int SC_UNAUTHORIZED = HttpServletResponse.SC_UNAUTHORIZED;
/**
* Status code (403) indicating the server understood the request
* but refused to fulfill it.
*/
public static final int SC_FORBIDDEN = HttpServletResponse.SC_FORBIDDEN;
/**
* Status code (404) indicating that the requested resource is not
* available.
*/
public static final int SC_NOT_FOUND = HttpServletResponse.SC_NOT_FOUND;
/**
* Status code (500) indicating an error inside the HTTP service
* which prevented it from fulfilling the request.
*/
public static final int SC_INTERNAL_SERVER_ERROR = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
/**
* Status code (501) indicating the HTTP service does not support
* the functionality needed to fulfill the request.
*/
public static final int SC_NOT_IMPLEMENTED = HttpServletResponse.SC_NOT_IMPLEMENTED;
/**
* Status code (502) indicating that the HTTP server received an
* invalid response from a server it consulted when acting as a
* proxy or gateway.
*/
public static final int SC_BAD_GATEWAY = HttpServletResponse.SC_BAD_GATEWAY;
/**
* Status code (503) indicating that the HTTP service is
* temporarily overloaded, and unable to handle the request.
*/
public static final int SC_SERVICE_UNAVAILABLE = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
/*
* HTTP 1.1 Server status codes; see RFC 2048. When JWS supports HTTP 1.1 we
* will use the appropriate HttpServletRespones status codes.
*/
/**
* Status code (100) indicating the client may continue with
* its request. This interim response is used to inform the
* client that the initial part of the request has been
* received and has not yet been rejected by the server.
*/
public static final int SC_CONTINUE = 100;
/**
* Status code (405) indicating the method specified is not
* allowed for the resource.
*/
public static final int SC_METHOD_NOT_ALLOWED = 405;
/**
* Status code (409) indicating that the request could not be
* completed due to a conflict with the current state of the
* resource.
*/
public static final int SC_CONFLICT = 409;
/**
* Status code (412) indicating the precondition given in one
* or more of the request-header fields evaluated to false
* when it was tested on the server.
*/
public static final int SC_PRECONDITION_FAILED = 412;
/**
* Status code (413) indicating the server is refusing to
* process a request because the request entity is larger
* than the server is willing or able to process.
*/
public static final int SC_REQUEST_TOO_LONG = 413;
/**
* Status code (415) indicating the server is refusing to service
* the request because the entity of the request is in a format
* not supported by the requested resource for the requested
* method.
*/
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
/*
* Extended WebDAV HTTP status codes; see <draft-ietf-webdav-protocol-05>.
*/
/**
* Status code (207) indicating that the response requires
* providing status for multiple independent operations.
*/
public static final int SC_MULTI_STATUS = 207;
// This one colides with HTTP 1.1
// "207 Parital Update OK"
/**
* Status code (418) indicating the entity body submitted with
* the PATCH method was not understood by the resource.
*/
public static final int SC_UNPROCESSABLE_ENTITY = 418;
// This one colides with HTTP 1.1
// "418 Reauthentication Required"
/**
* Status code (419) indicating that the resource does not have
* sufficient space to record the state of the resource after the
* execution of this method.
*/
public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419;
// This one colides with HTTP 1.1
// "419 Proxy Reauthentication Required"
/**
* Status code (420) indicating the method was not executed on
* a particular resource within its scope because some part of
* the method's execution failed causing the entire method to be
* aborted.
*/
public static final int SC_METHOD_FAILURE = 420;
/**
* Status code (423) indicating the destination resource of a
* method is locked, and either the request did not contain a
* valid Lock-Info header, or the Lock-Info header identifies
* a lock held by another principal.
*/
public static final int SC_LOCKED = 423;
static {
// HTTP 1.0 Server status codes -- see RFC 1945
addStatusCodeMap(SC_OK, "OK");
addStatusCodeMap(SC_CREATED, "Created");
addStatusCodeMap(SC_ACCEPTED, "Accepted");
addStatusCodeMap(SC_NO_CONTENT, "No Content");
addStatusCodeMap(SC_MOVED_PERMANENTLY, "Moved Permanently");
addStatusCodeMap(SC_MOVED_TEMPORARILY, "Moved Temporarily");
addStatusCodeMap(SC_NOT_MODIFIED, "Not Modified");
addStatusCodeMap(SC_BAD_REQUEST, "Bad Request");
addStatusCodeMap(SC_UNAUTHORIZED, "Unauthorized");
addStatusCodeMap(SC_FORBIDDEN, "Forbidden");
addStatusCodeMap(SC_NOT_FOUND, "Not Found");
addStatusCodeMap(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
addStatusCodeMap(SC_NOT_IMPLEMENTED, "Not Implemented");
addStatusCodeMap(SC_BAD_GATEWAY, "Bad Gateway");
addStatusCodeMap(SC_SERVICE_UNAVAILABLE, "Service Unavailable");
// HTTP 1.1 Server status codes -- see RFC 2048
addStatusCodeMap(SC_CONTINUE, "Continue");
addStatusCodeMap(SC_METHOD_NOT_ALLOWED, "Method Not Allowed");
addStatusCodeMap(SC_CONFLICT, "Conflict");
addStatusCodeMap(SC_PRECONDITION_FAILED, "Precondition Failed");
addStatusCodeMap(SC_REQUEST_TOO_LONG, "Request Too Long");
addStatusCodeMap(SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
// WebDav Server-specific status codes
addStatusCodeMap(SC_MULTI_STATUS, "Multi-Status");
addStatusCodeMap(SC_UNPROCESSABLE_ENTITY, "Unprocessable Entity");
addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE, "Insufficient Space On Resource");
addStatusCodeMap(SC_METHOD_FAILURE, "Method Failure");
addStatusCodeMap(SC_LOCKED, "Locked");
}
};
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/WebdavXMLPrinter.java
Index: WebdavXMLPrinter.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/WebdavXMLPrinter.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.common;
/**
* WebdavXMLPrinter helper class.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class WebdavXMLPrinter {
// -------------------------------------------------------------- Constants
/**
* Opening tag.
*/
public static final int OPENING = 0;
/**
* Closing tag.
*/
public static final int CLOSING = 1;
/**
* Element with no content.
*/
public static final int NO_CONTENT = 2;
// ----------------------------------------------------- Instance Variables
/**
* Buffer.
*/
protected StringBuffer buffer;
// ----------------------------------------------------------- Constructors
/**
* Constructor.
*/
public WebdavXMLPrinter() {
buffer = new StringBuffer();
}
// --------------------------------------------------------- Public Methods
/**
* Retrieve generated XML.
*
* @return String containing the generated XML
*/
public String toString() {
return buffer.toString();
}
/**
* Write property to the XML.
*
* @param namespace Namespace
* @param namespaceInfo Namespace info
* @param name Property name
* @param value Property value
*/
public void writeProperty(String namespace, String namespaceInfo,
String name, String value) {
writeElement(namespace, namespaceInfo, name, OPENING);
buffer.append(value);
writeElement(namespace, namespaceInfo, name, CLOSING);
}
/**
* Write property to the XML.
*
* @param namespace Namespace
* @param name Property name
* @param value Property value
*/
public void writeProperty(String namespace, String name, String value) {
writeElement(namespace, name, OPENING);
buffer.append(value);
writeElement(namespace, name, CLOSING);
}
/**
* Write property to the XML.
*
* @param namespace Namespace
* @param name Property name
*/
public void writeProperty(String namespace, String name) {
writeElement(namespace, name, NO_CONTENT);
}
/**
* Write an element.
*
* @param name Element name
* @param namespace Namespace abbreviation
* @param type Element type
*/
public void writeElement(String namespace, String name, int type) {
writeElement(namespace, null, name, type);
}
/**
* Write an element.
*
* @param namespace Namespace abbreviation
* @param namespaceInfo Namespace info
* @param name Element name
* @param type Element type
*/
public void writeElement(String namespace, String namespaceInfo,
String name, int type) {
if ((namespace != null) && (namespace.length() > 0)) {
switch (type) {
case OPENING:
if (namespaceInfo != null) {
buffer.append("<" + namespace + ":" + name + " xmlns:"
+ namespace + "=\""
+ namespaceInfo + "\">");
} else {
buffer.append("<" + namespace + ":" + name + ">");
}
break;
case CLOSING:
buffer.append("</" + namespace + ":" + name + ">\n");
break;
case NO_CONTENT:
default:
if (namespaceInfo != null) {
buffer.append("<" + namespace + ":" + name + " xmlns:"
+ namespace + "=\""
+ namespaceInfo + "\"/>");
} else {
buffer.append("<" + namespace + ":" + name + "/>");
}
break;
}
} else {
switch (type) {
case OPENING:
buffer.append("<" + name + ">");
break;
case CLOSING:
buffer.append("</" + name + ">\n");
break;
case NO_CONTENT:
default:
buffer.append("<" + name + "/>");
break;
}
}
}
/**
* Write text.
*
* @param text Text to append
*/
public void writeText(String text) {
buffer.append(text);
}
/**
* Write XML Header.
*/
public void writeXMLHeader() {
buffer.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java
Index: CopyMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;
/**
* COPY Method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class CopyMethod extends WebdavMethod {
// ----------------------------------------------------- Instance Variables
/**
* Id of the resosurce or collection which is to be copied.
*/
private String sourceUri;
/**
* Uri of the target.
*/
private String destinationUri;
/**
* Overwrite.
*/
private boolean overwrite;
// ----------------------------------------------------------- Constructors
/**
* COPY method constructor.
*
* @param token Namespace access token
* @param requestUri Request URI
* @param principal Principal object, given by the servlet container
* @param req HTTP request
* @param resp HTTP response
*/
public CopyMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse request.
*
* @exception WebdavException Does not happen
*/
protected void parseRequest()
throws WebdavException {
sourceUri = requestUri;
if (sourceUri == null) {
sourceUri = "/";
}
destinationUri = req.getHeader("Destination");
String HTTPHeader = "http://";
if (destinationUri.startsWith(HTTPHeader)) {
destinationUri = destinationUri.substring(HTTPHeader.length());
}
String hostName = req.getServerName();
if ((hostName != null) && (destinationUri.startsWith(hostName))) {
destinationUri = destinationUri.substring(hostName.length());
}
if (destinationUri.startsWith(":")) {
int firstSeparator = destinationUri.indexOf("/");
if (firstSeparator < 0) {
destinationUri = "/";
} else {
destinationUri = destinationUri.substring(firstSeparator);
}
}
String contextPath = req.getContextPath();
if ((contextPath != null) &&
(destinationUri.startsWith(contextPath))) {
destinationUri = destinationUri.substring(contextPath.length());
}
String pathInfo = req.getPathInfo();
if (pathInfo != null) {
String servletPath = req.getServletPath();
if ((servletPath != null) &&
(destinationUri.startsWith(servletPath))) {
destinationUri = destinationUri
.substring(servletPath.length());
}
}
String overwriteHeader = req.getHeader("Overwrite");
if (overwriteHeader != null) {
if (overwriteHeader.equalsIgnoreCase("T")) {
overwrite = true;
} else {
overwrite = false;
}
} else {
overwrite = true;
}
}
/**
* Execute request.
*
* @exception WebdavException Unrecoverable error occured while copying
*/
protected void executeRequest()
throws WebdavException {
MacroParameters macroParameters = null;
String status = null;
if (overwrite) {
macroParameters = Macro.RECURSIVE_OVERWRITE_PARAMETERS;
} else {
macroParameters = Macro.DEFAULT_PARAMETERS;
}
try {
macro.copy(credToken, sourceUri, destinationUri, macroParameters);
if (overwrite) {
resp.setStatus(WebdavStatus.SC_NO_CONTENT);
} else {
resp.setStatus(WebdavStatus.SC_CREATED);
}
} catch (CopyMacroException e) {
String errorMessage = generateErrorMessage(e);
// Write it on the servlet writer
//status = new String("HTTP/1.1 " + WebdavStatus.SC_MULTI_STATUS
//+ " " + WebdavStatus.getStatusText
//(WebdavStatus.SC_MULTI_STATUS));
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
try {
resp.getWriter().write(errorMessage);
} catch(IOException ex) {
// Critical error ... Servlet container is dead or something
ex.printStackTrace();
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
} catch(DeleteMacroException e) {
resp.setStatus(WebdavStatus.SC_PRECONDITION_FAILED);
}
}
/**
* Generate an XML error message.
*
* @param macroException Nested exception
* @return String XML message
*/
protected String generateErrorMessage(CopyMacroException macroException) {
WebdavXMLPrinter errorMessage = new WebdavXMLPrinter();
errorMessage.writeXMLHeader();
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.OPENING);
Enumeration nestedExceptionsList = macroException
.enumerateExceptions();
while (nestedExceptionsList.hasMoreElements()) {
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.OPENING);
SlideException ex = (SlideException) nestedExceptionsList
.nextElement();
String status = new String();
try {
throw ex;
} catch(ObjectNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(AccessDeniedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_FORBIDDEN);
} catch(ObjectAlreadyExistsException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ServiceAccessException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_BAD_GATEWAY);
} catch(LinkedObjectNotFoundException e) {
generateStatusText(errorMessage, e.getTargetUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(RevisionNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ObjectLockedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_LOCKED);
} catch(SlideException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.CLOSING);
}
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.CLOSING);
return errorMessage.toString();
}
/**
* Generate status text.
*
* @param printer XML Printer
* @param href Uri of the object
* @param statusCode HTTP status code of the error
*/
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
printer.writeText(href);
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
+ WebdavStatus.getStatusText(statusCode));
printer.writeElement("d", "status", WebdavXMLPrinter.CLOSING);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java
Index: DeleteMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;
/**
* DELETE method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class DeleteMethod extends WebdavMethod {
// ----------------------------------------------------- Instance Variables
/**
* Id of the resosurce or collection which is to be deleted.
*/
private String toDelete;
// ----------------------------------------------------------- Constructors
/**
* DELETE method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public DeleteMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse request.
*
* @exception WebdavException Does not happen
*/
protected void parseRequest()
throws WebdavException {
toDelete = requestUri;
if (toDelete == null) {
toDelete = "/";
}
}
/**
* Execute request.
*
* @exception WebdavException Unrecoverable error while deleting
*/
protected void executeRequest()
throws WebdavException {
try {
macro.delete(credToken, toDelete);
resp.setStatus(WebdavStatus.SC_NO_CONTENT);
} catch (DeleteMacroException e) {
String errorMessage = generateErrorMessage(e);
// Write it on the servlet writer
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
try {
resp.getWriter().write(errorMessage);
} catch(IOException ex) {
// Critical error ... Servlet container is dead or something
ex.printStackTrace();
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
}
/**
* Generate an XML error message.
*
* @param macroException Nested exception
* @return String XML message
*/
protected String generateErrorMessage
(DeleteMacroException macroException) {
WebdavXMLPrinter errorMessage = new WebdavXMLPrinter();
errorMessage.writeXMLHeader();
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.OPENING);
Enumeration nestedExceptionsList =
macroException.enumerateExceptions();
while (nestedExceptionsList.hasMoreElements()) {
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.OPENING);
SlideException ex =
(SlideException) nestedExceptionsList.nextElement();
String status = new String();
try {
throw ex;
} catch(ObjectNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(AccessDeniedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_FORBIDDEN);
} catch(ObjectAlreadyExistsException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ServiceAccessException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_BAD_GATEWAY);
} catch(LinkedObjectNotFoundException e) {
generateStatusText(errorMessage, e.getTargetUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(RevisionNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ObjectLockedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_LOCKED);
} catch(SlideException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.CLOSING);
}
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.CLOSING);
return errorMessage.toString();
}
/**
* Generate status text.
*
* @param printer XML Printer
* @param href Uri of the object
* @param statusCode HTTP status code of the error
*/
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
printer.writeText(href);
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
+ WebdavStatus.getStatusText(statusCode));
printer.writeElement("d", "status", WebdavXMLPrinter.CLOSING);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java
Index: GetMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.util.Messages;
import org.apache.slide.content.*;
import org.apache.slide.lock.*;
import org.apache.slide.security.*;
import org.apache.slide.structure.*;
/**
* GET method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class GetMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
protected final int BUFFER_SIZE = 2048;
/**
* The set of SimpleDateFormat formats to use in getDateHeader().
*/
protected static final SimpleDateFormat formats[] = {
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
};
/**
* MIME multipart separation string
*/
protected static final String mimeSeparation = "SLIDE_MIME_BOUNDARY";
/**
* The input buffer size to use when serving resources.
*/
protected int input = 2048;
/**
* The output buffer size to use when serving resources.
*/
protected int output = 2048;
/**
* Print content.
*/
protected boolean printContent = true;
// ----------------------------------------------------- Instance Variables
/**
* Resource to be retrieved.
*/
private String resourcePath;
// ----------------------------------------------------------- Constructors
/**
* GET Method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public GetMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse XML request.
*/
protected void parseRequest()
throws WebdavException {
resourcePath = requestUri;
if (resourcePath == null) {
resourcePath = "/";
}
}
/**
* Execute request.
*
* @exception WebdavException Can't access resource
*/
protected void executeRequest()
throws WebdavException {
try {
// Then we must get object contents ...
ObjectNode object = structure.retrieve(credToken, resourcePath);
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, resourcePath);
if (revisionDescriptors.hasRevisions()) {
// Retrieve latest revision descriptor
NodeRevisionDescriptor revisionDescriptor =
content.retrieve(credToken, revisionDescriptors);
if (isCollection(revisionDescriptor)) {
Writer writer = resp.getWriter();
resp.setContentType("text/html");
displayDirectoryBrowsing(object, writer);
writer.close();
} else {
ResourceInfo resourceInfo =
new ResourceInfo(resourcePath, revisionDescriptor);
// Checking If headers
if (!checkIfHeaders(req, resp, resourceInfo))
return;
ServletOutputStream os = resp.getOutputStream();
NodeRevisionContent revisionContent =
content.retrieve(credToken, revisionDescriptors,
revisionDescriptor);
InputStream is = null;
if (printContent) {
is = content.retrieve
(credToken, revisionDescriptors,
revisionDescriptor).streamContent();
}
Vector ranges = parseRange(req, resp, resourceInfo);
// ETag header
resp.setHeader("ETag", getETag(resourceInfo, true));
resp.addHeader
("Last-Modified",
revisionDescriptor.getCreationDate().toString());
if ( ((ranges == null) || (ranges.isEmpty()))
&& (req.getHeader("Range") == null) ) {
resp.setContentType
(revisionDescriptor.getContentType());
resp.setContentLength
((int) revisionDescriptor.getContentLength());
// Copy the input stream to our output stream
// (if requested)
if (printContent) {
resp.setBufferSize(output);
copy(resourceInfo, is, os);
}
} else {
if ((ranges == null) || (ranges.isEmpty()))
return;
// Partial content response.
resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
if (ranges.size() == 1) {
Range range = (Range) ranges.elementAt(0);
resp.addHeader("Content-Range", "bytes "
+ range.start
+ "-" + range.end + "/"
+ range.length);
resp.setContentType
(revisionDescriptor.getContentType());
if (printContent) {
resp.setBufferSize(output);
copy(resourceInfo, is, os, range);
}
} else {
resp.setContentType
("multipart/byteranges; boundary="
+ mimeSeparation);
if (printContent) {
resp.setBufferSize(output);
copy(resourceInfo, is, os,
ranges.elements(),
revisionDescriptor.getContentType());
}
}
}
}
} else {
Writer writer = resp.getWriter();
resp.setContentType("text/html");
displayDirectoryBrowsing(object, writer);
writer.close();
}
} catch (RevisionNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (RevisionContentNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (ObjectLockedException e) {
// Locked
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_LOCKED);
} catch (RevisionDescriptorNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (ObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (LinkedObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (AccessDeniedException e) {
// 403 - Forbidden
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
} catch (ServiceAccessException e) {
// 500 - Internal server error
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (IOException e) {
e.printStackTrace();
// Unable to write to output stream.
// 500 - Internal server error
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (RuntimeException e) {
e.printStackTrace();
// 500 - Internal server error
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
/**
* Display a directory browsing page.
*/
protected void displayDirectoryBrowsing(ObjectNode object,
Writer servletWriter)
throws IOException {
String contextPath = req.getContextPath();
if (contextPath == null)
contextPath = "";
String name = object.getUri();
// Number of characters to trim from the beginnings of filenames
int trim = name.length();
if (!name.endsWith("/"))
trim += 1;
if (name.equals("/"))
trim = 1;
PrintWriter writer = new PrintWriter(servletWriter);
// Render the page header
writer.print("<html>\r\n");
writer.print("<head>\r\n");
writer.print("<title>");
writer.print
(Messages.format
("org.apache.slide.webdav.GetMethod.directorylistingfor", 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
(Messages.format
("org.apache.slide.webdav.GetMethod.directorylistingfor", 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=\"5\" bgcolor=\"#ffffff\">\r\n");
writer.print("<a href=\"");
writer.print(rewriteUrl(contextPath));
if (parent.equals(""))
parent = "/";
writer.print(parent);
writer.print("\">");
writer.print(Messages.format
("org.apache.slide.webdav.GetMethod.parent", parent));
writer.print("</a>\r\n");
writer.print("</td></tr>\r\n");
}
Enumeration permissionsList = null;
Enumeration locksList = null;
try {
permissionsList =
security.enumeratePermissions(credToken, object.getUri());
locksList = lock.enumerateLocks(credToken, object.getUri());
} catch (SlideException e) {
// Any security based exception will be trapped here
// Any locking based exception will be trapped here
}
// Displaying ACL info
displayPermissions(permissionsList, writer, false);
// Displaying lock info
displayLocks(locksList, writer, false);
writer.print("<tr><td colspan=\"5\" bgcolor=\"#ffffff\">");
writer.print(" ");
writer.print("</td></tr>\r\n");
// Render the column headings
writer.print("<tr bgcolor=\"#cccccc\">\r\n");
writer.print("<td align=\"left\" colspan=\"3\">");
writer.print("<font size=\"+1\"><strong>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.filename"));
writer.print("</strong></font></td>\r\n");
writer.print("<td align=\"center\"><font size=\"+1\"><strong>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.size"));
writer.print("</strong></font></td>\r\n");
writer.print("<td align=\"right\"><font size=\"+1\"><strong>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.lastModified"));
writer.print("</strong></font></td>\r\n");
writer.print("</tr>\r\n");
Enumeration resources = object.enumerateChildren();
boolean shade = false;
while (resources.hasMoreElements()) {
String currentResource = (String) resources.nextElement();
NodeRevisionDescriptor currentDescriptor = null;
permissionsList = null;
locksList = null;
try {
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, currentResource);
// Retrieve latest revision descriptor
currentDescriptor =
content.retrieve(credToken, revisionDescriptors);
} catch (SlideException e) {
// Silent exception : Objects without any revision are
// considered collections, and do not have any attributes
// Any security based exception will be trapped here
// Any locking based exception will be trapped here
}
try {
permissionsList =
security.enumeratePermissions(credToken, currentResource);
locksList = lock.enumerateLocks(credToken, currentResource);
} catch (SlideException e) {
// Any security based exception will be trapped here
// Any locking based exception will be trapped here
}
String trimmed = currentResource.substring(trim);
if (trimmed.equalsIgnoreCase("WEB-INF") ||
trimmed.equalsIgnoreCase("META-INF"))
continue;
writer.print("<tr");
if (shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
shade = !shade;
writer.print("<td align=\"left\" colspan=\"3\"> \r\n");
writer.print("<a href=\"");
writer.print(rewriteUrl(contextPath));
writer.print(rewriteUrl(currentResource));
writer.print("\"><tt>");
writer.print(trimmed);
if (isCollection(currentDescriptor)) {
writer.print("/");
}
writer.print("</tt></a></td>\r\n");
writer.print("<td align=\"right\"><tt>");
if (isCollection(currentDescriptor))
writer.print(" ");
else
writer.print(renderSize(currentDescriptor.getContentLength()));
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
if (currentDescriptor != null) {
writer.print(currentDescriptor.getLastModified());
} else {
writer.print(" ");
}
writer.print("</tt></td>\r\n");
writer.print("</tr>\r\n");
// Displaying ACL info
displayPermissions(permissionsList, writer, shade);
// Displaying lock info
displayLocks(locksList, writer, shade);
}
// Render the page footer
writer.print("<tr><td colspan=\"5\"> </td></tr>\r\n");
writer.print("<tr><td colspan=\"3\" bgcolor=\"#cccccc\">");
writer.print("<font size=\"-1\">");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.version"));
writer.print("</font></td>\r\n");
writer.print("<td colspan=\"2\" align=\"right\" bgcolor=\"#cccccc\">");
writer.print("<font size=\"-1\">");
writer.print(formats[0].format(new Date()));
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();
}
/**
* Display an ACL list.
*
* @param permissionsList List of NodePermission objects
* @param boolean Shade
* @param writer The output will be appended to this writer
*/
private void displayPermissions(Enumeration permissionsList,
PrintWriter writer,
boolean shade)
throws IOException {
if ((permissionsList != null) && (permissionsList.hasMoreElements())) {
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
writer.print("<td align=\"left\" colspan=\"5\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.aclinfo"));
writer.print("</b></tt></td>\r\n");
writer.print("</tr>\r\n");
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
writer.print("<td align=\"left\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.subject"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"left\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.action"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.inheritable"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.deny"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print("<a href=\"");
if (req.getContextPath() != null) {
writer.print(req.getContextPath());
}
writer.print(managerServletPath + token.getName()
+ "?command=addacl\">");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.add"));
writer.print("</a>");
writer.print("</b></tt></td>\r\n");
writer.print("</tr>\r\n");
while (permissionsList.hasMoreElements()) {
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
NodePermission currentPermission =
(NodePermission) permissionsList.nextElement();
writer.print("<td align=\"left\"><tt>");
writer.print(currentPermission.getSubjectUri());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"left\"><tt>");
writer.print(currentPermission.getActionUri());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
writer.print(currentPermission.isInheritable());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
writer.print(currentPermission.isNegative());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print("<a href=\"");
if (req.getContextPath() != null) {
writer.print(req.getContextPath());
}
writer.print(managerServletPath + token.getName()
+ "?command=removeacl"
+ "&object=" + currentPermission.getObjectUri()
+ "&subject=" + currentPermission.getSubjectUri()
+ "&action=" + currentPermission.getActionUri()
+ "\">");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.remove"));
writer.print("</a>");
writer.print("</b></tt></td>\r\n");
writer.print("</tr>\r\n");
}
}
}
/**
* Display a lock list.
*
* @param locksList List of NodeLock objects
* @param boolean Shade
* @param writer The output will be appended to this writer
*/
private void displayLocks(Enumeration locksList, PrintWriter writer,
boolean shade)
throws IOException {
if ((locksList != null) && (locksList.hasMoreElements())) {
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
writer.print("<td align=\"left\" colspan=\"5\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.locksinfo"));
writer.print("</b></tt></td>\r\n");
writer.print("</tr>\r\n");
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
writer.print("<td align=\"left\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.subject"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"left\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.type"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.expiration"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.inheritable"));
writer.print("</b></tt></td>\r\n");
writer.print("<td align=\"right\"><tt><b>");
writer.print(Messages.message
("org.apache.slide.webdav.GetMethod.exclusive"));
writer.print("</b></tt></td>\r\n");
writer.print("</tr>\r\n");
while (locksList.hasMoreElements()) {
writer.print("<tr");
if (!shade) {
writer.print(" bgcolor=\"dddddd\"");
} else {
writer.print(" bgcolor=\"eeeeee\"");
}
writer.print(">\r\n");
NodeLock currentLock = (NodeLock) locksList.nextElement();
writer.print("<td align=\"left\"><tt>");
writer.print(currentLock.getSubjectUri());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"left\"><tt>");
writer.print(currentLock.getTypeUri());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
writer.print
(formats[0].format(currentLock.getExpirationDate()));
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
writer.print(currentLock.isInheritable());
writer.print("</tt></td>\r\n");
writer.print("<td align=\"right\"><tt>");
writer.print(currentLock.isExclusive());
writer.print("</tt></td>\r\n");
}
}
}
// -------------------------------------------------------- Private Methods
/**
* 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");
}
/**
* URL rewriter.
*
* @param path Path which has to be rewiten
*/
private 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;
}
/**
* Check if the conditions specified in the optional If headers are
* satisfied.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param resourceInfo File object
* @return boolean true if the resource meets all the specified conditions,
* and false if any of the conditions is not satisfied, in which case
* request processing is stopped
*/
private boolean checkIfHeaders(HttpServletRequest request,
HttpServletResponse response,
ResourceInfo resourceInfo)
throws IOException {
String eTag = getETag(resourceInfo, true);
long fileLength = resourceInfo.length;
long lastModified = resourceInfo.date;
StringTokenizer commaTokenizer;
String headerValue;
// Checking If-Match
headerValue = request.getHeader("If-Match");
if (headerValue != null) {
if (headerValue.indexOf("*") == -1) {
commaTokenizer = new StringTokenizer(headerValue, ",");
boolean conditionSatisfied = false;
while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
String currentToken = commaTokenizer.nextToken();
if (currentToken.trim().equals(eTag))
conditionSatisfied = true;
}
// If none of the given ETags match, 412 Precodition failed is
// sent back
if (!conditionSatisfied) {
response.sendError
(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
}
}
// Checking If-Modified-Since
headerValue = request.getHeader("If-Modified-Since");
if (headerValue != null) {
// If an If-None-Match header has been specified, if modified since
// is ignored.
if (request.getHeader("If-None-Match") == null) {
Date date = null;
// Parsing the HTTP Date
for (int i = 0; (date == null) && (i < formats.length); i++) {
try {
date = formats[i].parse(headerValue);
} catch (ParseException e) {
;
}
}
if ((date != null)
&& (lastModified <= (date.getTime() + 1000)) ) {
// The entity has not been modified since the date
// specified by the client. This is not an error case.
response.sendError
(HttpServletResponse.SC_NOT_MODIFIED);
return false;
}
}
}
// Checking If-None-Match
headerValue = request.getHeader("If-None-Match");
if (headerValue != null) {
if (headerValue.indexOf("*") == -1) {
commaTokenizer = new StringTokenizer(headerValue, ",");
boolean conditionSatisfied = false;
while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
String currentToken = commaTokenizer.nextToken();
if (currentToken.trim().equals(eTag))
conditionSatisfied = true;
}
if (conditionSatisfied) {
// For GET and HEAD, we should respond with
// 304 Not Modified.
// For every other method, 412 Precondition Failed is sent
// back.
if ( ("GET".equals(request.getMethod()))
|| ("HEAD".equals(request.getMethod())) ) {
response.sendError
(HttpServletResponse.SC_NOT_MODIFIED);
return false;
} else {
response.sendError
(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
}
} else {
if (resourceInfo.exists()) {
}
}
}
// Checking If-Unmodified-Since
headerValue = request.getHeader("If-Unmodified-Since");
if (headerValue != null) {
Date date = null;
// Parsing the HTTP Date
for (int i = 0; (date == null) && (i < formats.length); i++) {
try {
date = formats[i].parse(headerValue);
} catch (ParseException e) {
;
}
}
if ( (date != null) && (lastModified > date.getTime()) ) {
// The entity has not been modified since the date
// specified by the client. This is not an error case.
response.sendError
(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
}
return true;
}
/**
* Get the ETag value associated with a file.
*
* @param resourceInfo File object
* @param strong True if we want a strong ETag, in which case a checksum
* of the file has to be calculated
*/
private String getETagValue(ResourceInfo resourceInfo, boolean strong) {
// FIXME : Compute a strong ETag if requested, using an MD5 digest
// of the file contents
return resourceInfo.length + "-" + resourceInfo.date;
}
/**
* Get the ETag associated with a file.
*
* @param resourceInfo File object
* @param strong True if we want a strong ETag, in which case a checksum
* of the file has to be calculated
*/
private String getETag(ResourceInfo resourceInfo, boolean strong) {
if (strong)
return "\"" + getETagValue(resourceInfo, strong) + "\"";
else
return "W/\"" + getETagValue(resourceInfo, strong) + "\"";
}
/**
* Copy the contents of the specified input stream to the specified
* output stream, and ensure that both streams are closed before returning
* (even in the face of an exception).
*
* @param istream The input stream to read from
* @param ostream The output stream to write to
*
* @exception IOException if an input/output error occurs
*/
private void copy(ResourceInfo resourceInfo,
InputStream resourceInputStream,
ServletOutputStream ostream)
throws IOException {
IOException exception = null;
InputStream istream = new BufferedInputStream
(resourceInputStream, input);
// Copy the input stream to the output stream
exception = copyRange(istream, ostream);
// Clean up the input and output streams
try {
istream.close();
} catch (Throwable t) {
;
}
try {
ostream.flush();
} catch (Throwable t) {
;
}
try {
ostream.close();
} catch (Throwable t) {
;
}
// Rethrow any exception that has occurred
if (exception != null)
throw exception;
}
/**
* Copy the contents of the specified input stream to the specified
* output stream, and ensure that both streams are closed before returning
* (even in the face of an exception).
*
* @param resourceInfo The ResourceInfo object
* @param ostream The output stream to write to
* @param range Range the client wanted to retrieve
* @exception IOException if an input/output error occurs
*/
private void copy(ResourceInfo resourceInfo,
InputStream resourceInputStream,
ServletOutputStream ostream,
Range range)
throws IOException {
IOException exception = null;
InputStream istream =
new BufferedInputStream(resourceInputStream, input);
exception = copyRange(istream, ostream, range.start, range.end);
// Clean up the input and output streams
try {
istream.close();
} catch (Throwable t) {
;
}
try {
ostream.flush();
} catch (Throwable t) {
;
}
try {
ostream.close();
} catch (Throwable t) {
;
}
// Rethrow any exception that has occurred
if (exception != null)
throw exception;
}
/**
* Copy the contents of the specified input stream to the specified
* output stream, and ensure that both streams are closed before returning
* (even in the face of an exception).
*
* @param resourceInfo The ResourceInfo object
* @param ostream The output stream to write to
* @param ranges Enumeration of the ranges the client wanted to retrieve
* @param contentType Content type of the resource
* @exception IOException if an input/output error occurs
*/
private void copy(ResourceInfo resourceInfo,
InputStream resourceInputStream,
ServletOutputStream ostream,
Enumeration ranges, String contentType)
throws IOException {
IOException exception = null;
while ( (exception == null) && (ranges.hasMoreElements()) ) {
InputStream istream =
new BufferedInputStream(resourceInputStream, input);
Range currentRange = (Range) ranges.nextElement();
// Writing MIME header.
ostream.println("--" + mimeSeparation);
if (contentType != null)
ostream.println("Content-Type: " + contentType);
ostream.println("Content-Range: bytes " + currentRange.start
+ "-" + currentRange.end + "/"
+ currentRange.length);
ostream.println();
// Printing content
exception = copyRange(istream, ostream, currentRange.start,
currentRange.end);
try {
istream.close();
} catch (Throwable t) {
;
}
}
ostream.print("--" + mimeSeparation + "--");
// Clean up the output streams
try {
ostream.flush();
} catch (Throwable t) {
;
}
try {
ostream.close();
} catch (Throwable t) {
;
}
// Rethrow any exception that has occurred
if (exception != null)
throw exception;
}
/**
* Copy the contents of the specified input stream to the specified
* output stream, and ensure that both streams are closed before returning
* (even in the face of an exception).
*
* @param istream The input stream to read from
* @param ostream The output stream to write to
* @return Exception which occured during processing
*/
private IOException copyRange(InputStream istream,
ServletOutputStream ostream) {
// Copy the input stream to the output stream
IOException exception = null;
byte buffer[] = new byte[input];
int len = buffer.length;
while (true) {
try {
len = istream.read(buffer);
if (len == -1)
break;
ostream.write(buffer, 0, len);
} catch (IOException e) {
exception = e;
len = -1;
break;
}
}
return exception;
}
/**
* Copy the contents of the specified input stream to the specified
* output stream, and ensure that both streams are closed before returning
* (even in the face of an exception).
*
* @param istream The input stream to read from
* @param ostream The output stream to write to
* @param start Start of the range which will be copied
* @param end End of the range which will be copied
* @return Exception which occured during processing
*/
private IOException copyRange(InputStream istream,
ServletOutputStream ostream,
long start, long end) {
try {
istream.skip(start);
} catch (IOException e) {
return e;
}
IOException exception = null;
long bytesToRead = end - start + 1;
byte buffer[] = new byte[input];
int len = buffer.length;
while ( (bytesToRead > 0) && (len >= buffer.length)) {
try {
len = istream.read(buffer);
if (bytesToRead >= len) {
ostream.write(buffer, 0, len);
bytesToRead -= len;
} else {
ostream.write(buffer, 0, (int) bytesToRead);
bytesToRead = 0;
}
} catch (IOException e) {
exception = e;
len = -1;
}
if (len < buffer.length)
break;
}
return exception;
}
/**
* Parse the range header.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @return Vector of ranges
*/
private Vector parseRange(HttpServletRequest request,
HttpServletResponse response,
ResourceInfo resourceInfo)
throws IOException {
// Checking If-Range
String headerValue = request.getHeader("If-Range");
if (headerValue != null) {
String eTag = getETag(resourceInfo, true);
long lastModified = resourceInfo.date;
Date date = null;
// Parsing the HTTP Date
for (int i = 0; (date == null) && (i < formats.length); i++) {
try {
date = formats[i].parse(headerValue);
} catch (ParseException e) {
;
}
}
if (date == null) {
// If the ETag the client gave does not match the entity
// etag, then the entire entity is returned.
if (!eTag.equals(headerValue.trim()))
return null;
} else {
// If the timestamp of the entity the client got is older than
// the last modification date of the entity, the entire entity
// is returned.
if (lastModified > (date.getTime() + 1000))
return null;
}
}
long fileLength = resourceInfo.length;
if (fileLength == 0)
return null;
// Retrieving the range header (if any is specified
String rangeHeader = request.getHeader("Range");
if (rangeHeader == null)
return null;
// bytes is the only range unit supported (and I don't see the point
// of adding new ones).
if (!rangeHeader.startsWith("bytes")) {
response.sendError
(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
}
rangeHeader = rangeHeader.substring(6);
// Vector which will contain all the ranges which are successfully
// parsed.
Vector result = new Vector();
StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ",");
// Parsing the range list
while (commaTokenizer.hasMoreTokens()) {
String rangeDefinition = commaTokenizer.nextToken();
Range currentRange = new Range();
currentRange.length = fileLength;
int dashPos = rangeDefinition.indexOf('-');
if (dashPos == -1) {
response.sendError
(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
}
if (dashPos == 0) {
try {
long offset = Long.parseLong(rangeDefinition);
currentRange.start = fileLength + offset;
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
response.sendError
(HttpServletResponse
.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
}
} else {
try {
currentRange.start = Long.parseLong
(rangeDefinition.substring(0, dashPos));
if (dashPos < rangeDefinition.length() - 1)
currentRange.end = Long.parseLong
(rangeDefinition.substring
(dashPos + 1, rangeDefinition.length()));
else
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
response.sendError
(HttpServletResponse
.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
}
}
if (!currentRange.validate()) {
response.sendError
(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
}
result.addElement(currentRange);
}
return result;
}
// ------------------------------------------------------ Range Inner Class
private class Range {
public long start;
public long end;
public long length;
/**
* Validate range.
*/
public boolean validate() {
return ( (start >= 0) && (end >= 0) && (length > 0)
&& (start <= end) && (end < length) );
}
}
// ---------------------------------------------- ResourceInfo Inner Class
private class ResourceInfo {
/**
* Constructor.
*
* @param pathname Path name of the file
*/
public ResourceInfo(String path, NodeRevisionDescriptor properties) {
this.path = path;
this.exists = true;
this.creationDate = properties.getCreationDateAsDate().getTime();
this.date = properties.getLastModifiedAsDate().getTime();
this.httpDate = properties.getLastModified();
this.length = properties.getContentLength();
}
public String path;
public long creationDate;
public String httpDate;
public long date;
public long length;
//public boolean collection;
public boolean exists;
/**
* Test if the associated resource exists.
*/
public boolean exists() {
return exists;
}
/**
* String representation.
*/
public String toString() {
return path;
}
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/HeadMethod.java
Index: HeadMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/HeadMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.lock.*;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
/**
* HEAD method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class HeadMethod extends GetMethod {
// ----------------------------------------------------------- Constructors
/**
* HEAD Method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public HeadMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
printContent = false;
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java
Index: LockMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;
import org.apache.slide.util.dom.DOMWriter;
import javax.xml.parsers.DocumentBuilder;
/**
* LOCK method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class LockMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
/**
* Default depth is infite.
*/
private static final int INFINITY = -1;
/**
* Create a new lock.
*/
private static final int LOCK_CREATION = 0;
/**
* Refresh lock.
*/
private static final int LOCK_REFRESH = 1;
/**
* Default timeout value.
*/
private static final int DEFAULT_TIMEOUT = 3600;
/**
* Maximum timeout.
*/
private static final int MAX_TIMEOUT = 604800;
// ----------------------------------------------------- Instance Variables
/**
* Depth.
*/
private int depth;
/**
* Type of the LOCK method.
*/
private int lockType;
/**
* Lock duration.
*/
private int lockDuration;
/**
* DAV Namespace support.
*/
private boolean davNative;
/**
* MS Proprietary properties support.
*/
private boolean msProprietarySupport;
/**
* Lock scope.
*/
private String lockInfo_lockScope;
/**
* Lock type.
*/
private String lockInfo_lockType;
/**
* Lock owner.
*/
private String lockInfo_lockOwner;
/**
* Lock subject.
*/
private String lockInfo_lockSubject;
// ----------------------------------------------------------- Constructors
/**
* LOCK method constructor.
*
* @param token Namespace access token
* @param requestUri Request URI
* @param principal Principal object, given by the servlet container
* @param req HTTP request
* @param resp HTTP response
*/
public LockMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
readRequestContent();
}
// ------------------------------------------------------ Protected Methods
/**
* Parse request.
*
* @exception WebdavException Does not happen
*/
protected void parseRequest()
throws WebdavException {
// Show request
if (req.getContentLength() > 0) {
System.out.println(new String(requestBody));
}
msProprietarySupport = isMsProprietarySupport();
// Loads the associated object from the store.
lockInfo_lockSubject = requestUri;
if (lockInfo_lockSubject == null) {
lockInfo_lockSubject = "/";
}
String depthStr = req.getHeader("Depth");
if (depthStr == null) {
depth = INFINITY;
} else {
if (depthStr.equals("0")) {
depth = 0;
} else {
depth = INFINITY;
}
}
String lockDurationStr = req.getHeader("Timeout");
if (lockDurationStr == null) {
lockDuration = DEFAULT_TIMEOUT;
} else {
if (lockDurationStr.startsWith("Second-")) {
lockDuration =
(new Integer(lockDurationStr.substring(7))).intValue();
} else {
if (lockDurationStr.equalsIgnoreCase("infinity")) {
lockDuration = MAX_TIMEOUT;
} else {
try {
lockDuration =
(new Integer(lockDurationStr)).intValue();
} catch (NumberFormatException e) {
lockDuration = MAX_TIMEOUT;
}
}
}
if (lockDuration == 0) {
lockDuration = DEFAULT_TIMEOUT;
}
if (lockDuration > MAX_TIMEOUT) {
lockDuration = MAX_TIMEOUT;
}
}
// For some strange reason, IIS doesn't handle properly
// lock expiration.
/*
if (isMsProprietarySupport()) {
lockDuration = MAX_TIMEOUT;
}
*/
if (req.getContentLength() > 0) {
lockType = LOCK_CREATION;
Node lockInfoNode = null;
try {
Document document = documentBuilder.parse(new InputSource
(new StringReader(new String(requestBody))));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
lockInfoNode = rootElement;
} catch(Exception e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
NodeList childList = lockInfoNode.getChildNodes();
StringWriter strWriter = null;
DOMWriter domWriter = null;
Node lockScopeNode = null;
Node lockTypeNode = null;
Node lockOwnerNode = null;
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
String nodeName = currentNode.getNodeName();
if (nodeName.endsWith("lockscope")) {
lockScopeNode = currentNode;
}
if (nodeName.endsWith("locktype")) {
lockTypeNode = currentNode;
}
if (nodeName.endsWith("owner")) {
lockOwnerNode = currentNode;
}
break;
}
}
if (lockScopeNode != null) {
childList = lockScopeNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
String tempScope = currentNode.getNodeName();
if (tempScope.indexOf(':') != -1) {
lockInfo_lockScope = "<"
+ tempScope.substring(tempScope.indexOf(':')
+ 1) + "/>";
} else {
lockInfo_lockScope = "<" + tempScope + "/>";
}
System.out.println("Lock scope : "
+ lockInfo_lockScope);
break;
}
}
if (lockInfo_lockScope == null) {
// Bad request
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
}
} else {
// Bad request
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
}
if (lockTypeNode != null) {
childList = lockTypeNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
String tempType = currentNode.getNodeName();
if (tempType.indexOf(':') != -1) {
lockInfo_lockType = "<"
+ tempType.substring(tempType.indexOf(':') + 1)
+ "/>";
} else {
lockInfo_lockType = "<" + tempType + "/>";
}
System.out.println("Lock type : " + lockInfo_lockType);
break;
}
}
if (lockInfo_lockType == null) {
// Bad request
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
}
} else {
// Bad request
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
}
if (lockOwnerNode != null) {
childList = lockOwnerNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
strWriter = new StringWriter();
domWriter = new DOMWriter(strWriter, true);
domWriter.print(currentNode);
lockInfo_lockOwner = strWriter.toString();
System.out.println("Lock owner : "
+ lockInfo_lockOwner);
break;
}
}
if (lockInfo_lockScope == null) {
// Bad request
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
}
} else {
lockInfo_lockOwner = new String();
}
} else {
lockType = LOCK_REFRESH;
}
}
/**
* Execute request.
*
* @exception WebdavException Unrecoverable error while renewing lock
*/
protected void executeRequest()
throws WebdavException {
SubjectNode toLockSubject = null;
switch (lockType) {
case LOCK_CREATION:
try {
NamespaceConfig namespaceConfig = token.getNamespaceConfig();
try {
toLockSubject = (SubjectNode) structure
.retrieve(credToken, lockInfo_lockSubject);
} catch (ObjectNotFoundException ex) {
// Creating a lock null resource
toLockSubject = new SubjectNode();
// Creating new subject
structure.create(credToken, toLockSubject,
lockInfo_lockSubject);
NodeRevisionDescriptor revisionDescriptor =
new NodeRevisionDescriptor(0);
NodeProperty property = null;
// Resource type
property = new NodeProperty("resourcetype",
"<lock-null/>", true);
revisionDescriptor.setProperty(property);
// Creating the revision descriptor
content.create(credToken, lockInfo_lockSubject,
revisionDescriptor, null);
}
SubjectNode credentialsSubject =
(SubjectNode) structure.retrieve
(credToken, namespaceConfig.getUsersPath() + "/"
+ credToken.getPublicCredentials());
NodeLock lockToken = null;
boolean inheritance = (depth != 0);
boolean exclusive =
!(lockInfo_lockScope.equals("<shared/>"));
Date lockDate = new Date((new Date()).getTime()
+ (lockDuration * 1000));
lockToken =
new NodeLock(toLockSubject, credentialsSubject,
namespaceConfig.getCreateObjectAction(),
lockDate, inheritance, exclusive);
lock.lock(credToken, lockToken);
try {
lockToken = new NodeLock
(lockToken,
namespaceConfig.getCreateRevisionMetadataAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
try {
lockToken = new NodeLock
(lockToken,
namespaceConfig.getModifyRevisionMetadataAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
try {
lockToken = new NodeLock
(lockToken,
namespaceConfig.getRemoveRevisionMetadataAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
try {
lockToken = new NodeLock
(lockToken,
namespaceConfig.getModifyRevisionContentAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
try {
lockToken = new NodeLock
(lockToken,
namespaceConfig.getRemoveRevisionContentAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
try {
lockToken =
new NodeLock(lockToken,
namespaceConfig.getRemoveObjectAction()
.getUri());
lock.lock(credToken, lockToken);
} catch (ObjectIsAlreadyLockedException e) {
// Silent catch
}
resp.setStatus(WebdavStatus.SC_OK);
// The lock token on which the DAV module will have the info
showLockDiscoveryInfo(lockToken);
} catch (ObjectIsAlreadyLockedException e) {
resp.setStatus(WebdavStatus.SC_LOCKED);
e.printStackTrace();
} catch (SlideException e) {
resp.setStatus(WebdavStatus.SC_PRECONDITION_FAILED);
e.printStackTrace();
}
break;
case LOCK_REFRESH:
try {
Enumeration lockTokens =
lock.enumerateLocks(credToken, lockInfo_lockSubject);
NodeLock currentLockToken = null;
Date newExpirationDate =
new Date((new Date()).getTime() + (lockDuration * 1000));
while (lockTokens.hasMoreElements()) {
currentLockToken = (NodeLock) lockTokens.nextElement();
lock.renew(credToken, currentLockToken, newExpirationDate);
}
showLockDiscoveryInfo(currentLockToken);
} catch (SlideException e) {
resp.setStatus(WebdavStatus.SC_PRECONDITION_FAILED);
e.printStackTrace();
}
break;
}
}
/**
* Show lockdiscovery info.
*
* @exception WebdavException Something is wrong with the servlet container
*/
protected void showLockDiscoveryInfo(NodeLock token)
throws WebdavException {
// Generating XML response
WebdavXMLPrinter generatedXML = new WebdavXMLPrinter();
generatedXML.writeXMLHeader();
generatedXML.writeElement("d", "DAV:", "prop",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "lockdiscovery",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "activelock",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "locktype",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "write",
WebdavXMLPrinter.NO_CONTENT);
generatedXML.writeElement("d", null, "locktype",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "lockscope",
WebdavXMLPrinter.OPENING);
if (token.isExclusive()) {
generatedXML.writeElement("d", null, "exclusive",
WebdavXMLPrinter.NO_CONTENT);
} else {
generatedXML.writeElement("d", null, "shared",
WebdavXMLPrinter.NO_CONTENT);
}
generatedXML.writeElement("d", null, "lockscope",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "depth",
WebdavXMLPrinter.OPENING);
if (token.isInheritable()) {
generatedXML.writeText("Infinity");
} else {
generatedXML.writeText("0");
}
generatedXML.writeElement("d", null, "depth",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "owner",
WebdavXMLPrinter.OPENING);
//generatedXML.writeText(lockInfo_lockOwner);
generatedXML.writeText(req.getServletPath() + token.getSubjectUri());
generatedXML.writeElement("d", null, "owner",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "timeout",
WebdavXMLPrinter.OPENING);
generatedXML.writeText("Second-"
+ (new Long((token.getExpirationDate().getTime()
- (new Date()).getTime())/1000))
.toString());
generatedXML.writeElement("d", null, "timeout",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "locktoken",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "href",
WebdavXMLPrinter.OPENING);
// Put here the token Id
generatedXML.writeText("opaquelocktoken:" + token.getLockId());
generatedXML.writeElement("d", null, "href",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "locktoken",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "activelock",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "lockdiscovery",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.CLOSING);
try {
System.out.println("Query result");
System.out.println(generatedXML.toString());
Writer writer = resp.getWriter();
writer.write(generatedXML.toString());
writer.flush();
} catch (Exception e) {
e.printStackTrace();
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java
Index: MkcolMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
import org.apache.slide.lock.*;
import org.apache.slide.security.AccessDeniedException;
/**
* MKCOL method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class MkcolMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
/**
* HTTP Date format pattern (RFC 2068, 822, 1123).
*/
public static final String DATE_FORMAT = "EEE, d MMM yyyy kk:mm:ss z";
// ----------------------------------------------------- Instance Variables
/**
* Collection name.
*/
private String colName;
// ----------------------------------------------------------- Constructors
/**
* GET Method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public MkcolMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse XML request.
*/
protected void parseRequest()
throws WebdavException {
colName = requestUri;
if (colName == null) {
colName = "/";
}
}
/**
* Execute request.
*
* @exception WebdavException Bad request
*/
protected void executeRequest()
throws WebdavException {
SubjectNode collection = new SubjectNode();
NodeRevisionDescriptor revisionDescriptor =
new NodeRevisionDescriptor(0);
NodeProperty property = null;
// Resource type
property = new NodeProperty("resourcetype", "<collection/>", true);
revisionDescriptor.setProperty(property);
// Creation date
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
property = new NodeProperty("creationdate",
formatter.format(new Date()), true);
revisionDescriptor.setProperty(property);
// Last modification date
property = new NodeProperty("getlastmodified",
formatter.format(new Date()), true);
revisionDescriptor.setProperty(property);
// Display name
property = new NodeProperty("displayname", colName, true);
revisionDescriptor.setProperty(property);
// Display name
property = new NodeProperty("getcontentlength", "0", true);
revisionDescriptor.setProperty(property);
// Source
property = new NodeProperty("source", "", true);
revisionDescriptor.setProperty(property);
if (isMsProprietarySupport()) {
// Name
/*
property = new NodeProperty("name", colName, "ms", "MICROSOFT");
properties.setProperty(property);
*/
// ParentName
// TODO : Fix this
/*
property = new NodeProperty("parentname", colName, "ms",
"MICROSOFT");
properties.setProperty(property);
*/
// Href
/*
property = new NodeProperty("href", colName, "ms", "MICROSOFT");
properties.setProperty(property);
*/
// Is hidden
property = new NodeProperty("ishidden", "0", "MICROSOFT");
revisionDescriptor.setProperty(property);
// Is collection
property = new NodeProperty("iscollection", "1", "MICROSOFT");
revisionDescriptor.setProperty(property);
// Is read only
property = new NodeProperty("isreadonly", "0", "MICROSOFT");
revisionDescriptor.setProperty(property);
// Last accessed
property = new NodeProperty("lastaccessed",
(new Date()).toString(), "MICROSOFT");
revisionDescriptor.setProperty(property);
}
try {
structure.create(credToken, collection, colName);
content.create(credToken, colName, revisionDescriptor, null);
} catch (ObjectNotFoundException e) {
resp.setStatus(WebdavStatus.SC_CONFLICT);
throw new WebdavException(WebdavStatus.SC_CONFLICT);
} catch (ObjectLockedException e) {
resp.setStatus(WebdavStatus.SC_LOCKED);
throw new WebdavException(WebdavStatus.SC_LOCKED);
} catch (RevisionAlreadyExistException e) {
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (ServiceAccessException e) {
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (LinkedObjectNotFoundException e) {
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
throw new WebdavException(WebdavStatus.SC_NOT_FOUND);
} catch (ObjectAlreadyExistsException e) {
resp.setStatus(WebdavStatus.SC_METHOD_NOT_ALLOWED);
throw new WebdavException(WebdavStatus.SC_METHOD_NOT_ALLOWED);
} catch (AccessDeniedException e) {
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
//throw new WebdavException(WebdavStatus.SC_FORBIDDEN);
}
// 415 - Unsupported Media Type
// TODO : Has something to do with the body of the request ...
// WebDAV RFC is vague on the subject.
// 507 - Insufficient storage
// Would be returned as a ServiceAccessException, so it would
// return an Internal Server Error, which is probably acceptable.
// TODO : Initialize and create collection's properties.
// 201 - Created / OK
resp.setStatus(WebdavStatus.SC_CREATED);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java
Index: MoveMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;
/**
* MOVE Method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class MoveMethod extends WebdavMethod {
// ----------------------------------------------------- Instance Variables
/**
* Id of the resosurce or collection which is to be move.
*/
private String sourceUri;
/**
* Uri of the target.
*/
private String destinationUri;
/**
* Overwrite.
*/
private boolean overwrite;
// ----------------------------------------------------------- Constructors
/**
* MOVE method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public MoveMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse request.
*
* @exception WebdavException Does not happen
*/
protected void parseRequest()
throws WebdavException {
sourceUri = requestUri;
if (sourceUri == null) {
sourceUri = "/";
}
destinationUri = req.getHeader("Destination");
String HTTPHeader = "http://";
if (destinationUri.startsWith(HTTPHeader)) {
destinationUri = destinationUri.substring(HTTPHeader.length());
}
String hostName = req.getServerName();
if ((hostName != null) && (destinationUri.startsWith(hostName))) {
destinationUri = destinationUri.substring(hostName.length());
}
if (destinationUri.startsWith(":")) {
int firstSeparator = destinationUri.indexOf("/");
if (firstSeparator < 0) {
destinationUri = "/";
} else {
destinationUri = destinationUri.substring(firstSeparator);
}
}
String contextPath = req.getContextPath();
if ((contextPath != null) &&
(destinationUri.startsWith(contextPath))) {
destinationUri = destinationUri.substring(contextPath.length());
}
String pathInfo = req.getPathInfo();
if (pathInfo != null) {
String servletPath = req.getServletPath();
if ((servletPath != null) &&
(destinationUri.startsWith(servletPath))) {
destinationUri = destinationUri
.substring(servletPath.length());
}
}
String overwriteHeader = req.getHeader("Overwrite");
if (overwriteHeader != null) {
if (overwriteHeader.equalsIgnoreCase("T")) {
overwrite = true;
} else {
overwrite = false;
}
} else {
overwrite = true;
}
}
/**
* Execute request.
*
* @exception WebdavException Unrecoverable error while moving the files
*/
protected void executeRequest()
throws WebdavException {
MacroParameters macroParameters = null;
if (overwrite) {
macroParameters = Macro.RECURSIVE_OVERWRITE_PARAMETERS;
} else {
macroParameters = Macro.DEFAULT_PARAMETERS;
}
try {
macro.move(credToken, sourceUri, destinationUri, macroParameters);
if (overwrite) {
resp.setStatus(WebdavStatus.SC_NO_CONTENT);
} else {
resp.setStatus(WebdavStatus.SC_CREATED);
}
} catch (DeleteMacroException e) {
String errorMessage = generateErrorMessage(e);
// Write it on the servlet writer
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
try {
resp.getWriter().write(errorMessage);
} catch(IOException ex) {
// Critical error ... Servlet container is dead or something
ex.printStackTrace();
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
} catch (CopyMacroException e) {
String errorMessage = generateErrorMessage(e);
// Write it on the servlet writer
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
try {
resp.getWriter().write(errorMessage);
} catch(IOException ex) {
// Critical error ... Servlet container is dead or something
ex.printStackTrace();
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
}
/**
* Generate an XML error message.
*
* @param macroException Nested exception
* @return String XML message
*/
protected String generateErrorMessage(MacroException macroException) {
WebdavXMLPrinter errorMessage = new WebdavXMLPrinter();
errorMessage.writeXMLHeader();
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.OPENING);
Enumeration nestedExceptionsList =
macroException.enumerateExceptions();
while (nestedExceptionsList.hasMoreElements()) {
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.OPENING);
SlideException ex =
(SlideException) nestedExceptionsList.nextElement();
String status = new String();
try {
throw ex;
} catch(ObjectNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(AccessDeniedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_FORBIDDEN);
} catch(ObjectAlreadyExistsException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ServiceAccessException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_BAD_GATEWAY);
} catch(LinkedObjectNotFoundException e) {
generateStatusText(errorMessage, e.getTargetUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(RevisionNotFoundException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch(ObjectLockedException e) {
generateStatusText(errorMessage, e.getObjectUri(),
WebdavStatus.SC_LOCKED);
} catch(SlideException e) {
generateStatusText(errorMessage, e.getMessage(),
WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
errorMessage.writeElement("d", "DAV", "response",
WebdavXMLPrinter.CLOSING);
}
errorMessage.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.CLOSING);
return errorMessage.toString();
}
/**
* Generate status text.
*
* @param printer XML Printer
* @param href Uri of the object
* @param statusCode HTTP status code of the error
*/
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
printer.writeText(href);
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
+ WebdavStatus.getStatusText(statusCode));
printer.writeElement("d", "status", WebdavXMLPrinter.CLOSING);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/OptionsMethod.java
Index: OptionsMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/OptionsMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.common.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.structure.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
/**
* OPTIONS Method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class OptionsMethod extends WebdavMethod {
// ----------------------------------------------------------- Constructors
public OptionsMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
protected void parseRequest()
throws WebdavException {
}
protected void executeRequest()
throws WebdavException {
resp.addHeader("DAV", "1,2");
String resourceUri = requestUri;
if (resourceUri == null) {
resourceUri = "/";
}
String methodsAllowed = null;
try {
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, resourceUri);
NodeRevisionDescriptor revisionDescriptor =
content.retrieve(credToken, revisionDescriptors);
boolean isCollection = isCollection(revisionDescriptor);
methodsAllowed = "OPTIONS, GET, HEAD, POST, DELETE, TRACE, "
+ "PROPFIND, PROPPATCH, COPY, MOVE, LOCK, UNLOCK";
if (!isCollection) {
methodsAllowed = methodsAllowed + ", PUT";
}
} catch (SlideException e) {
if (resourceUri.equals("/")) {
methodsAllowed = "OPTIONS, GET, HEAD, POST, DELETE, TRACE, "
+ "PROPFIND, PROPPATCH, COPY, MOVE, LOCK, UNLOCK";
} else {
methodsAllowed = "OPTIONS, MKCOL, PUT, LOCK";
}
}
resp.addHeader("Allow", methodsAllowed);
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PostMethod.java
Index: PostMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PostMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* POST method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class PostMethod extends WebdavMethod {
// ----------------------------------------------------------- Constructors
public PostMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
protected void parseRequest()
throws WebdavException {
// Don't know what to do there.
// RFC is extremely vague on the subject ...
}
protected void executeRequest()
throws WebdavException {
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java
Index: PropFindMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.common.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.structure.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import javax.xml.parsers.DocumentBuilder;
/**
* PROPFIND method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public final class PropFindMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
/**
* Root node URI.
*/
private static final String DIRECTORY = "/";
/**
* Default depth is infite.
*/
private static final int INFINITY = 3; // To limit tree browsing a bit
/**
* Specify a property mask.
*/
private static final int FIND_BY_PROPERTY = 0;
/**
* Display all properties.
*/
private static final int FIND_ALL_PROP = 1;
/**
* Return property names.
*/
private static final int FIND_PROPERTY_NAMES = 2;
/**
* Supported locks property value.
*/
private static final String SUPPORTED_LOCK = "<lockentry>"
+ "<lockscope><exclusive/></lockscope>"
+ "<locktype><write/></locktype>"
+ "</lockentry>"
+ "<lockentry>"
+ "<lockscope><shared/></lockscope>"
+ "<locktype><write/></locktype>"
+ "</lockentry>";
// ----------------------------------------------------- Instance Variables
/**
* Depth.
*/
private int depth;
/**
* Type of the PROPFIND method.
*/
private int propFindType;
/**
* Properties to display
*/
private Vector propertyVector;
/**
* MS Proprietary properties support.
*/
private boolean msProprietarySupport;
/**
* Current namespace number used to generate namespace abbreviations.
*/
private int namespaceNumber = 0;
/**
* Namespaces list. Keyed by namespace names.
*/
private Hashtable namespaceAbbrevs;
// ----------------------------------------------------------- Constructors
/**
* PROPFIND method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public PropFindMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
readRequestContent();
namespaceAbbrevs = new Hashtable();
depth = INFINITY;
propFindType = FIND_ALL_PROP;
}
// ------------------------------------------------------ Protected Methods
/**
* Parse the request.
*
* @exception WebdavException Bad request
*/
protected void parseRequest()
throws WebdavException {
msProprietarySupport = isMsProprietarySupport();
String depthStr = req.getHeader("Depth");
if (depthStr == null) {
depth = INFINITY;
} else {
if (depthStr.equals("0")) {
depth = 0;
}
if (depthStr.equals("1")) {
depth = 1;
}
if (depthStr.equals("infinity")) {
depth = INFINITY;
}
}
if (req.getContentLength() != 0) {
//Propfind propfind = null;
// Workaround : Castor doesn't work, so I use DOM in the meantime
Node propNode = null;
try {
Document document =
documentBuilder.parse(new InputSource
(new StringReader(new String(requestBody))));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
NodeList childList = rootElement.getChildNodes();
parseNodeNamespaceDeclarations(rootElement);
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations(currentNode);
if (currentNode.getNodeName().endsWith("prop")) {
propFindType = FIND_BY_PROPERTY;
propNode = currentNode;
}
if (currentNode.getNodeName().endsWith("propname")) {
propFindType = FIND_PROPERTY_NAMES;
}
if (currentNode.getNodeName().endsWith("allprop")) {
propFindType = FIND_ALL_PROP;
}
break;
}
}
} catch(Exception e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
if (propFindType == FIND_BY_PROPERTY) {
propertyVector = new Vector();
NodeList childList = propNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations(currentNode);
Property property = getProperty(currentNode);
propertyVector.addElement(property);
break;
}
}
}
}
}
/**
* Execute the request.
*
* @exception WebdavException
*/
protected void executeRequest()
throws WebdavException {
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
// Loads the associated object from the store.
String resourceUri = requestUri;
// Get the object from Data.
ObjectNode resource = null;
try {
resource = structure.retrieve(credToken, resourceUri);
} catch (StructureException e) {
// We silently catch that since we need to generate some XML ...
e.printStackTrace();
try {
resp.sendError
(WebdavStatus.SC_NOT_FOUND,
WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND));
} catch(IOException ex) {
ex.printStackTrace();
}
throw new WebdavException(WebdavStatus.SC_NOT_FOUND);
} catch (ServiceAccessException e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (AccessDeniedException e) {
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
throw new WebdavException(WebdavStatus.SC_FORBIDDEN);
} catch (Exception e) {
e.printStackTrace();
}
// Create multistatus object
WebdavXMLPrinter generatedXML = new WebdavXMLPrinter();
generatedXML.writeXMLHeader();
generatedXML.writeElement(null, "multistatus"
+ generateNamespaceDeclarations(),
WebdavXMLPrinter.OPENING);
if (resource != null) {
if (depth == 0) {
parsePropertiesOfObject(resource, generatedXML);
} else {
// The stack always contains the object of the current level
Stack stack = new Stack();
stack.push(resource);
// Stack of the objects one level below
Stack stackBelow = new Stack();
while ((!stack.isEmpty()) && (depth >= 0)) {
ObjectNode cur = (ObjectNode) stack.pop();
parsePropertiesOfObject(cur, generatedXML);
Enumeration enum = null;
try {
enum = structure.getChildren(credToken, cur);
} catch (StructureException e) {
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (ServiceAccessException e) {
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException
(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
while (enum.hasMoreElements()) {
stackBelow.push(enum.nextElement());
}
if (stack.isEmpty()) {
depth--;
stack = stackBelow;
stackBelow = new Stack();
}
}
}
}
generatedXML.writeElement(null, "multistatus",
WebdavXMLPrinter.CLOSING);
try {
//System.out.println("Query result");
//System.out.println(generatedXML.toString());
Writer writer = resp.getWriter();
writer.write(generatedXML.toString());
writer.flush();
} catch (Exception e) {
e.printStackTrace();
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
/**
* Parse properties of an object.
*
* @param object
* @param multistatus
* @exception WebdavException
*/
protected void parsePropertiesOfObject(ObjectNode object,
WebdavXMLPrinter generatedXML)
throws WebdavException {
generatedXML.writeElement(null, "response", WebdavXMLPrinter.OPENING);
String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " "
+ WebdavStatus.getStatusText
(WebdavStatus.SC_OK));
NodeRevisionDescriptors revisionDescriptors = null;
NodeRevisionDescriptor revisionDescriptor = null;
boolean isCollection = false;
NodeLock objectLockToken = null;
try {
generatedXML.writeElement(null, "href", WebdavXMLPrinter.OPENING);
revisionDescriptors = content.retrieve(credToken, object.getUri());
try {
revisionDescriptor = content.retrieve(credToken,
revisionDescriptors);
isCollection = isCollection(revisionDescriptor);
String path = object.getUri();
String absoluteUri = req.getRequestURI();
String relativePath = requestUri;
String toAppend = "";
if (relativePath.length() <= path.length()) {
toAppend = path.substring(relativePath.length());
if ((!absoluteUri.endsWith("/")) &&
(!toAppend.startsWith("/"))) {
toAppend = "/" + toAppend;
}
if (toAppend.equals("/")) {
toAppend = "";
}
}
generatedXML.writeText(absoluteUri + toAppend);
} catch (RevisionDescriptorNotFoundException e) {
// The object doesn't have any revision, we create a dummy
// NodeRevisionDescriptor object
isCollection = true;
revisionDescriptor = new NodeRevisionDescriptor(0);
revisionDescriptor.setName(object.getUri());
String path = object.getUri();
String absoluteUri = req.getRequestURI();
String relativePath = requestUri;
String toAppend = "";
if (relativePath.length() <= path.length()) {
toAppend = path.substring(relativePath.length());
if ((!absoluteUri.endsWith("/"))
&& (!toAppend.startsWith("/"))) {
toAppend = "/" + toAppend;
}
}
generatedXML.writeText(absoluteUri + toAppend);
}
generatedXML.writeElement(null, "href", WebdavXMLPrinter.CLOSING);
Enumeration lockTokens = lock.enumerateLocks(credToken,
object.getUri());
if (lockTokens.hasMoreElements()) {
objectLockToken = (NodeLock) lockTokens.nextElement();
}
} catch (ServiceAccessException e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (AccessDeniedException e) {
if (revisionDescriptor == null) {
revisionDescriptor = new NodeRevisionDescriptor(0);
}
} catch (SlideException e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
Vector propertiesParser = null;
switch (propFindType) {
case FIND_ALL_PROP :
// Show properties / values for current object.
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.OPENING);
status = new String("HTTP/1.1 " + WebdavStatus.SC_OK
+ " " + WebdavStatus.getStatusText
(WebdavStatus.SC_OK));
// Lock information, which is dynamically generated
if (objectLockToken != null) {
showLockDiscoveryInfo(objectLockToken, generatedXML);
}
// Supported locks
generatedXML.writeElement(null, "supportedlock",
WebdavXMLPrinter.OPENING);
generatedXML.writeText(SUPPORTED_LOCK);
generatedXML.writeElement(null, "supportedlock",
WebdavXMLPrinter.CLOSING);
// Other properties
Enumeration propertyList =
revisionDescriptor.enumerateProperties();
while (propertyList.hasMoreElements()) {
NodeProperty currentProperty =
(NodeProperty) propertyList.nextElement();
if (currentProperty != null) {
String namespace = currentProperty.getNamespace();
String namespaceAbbrev =
(String) namespaceAbbrevs.get(namespace);
Object currentPropertyValue = currentProperty.getValue();
if ((currentPropertyValue == null) ||
(currentPropertyValue.toString().equals(""))) {
generatedXML.writeElement
(namespaceAbbrev, namespace,
currentProperty.getName(),
WebdavXMLPrinter.NO_CONTENT);
} else {
generatedXML.writeElement
(namespaceAbbrev, namespace,
currentProperty.getName(),
WebdavXMLPrinter.OPENING);
generatedXML.writeText
(currentPropertyValue.toString());
generatedXML.writeElement
(namespaceAbbrev, namespace,
currentProperty.getName(),
WebdavXMLPrinter.CLOSING);
}
}
}
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty(null, "status", status);
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
break;
case FIND_PROPERTY_NAMES :
// Show properties for current object.
status = new String("HTTP/1.1 " + WebdavStatus.SC_OK
+ " " + WebdavStatus.getStatusText
(WebdavStatus.SC_OK));
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.OPENING);
// Lock information
generatedXML.writeElement(null, "lockdiscovery",
WebdavXMLPrinter.NO_CONTENT);
generatedXML.writeElement(null, "supportedlock",
WebdavXMLPrinter.NO_CONTENT);
// Then, add this resource's custom properties
propertyList = revisionDescriptor.enumerateProperties();
while (propertyList.hasMoreElements()) {
NodeProperty currentProperty =
(NodeProperty) propertyList.nextElement();
if (currentProperty != null) {
String namespace = currentProperty.getNamespace();
String namespaceAbbrev =
(String) namespaceAbbrevs.get(namespace);
generatedXML.writeElement
(namespaceAbbrev, namespace,
currentProperty.getName(),
WebdavXMLPrinter.NO_CONTENT);
}
}
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty(null, "status", status);
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
break;
case FIND_BY_PROPERTY :
// Show requested properties value.
propertyList = propertyVector.elements();
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.OPENING);
status = new String("HTTP/1.1 " + WebdavStatus.SC_OK
+ " " + WebdavStatus.getStatusText
(WebdavStatus.SC_OK));
Vector propertiesNotFoundVector = new Vector();
while (propertyList.hasMoreElements()) {
Property property = (Property) propertyList.nextElement();
String propertyName = property.name;
String propertyNamespace = property.namespace;
// Lock information, dynamically generated
if ((propertyName.equals("lockdiscovery")) &&
(propertyNamespace.equals
(NodeProperty.DEFAULT_NAMESPACE))) {
// Return list of active locks ...
if (objectLockToken != null) {
showLockDiscoveryInfo(objectLockToken, generatedXML);
}
} else if ((propertyName.equals("supportedlock")) &&
(propertyNamespace.equals
(NodeProperty.DEFAULT_NAMESPACE))) {
// Supported locks
generatedXML.writeElement(null, "supportedlock",
WebdavXMLPrinter.OPENING);
generatedXML.writeText(SUPPORTED_LOCK);
generatedXML.writeElement(null, "supportedlock",
WebdavXMLPrinter.CLOSING);
} else {
// Search in the custom properties
NodeProperty currentProperty =
revisionDescriptor.getProperty(propertyName,
propertyNamespace);
if (currentProperty != null) {
Object currentPropertyValue =
currentProperty.getValue();
if ((currentPropertyValue == null) ||
(currentPropertyValue.toString().equals(""))) {
generatedXML.writeElement
(property.namespaceAbbrev, null,
currentProperty.getName(),
WebdavXMLPrinter.NO_CONTENT);
} else {
generatedXML.writeElement
(property.namespaceAbbrev, null,
currentProperty.getName(),
WebdavXMLPrinter.OPENING);
generatedXML.writeText
(currentPropertyValue.toString());
generatedXML.writeElement
(property.namespaceAbbrev, null,
currentProperty.getName(),
WebdavXMLPrinter.CLOSING);
}
} else {
propertiesNotFoundVector.addElement(propertyName);
}
}
}
generatedXML.writeElement(null, "prop", WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty(null, "status", status);
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
Enumeration propertiesNotFoundList =
propertiesNotFoundVector.elements();
if (propertiesNotFoundList.hasMoreElements()) {
status = new String("HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND
+ " " + WebdavStatus.getStatusText
(WebdavStatus.SC_NOT_FOUND));
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "prop",
WebdavXMLPrinter.OPENING);
while (propertiesNotFoundList.hasMoreElements()) {
generatedXML.writeElement
(null, (String) propertiesNotFoundList.nextElement(),
WebdavXMLPrinter.NO_CONTENT);
}
generatedXML.writeElement(null, "prop",
WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty(null, "status", status);
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
}
break;
}
generatedXML.writeElement(null, "response", WebdavXMLPrinter.CLOSING);
}
/**
* Parse a node for namespace declaration attributes.
*
* @param node DOM node
*/
protected void parseNodeNamespaceDeclarations(Node node) {
NamedNodeMap nodeMap = node.getAttributes();
if (nodeMap != null) {
for (int i = 0; i < nodeMap.getLength(); i++) {
Node currentNode = nodeMap.item(i);
if (currentNode.getNodeType() != Node.ATTRIBUTE_NODE)
continue;
String attributeName = currentNode.getNodeName();
if (attributeName.startsWith("xmlns")) {
// We found a namespace declaration
if (attributeName.equals("xmlns")) {
defaultNamespace = currentNode.getNodeValue();
} else {
// Stripping out the prefix
if (attributeName.startsWith("xmlns:")) {
String namespaceAbbreviation =
attributeName.substring(6);
namespaces.put(namespaceAbbreviation,
currentNode.getNodeValue());
namespaceAbbrevs.put(currentNode.getNodeValue(),
namespaceAbbreviation);
}
}
}
}
}
}
// -------------------------------------------------------- Private Methods
/**
* Parse the namespace info of a node name.
*
* @param node The DOM node to parse
* @return The corresponding Property object
*/
private Property getProperty(Node node) {
Property property = new Property();
String nodeName = node.getNodeName();
int colon = nodeName.indexOf(':');
if (colon != -1) {
property.name = nodeName.substring(colon + 1);
property.namespaceAbbrev = nodeName.substring(0, colon - 1);
String namespace =
(String) namespaces.get(property.namespaceAbbrev);
if ((namespace) != null) {
property.namespace = namespace;
} else {
property.namespace = defaultNamespace;
}
} else {
property.name = nodeName;
property.namespace = defaultNamespace;
}
return property;
}
/**
* Generate a namespace abbreviation for the given namespace.
*
* @param namespaceName Name of the namespace
*/
private void generateNamespaceAbbreviation(String namespaceName) {
if (namespaces.get(namespaceName) != null)
return;
String namespaceAbbrev = "ns" + namespaceNumber++;
while (namespaces.get(namespaceAbbrev) != null) {
namespaceAbbrev = "ns" + namespaceNumber++;
}
namespaces.put(namespaceAbbrev, namespaceName);
}
/**
* Generate namespace declaration attributes.
*
* @return String namespace attributes
*/
private String generateNamespaceDeclarations() {
StringBuffer result = new StringBuffer();
result.append(" xmlns=\"").append(defaultNamespace).append("\" ");
Enumeration abbreviationList = namespaces.keys();
while (abbreviationList.hasMoreElements()) {
String abbrev = (String) abbreviationList.nextElement();
String namespace = (String) namespaces.get(abbrev);
result.append("xmlns:").append(abbrev).append("=\"")
.append(namespace).append("\" ");
}
return result.toString();
}
/**
* Show lockdiscovery info.
*
* @exception WebdavException Something is wrong with the servlet container
*/
private void showLockDiscoveryInfo(NodeLock token,
WebdavXMLPrinter generatedXML)
throws WebdavException {
generatedXML.writeElement(null, "lockdiscovery",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "activelock",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "locktype", WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "write", WebdavXMLPrinter.NO_CONTENT);
generatedXML.writeElement(null, "locktype", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "lockscope", WebdavXMLPrinter.OPENING);
if (token.isExclusive()) {
generatedXML.writeElement(null, "exclusive",
WebdavXMLPrinter.NO_CONTENT);
} else {
generatedXML.writeElement(null, "shared",
WebdavXMLPrinter.NO_CONTENT);
}
generatedXML.writeElement(null, "lockscope", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "depth", WebdavXMLPrinter.OPENING);
if (token.isInheritable()) {
generatedXML.writeText("Infinity");
} else {
generatedXML.writeText("0");
}
generatedXML.writeElement(null, "depth", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "owner", WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "href", WebdavXMLPrinter.OPENING);
generatedXML.writeText(req.getServletPath() + token.getSubjectUri());
generatedXML.writeElement(null, "href", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "owner", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "timeout", WebdavXMLPrinter.OPENING);
generatedXML.writeText("Second-"
+ (new Long((token.getExpirationDate().getTime()
- (new Date()).getTime())/1000))
.toString());
generatedXML.writeElement(null, "timeout", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "locktoken", WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "href", WebdavXMLPrinter.OPENING);
// Put here the token Id
generatedXML.writeText("opaquelocktoken:" + token.getLockId());
generatedXML.writeElement(null, "href", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "locktoken", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "activelock",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "lockdiscovery",
WebdavXMLPrinter.CLOSING);
}
// --------------------------------------------------- Property Inner Class
private class Property {
public String name;
public String value;
public String namespace;
public String namespaceAbbrev;
public int status = WebdavStatus.SC_OK;
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java
Index: PropPatchMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.common.*;
import org.apache.slide.util.dom.DOMWriter;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.structure.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import javax.xml.parsers.DocumentBuilder;
/**
* PROPPATCH method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class PropPatchMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
private static final int SET = 0;
private static final int REMOVE = 1;
// ----------------------------------------------------- Instance Variables
/**
* Properties to set. Vector of SlideProperty objects.
*/
private Vector propertiesToSet;
/**
* Properties to remove. Vector of String.
*/
private Vector propertiesToRemove;
/**
* DOM Writer.
*/
private DOMWriter domWriter;
/**
* Resource which will have its properties updated.
*/
private String resourcePath;
// ----------------------------------------------------------- Constructors
/**
* PROPPATCH method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public PropPatchMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
readRequestContent();
}
// ------------------------------------------------------ Protected Methods
/**
* Parse the request.
*
* @exception WebdavException Bad request
*/
protected void parseRequest()
throws WebdavException {
resourcePath = requestUri;
if (resourcePath == null) {
resourcePath = "/";
}
propertiesToSet = new Vector();
propertiesToRemove = new Vector();
if (requestBody.length != 0) {
try {
Node setNode = null;
Node removeNode = null;
Document document = documentBuilder.parse(new InputSource(
(new StringReader(new String(requestBody)))));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
NodeList childList = rootElement.getChildNodes();
parseNodeNamespaceDeclarations(rootElement);
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations(currentNode);
if (currentNode.getNodeName().endsWith("set")) {
NodeList tempList = currentNode.getChildNodes();
for (int j=0; j < tempList.getLength(); j++) {
switch (tempList.item(j).getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations
(tempList.item(j));
if (tempList.item(j).getNodeName()
.endsWith("prop")) {
parseSetNode(tempList.item(j));
}
break;
}
}
}
if (currentNode.getNodeName().endsWith("remove")) {
NodeList tempList = currentNode.getChildNodes();
for (int j=0; j < tempList.getLength(); j++) {
switch (tempList.item(j).getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations
(tempList.item(j));
if (tempList.item(j).getNodeName()
.endsWith("prop")) {
parseRemoveNode(tempList.item(j));
}
break;
}
}
}
break;
}
}
} catch(Exception e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
} else {
try {
resp.sendError(WebdavStatus.SC_BAD_REQUEST,
WebdavStatus.getStatusText
(WebdavStatus.SC_BAD_REQUEST));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Execute the request.
*
* @exception WebdavException
*/
protected void executeRequest()
throws WebdavException {
try {
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, resourcePath);
NodeRevisionDescriptor revisionDescriptor = null;
try {
revisionDescriptor =
content.retrieve(credToken, revisionDescriptors);
} catch (RevisionDescriptorNotFoundException ex) {
revisionDescriptor = new NodeRevisionDescriptor(0);
// TODO : Create the initial revision ?
}
// Modifying the properties
Enumeration propertyList = null;
propertyList = propertiesToSet.elements();
while (propertyList.hasMoreElements()) {
Property currentProperty =
(Property) propertyList.nextElement();
if (checkProperty(currentProperty, SET)) {
NodeProperty newProperty =
new NodeProperty(currentProperty.name,
currentProperty.value,
currentProperty.namespace);
revisionDescriptor.setProperty(newProperty);
}
}
propertyList = propertiesToRemove.elements();
while (propertyList.hasMoreElements()) {
Property currentProperty =
(Property) propertyList.nextElement();
if (checkProperty(currentProperty, REMOVE)) {
revisionDescriptor.removeProperty(currentProperty.name);
}
}
// TEMP !!!! We should do a store instead !!
content.create(credToken, resourcePath, revisionDescriptor, null);
} catch(RevisionAlreadyExistException e) {
// 500 - Internal server error
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (LinkedObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (ObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (AccessDeniedException e) {
// 403 - Forbidden
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
} catch (ObjectLockedException e) {
// Locked
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_LOCKED);
} catch (ServiceAccessException e) {
// 500 - Internal server error
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (RuntimeException e) {
// 500 - Internal server error
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
// No serious errors. Printing the XML report.
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
writeReport();
}
// -------------------------------------------------------- Private Methods
/**
* Parse the set property node given.
*/
private void parseSetNode(Node setNode) {
NodeList childList = setNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations(currentNode);
Property propertyToSet = getProperty(currentNode);
StringWriter writer = new StringWriter();
domWriter = new DOMWriter(writer, true);
// Printing all child nodes using the DOM printer
NodeList childNodes = currentNode.getChildNodes();
Node childNode = childNodes.item(0);
int pos = 0;
while (childNode != null) {
domWriter.print(childNode);
childNode = childNodes.item(++pos);
}
String nodeValue = writer.toString();
propertyToSet.value = nodeValue;
propertiesToSet.addElement(propertyToSet);
break;
}
}
}
/**
* Parse the remove property node given.
*/
private void parseRemoveNode(Node removeNode) {
NodeList childList = removeNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
parseNodeNamespaceDeclarations(currentNode);
Property propertyToRemove = getProperty(currentNode);
propertiesToRemove.addElement(propertyToRemove);
break;
}
}
}
/**
* Parse the namespace info of a node name.
*
* @param node The DOM node to parse
* @return The corresponding Property object
*/
private Property getProperty(Node node) {
Property property = new Property();
String nodeName = node.getNodeName();
int colon = nodeName.indexOf(':');
if (colon != -1) {
property.name = nodeName.substring(colon + 1);
property.namespaceAbbrev = nodeName.substring(0, colon - 1);
String namespace =
(String) namespaces.get(property.namespaceAbbrev);
if ((namespace) != null) {
property.namespace = namespace;
} else {
property.namespace = defaultNamespace;
}
} else {
property.name = nodeName;
property.namespace = defaultNamespace;
}
return property;
}
/**
* Check if the property is a live property which should have its value
* enforced by the server.
*
* @param property The property object
* @param actionType Can be either SET or REMOVE
*/
private boolean checkProperty(Property property, int actionType) {
// Checking the standard DAV properties which can't be modified using
// a propatch.
if (
(property.name.equalsIgnoreCase("creationdate")) ||
(property.name.equalsIgnoreCase("getcontentlength")) ||
(property.name.equalsIgnoreCase("getetag")) ||
(property.name.equalsIgnoreCase("getlastmodified")) ||
(property.name.equalsIgnoreCase("lockdiscovery"))
) {
property.status = WebdavStatus.SC_CONFLICT;
return false;
}
switch (actionType) {
case SET:
break;
case REMOVE:
break;
}
return true;
}
/**
* Write the report.
*/
private void writeReport()
throws WebdavException {
// Create multistatus object
WebdavXMLPrinter generatedXML = new WebdavXMLPrinter();
generatedXML.writeXMLHeader();
generatedXML.writeElement("d", "DAV", "multistatus",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "response",
WebdavXMLPrinter.OPENING);
generatedXML.writeProperty("d", null, "href", requestUri);
// Parse the two properties list, and printout their status
Enumeration propertyList = null;
propertyList = propertiesToSet.elements();
while(propertyList.hasMoreElements()) {
Property property = (Property) propertyList.nextElement();
generatedXML.writeElement("d", null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(property.namespaceAbbrev,
property.namespace, property.name,
WebdavXMLPrinter.NO_CONTENT);
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty
("d", null, "status", "HTTP/1.1 " + property.status + " "
+ WebdavStatus.getStatusText(property.status));
generatedXML.writeElement("d", null, "propstat",
WebdavXMLPrinter.CLOSING);
}
propertyList = propertiesToRemove.elements();
while(propertyList.hasMoreElements()) {
Property property = (Property) propertyList.nextElement();
generatedXML.writeElement("d", null, "propstat",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.OPENING);
generatedXML.writeElement(property.namespaceAbbrev,
property.namespace, property.name,
WebdavXMLPrinter.NO_CONTENT);
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.CLOSING);
generatedXML.writeProperty
("d", null, "status", "HTTP/1.1 " + property.status + " "
+ WebdavStatus.getStatusText(property.status));
generatedXML.writeElement("d", null, "propstat",
WebdavXMLPrinter.CLOSING);
}
generatedXML.writeElement("d", null, "response",
WebdavXMLPrinter.CLOSING);
generatedXML.writeElement("d", "multistatus",
WebdavXMLPrinter.CLOSING);
try {
Writer writer = resp.getWriter();
writer.write(generatedXML.toString());
writer.flush();
} catch (Exception e) {
e.printStackTrace();
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
// --------------------------------------------------- Property Inner Class
private class Property {
public String name;
public String value;
public String namespace;
public String namespaceAbbrev;
public int status = WebdavStatus.SC_OK;
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java
Index: PutMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v 1.1 2000/11/22 06:20:46 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:46 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
import org.apache.slide.security.*;
import org.apache.slide.lock.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
/**
* PUT method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class PutMethod extends WebdavMethod {
// -------------------------------------------------------------- Constants
/**
* HTTP Date format pattern (RFC 2068, 822, 1123).
*/
public static final String DATE_FORMAT = "EEE, d MMM yyyy kk:mm:ss z";
// ----------------------------------------------------- Instance Variables
/**
* Resource to be written.
*/
private String resourcePath;
// ----------------------------------------------------------- Constructors
/**
* PUT Method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public PutMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse XML request.
*
* @exception WebdavException Does not happen
*/
protected void parseRequest()
throws WebdavException {
resourcePath = requestUri;
if (resourcePath == null) {
resourcePath = "/";
}
}
/**
* Execute request.
*
* @exception WebdavException Bad request
*/
protected void executeRequest()
throws WebdavException {
try {
try {
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, resourcePath);
NodeRevisionNumber revisionNumber =
revisionDescriptors.getLatestRevision();
NodeRevisionDescriptor revisionDescriptor =
new NodeRevisionDescriptor(req.getContentLength());
NodeRevisionContent revisionContent =
new NodeRevisionContent();
//revisionContent.setContent(req.getReader());
revisionContent.setContent(req.getInputStream());
NodeProperty property = null;
// Get content length
property = new NodeProperty
("getcontentlength", new Long(req.getContentLength()),
true);
revisionDescriptor.setProperty(property);
// Last modification date
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
property = new NodeProperty("getlastmodified",
new Date(),
true);
revisionDescriptor.setProperty(property);
// Etag generation
String etag = resourcePath.hashCode() + "_"
+ revisionNumber.hashCode() + "_"
+ revisionDescriptor.getContentLength();
property = new NodeProperty("getetag", etag, true);
revisionDescriptor.setProperty(property);
// Resource type
property = new NodeProperty("resourcetype", "", true);
revisionDescriptor.setProperty(property);
content.create(credToken, resourcePath, revisionDescriptor,
revisionContent);
} catch (LinkedObjectNotFoundException e) {
// Nothing we can do here ...
e.printStackTrace();
} catch (ObjectNotFoundException e) {
// Todo : Check to see if parent exists
SubjectNode subject = new SubjectNode();
// Creating an object
structure.create(credToken, subject, resourcePath);
NodeRevisionDescriptor revisionDescriptor =
new NodeRevisionDescriptor(req.getContentLength());
NodeProperty property = null;
// Creation date
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
property = new NodeProperty("creationdate",
new Date(),
true);
revisionDescriptor.setProperty(property);
// Display name
property = new NodeProperty("displayname", resourcePath, true);
revisionDescriptor.setProperty(property);
// Resource type
property = new NodeProperty("resourcetype", "", true);
revisionDescriptor.setProperty(property);
// Source
property = new NodeProperty("source", "", true);
revisionDescriptor.setProperty(property);
// Get content language
property = new NodeProperty("getcontentlanguage", "en", true);
revisionDescriptor.setProperty(property);
// Get content length
property = new NodeProperty
("getcontentlength",
new Long(req.getContentLength()), true);
revisionDescriptor.setProperty(property);
// Get content type
String contentType =
servlet.getServletContext().getMimeType(resourcePath);
if (contentType == null) {
contentType = "TEXT/PLAIN";
}
property = new NodeProperty("getcontenttype", contentType,
true);
revisionDescriptor.setProperty(property);
// Last modification date
property = new NodeProperty
("getlastmodified", new Date(), true);
revisionDescriptor.setProperty(property);
// Etag generation
String etag = resourcePath.hashCode() + "_"
+ (new NodeRevisionNumber()).hashCode() + "_"
+ req.getContentLength();
property = new NodeProperty("getetag", etag, true);
revisionDescriptor.setProperty(property);
if (isMsProprietarySupport()) {
// Name
/*
property = new NodeProperty("name", resourcePath,
"d", "DAV");
revisionDescriptor.setProperty(property);
*/
// ParentName
// TODO : Fix this
/*
property = new NodeProperty("parentname", resourcePath,
"ms", "MICROSOFT");
revisionDescriptor.setProperty(property);
*/
// Href
/*
property = new NodeProperty("href", resourcePath,
"ms", "MICROSOFT");
revisionDescriptor.setProperty(property);
*/
// Is hidden
property = new NodeProperty("ishidden", "0", "MICROSOFT");
revisionDescriptor.setProperty(property);
// Is collection
property = new NodeProperty("iscollection", "0",
"MICROSOFT");
revisionDescriptor.setProperty(property);
// Is read only
property = new NodeProperty("isreadonly", "0",
"MICROSOFT");
revisionDescriptor.setProperty(property);
// Content class
// TODO : Find what it is ...
/*
property = new NodeProperty("contentclass", "",
"MICROSOFT");
revisionDescriptor.setProperty(property);
*/
// Last accessed
property = new NodeProperty("lastaccessed",
(new Date()).toString(),
"MICROSOFT");
revisionDescriptor.setProperty(property);
// Is structured document
/*
property = new NodeProperty("isstructureddocument",
"false", "MICROSOFT");
revisionDescriptor.setProperty(property);
*/
// Default document
/*
property = new NodeProperty("defaultdocument",
"", "MICROSOFT");
revisionDescriptor.setProperty(property);
*/
// Is root
/*
property = new NodeProperty("isroot", "false",
"MICROSOFT");
revisionDescriptor.setProperty(property);
*/
}
// Creating revisionDescriptor associated with the object
NodeRevisionContent revisionContent =
new NodeRevisionContent();
revisionContent.setContent(req.getInputStream());
content.create(credToken, resourcePath, revisionDescriptor,
revisionContent);
}
String status = new String("HTTP/1.1 " + WebdavStatus.SC_CREATED
+ " " + WebdavStatus.getStatusText
(WebdavStatus.SC_CREATED));;
} catch (RevisionAlreadyExistException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
/*
} catch (RevisionDescriptorNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
*/
} catch (ObjectAlreadyExistsException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (ObjectNotFoundException e) {
// 409 - Conflict
resp.setStatus(WebdavStatus.SC_CONFLICT);
} catch (LinkedObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (AccessDeniedException e) {
// 403 - Forbidden
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
} catch (ObjectLockedException e) {
// Locked
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_LOCKED);
} catch (ServiceAccessException e) {
// 500 - Internal server error
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (IOException e) {
// 500 - Internal server error
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (RuntimeException e) {
// 500 - Internal server error
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java
Index: UnlockMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java,v 1.1 2000/11/22 06:20:47 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:47 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.slide.common.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.macro.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.structure.*;
/**
* UNLOCK method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class UnlockMethod extends WebdavMethod {
// ----------------------------------------------------- Instance Variables
/**
* Resource to unlock.
*/
private String toUnlock;
/**
* Id.
*/
private String lockId;
// ----------------------------------------------------------- Constructors
/**
* UNLOCK method constructor.
*
* @param token Namespace access token
* @param req HTTP request
* @param resp HTTP response
*/
public UnlockMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
}
// ------------------------------------------------------ Protected Methods
/**
* Parse the request.
*
* @exception WebdavException Bad request
*/
protected void parseRequest()
throws WebdavException {
// Loads the associated object from the store.
toUnlock = requestUri;
if (toUnlock == null) {
toUnlock = "/";
}
String lockTokenHeader = req.getHeader("Lock-Token");
if (lockTokenHeader != null) {
lockId = parseLockToken(lockTokenHeader);
} else {
// TODO : The call to UNLOCK is invalid
System.out.println("Invalid call");
}
}
/**
* Execute the request.
*
* @exception WebdavException
*/
protected void executeRequest()
throws WebdavException {
if (lockId != null) {
try {
lock.unlock(credToken, requestUri, lockId);
// Checking if the resource at the URI isn't a lock-null
// resource, in which case we must attempt to delete it
ObjectNode node = structure.retrieve(credToken, requestUri);
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(credToken, requestUri);
NodeRevisionDescriptor revisionDescriptor =
content.retrieve(credToken, revisionDescriptors);
NodeProperty typeProperty =
revisionDescriptor.getProperty
(NodeRevisionDescriptor.TYPE);
if (typeProperty.getValue().toString()
.equals("<lock-null/>")) {
content.remove(credToken, requestUri, revisionDescriptor);
content.remove(credToken, revisionDescriptors);
structure.remove(credToken, node);
}
resp.setStatus(WebdavStatus.SC_NO_CONTENT);
} catch (SlideException e) {
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
}
}
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java
Index: WebdavMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java,v 1.1 2000/11/22 06:20:47 remm Exp $
* $Revision: 1.1 $
* $Date: 2000/11/22 06:20:47 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.method;
import java.security.Principal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.apache.slide.common.*;
import org.apache.slide.authenticate.*;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
import org.apache.slide.lock.*;
import org.apache.slide.macro.*;
import org.apache.slide.security.*;
import org.apache.slide.webdav.common.*;
import org.apache.slide.webdav.*;
import org.apache.slide.util.MD5Encoder;
/**
* WebDAV method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public abstract class WebdavMethod {
// -------------------------------------------------------------- Constants
public static final String LOCK_TOKEN = "opaquelocktoken:";
// ----------------------------------------------------- Instance Variables
/**
* Requested Uri.
*/
protected String requestUri;
/**
* Principal.
*/
protected Principal principal;
/**
* Servlet request.
*/
protected HttpServletRequest req;
/**
* Servlet response.
*/
protected HttpServletResponse resp;
/**
* HTTP servlet.
*/
protected GenericServlet servlet;
/**
* Servlet context.
*/
protected ServletContext context;
/**
* Request body.
*/
protected char[] requestBody;
/**
* Namespace access token.
*/
protected NamespaceAccessToken token;
/**
* Files path.
*/
protected String filesPath;
/**
* Structure helper.
*/
protected Structure structure;
/**
* Content helper.
*/
protected Content content;
/**
* Security helper.
*/
protected Security security;
/**
* Lock helper.
*/
protected Lock lock;
/**
* Macro helper.
*/
protected Macro macro;
/**
* Credentials token associated with the principal.
*/
protected CredentialsToken credToken;
/**
* DOM XML parser.
*/
protected static DocumentBuilder documentBuilder;
/**
* Namespaces list. Keyed by abbreviation.
*/
protected Hashtable namespaces;
/**
* Default namespace.
*/
protected String defaultNamespace = NodeProperty.DEFAULT_NAMESPACE;
/**
* MD5 message digest provider.
*/
protected static MessageDigest md5Helper;
/**
* The MD5 helper object for this class.
*/
protected static final MD5Encoder md5Encoder = new MD5Encoder();
/**
* Manager servlet path.
*/
protected static String managerServletPath = "/manager/";
// ----------------------------------------------------------- Constructors
/**
* Method constructor.
*/
public WebdavMethod(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
if (documentBuilder == null) {
try {
documentBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch(ParserConfigurationException e) {
e.printStackTrace();
}
}
this.principal = req.getUserPrincipal();
this.req = req;
this.resp = resp;
this.servlet = servlet;
this.context = servlet.getServletContext();
this.token = token;
this.structure = token.getStructureHelper();
this.content = token.getContentHelper();
this.security = token.getSecurityHelper();
this.lock = token.getLockHelper();
this.macro = token.getMacroHelper();
if (principal != null) {
this.credToken = new CredentialsToken(principal);
} else {
this.credToken = new CredentialsToken("");
}
this.credToken.setEnforceLockTokens(true);
this.requestUri = getRelativePath(req);
parseHeaders();
System.out.println(System.currentTimeMillis() + " - "
+ req.getMethod() + " on object " + requestUri);
}
// --------------------------------------------------------- Public Methods
/**
* Initializes static fields.
*
* @param servletPath Path of the manager servlet
*/
public static void init(String servletPath) {
// Load the MD5 helper used to calculate signatures.
try {
md5Helper = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new IllegalStateException();
}
if (servletPath != null) {
managerServletPath = servletPath;
}
}
/**
* Exceute method.
*
* @exception WebdavException
*/
public void run()
throws WebdavException {
parseRequest();
executeRequest();
/*
if (isMsProprietarySupport()) {
resp.setHeader("Server", "Microsoft-IIS/5.0");
}
*/
}
// ------------------------------------------------------ Protected Methods
/**
* Return the relative path associated with this servlet.
*
* @param request The servlet request we are processing
*/
protected String getRelativePath(HttpServletRequest request) {
String result = request.getPathInfo();
if (result == null) {
result = request.getServletPath();
}
if ((result == null) || (result.equals(""))) {
result = "/";
}
return result;
}
/**
* Parse a node for namespace declaration attributes.
*
* @param node DOM node
*/
protected void parseNodeNamespaceDeclarations(Node node) {
NamedNodeMap nodeMap = node.getAttributes();
if (nodeMap != null) {
for (int i = 0; i < nodeMap.getLength(); i++) {
Node currentNode = nodeMap.item(i);
if (currentNode.getNodeType() != Node.ATTRIBUTE_NODE)
continue;
String attributeName = currentNode.getNodeName();
if (attributeName.startsWith("xmlns")) {
// We found a namespace declaration
if (attributeName.equals("xmlns")) {
defaultNamespace = currentNode.getNodeValue();
} else {
// Stripping out the prefix
if (attributeName.startsWith("xmlns:")) {
String namespaceAbbreviation =
attributeName.substring(6);
namespaces.put(namespaceAbbreviation,
currentNode.getNodeValue());
}
}
}
}
}
}
/**
* Read request contents.
*
* @param req Request object handed out by the servlet container
* @return char[] Array of char which contains the body of the request
*/
protected void readRequestContent() {
namespaces = new Hashtable();
if (req.getContentLength() == 0)
return;
// TODO : Modify this and make it chunking aware
int contentLength = req.getContentLength();
char[] result = null;
if (contentLength > 0) {
try {
BufferedReader reader = null;
requestBody = new char[contentLength];
int position = 0;
reader = req.getReader();
while (position < contentLength) {
int nChar = reader.read(requestBody, position,
contentLength - position);
position = position + nChar;
}
reader.close();
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
/**
* Parse lock token headers.
*/
protected void parseHeaders() {
// Retrieve if header
String ifHeader = req.getHeader("If");
//System.out.println("If header : " + ifHeader);
if (ifHeader == null)
return;
// Parse if header and extract the lock tokens
int pos = ifHeader.indexOf(LOCK_TOKEN);
int endPos = -1;
int offset = LOCK_TOKEN.length();
String lockToken = null;
while (pos != -1) {
endPos = ifHeader.indexOf('>', pos + offset);
if (endPos == -1) {
lockToken = ifHeader;
} else {
lockToken = ifHeader.substring(pos + offset, endPos);
}
//System.out.println("Lock Token found :-" + lockToken + "-");
credToken.addLockToken(lockToken);
pos = ifHeader.indexOf(LOCK_TOKEN, endPos);
}
}
/**
* Returns the lock token value from the lock token header.
*
* @return String Opaque lock token value
*/
protected String parseLockToken(String lockTokenValue) {
int semi = lockTokenValue.indexOf(":");
String result = null;
try {
result = lockTokenValue.substring(semi + 1,
lockTokenValue.length() - 1);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* Tests if a resource is a collection.
*/
protected boolean isCollection(NodeRevisionDescriptor revisionDescriptor) {
boolean result = false;
if (revisionDescriptor == null)
return true;
NodeProperty property = revisionDescriptor.getProperty("resourcetype");
if ((property != null)
&& (property.getValue().equals("<collection/>"))) {
result = true;
}
return result;
}
/**
* Parse WebDAV XML query.
*
* @exception WebdavException
*/
protected abstract void parseRequest()
throws WebdavException;
/**
* Generate XML response.
*
* @exception WebdavException
*/
protected abstract void executeRequest()
throws WebdavException;
/**
* Simulate MS IIS5 ?
*
* @return boolean
*/
protected boolean isMsProprietarySupport() {
return (token.getNamespaceConfig().getParameter("ms") != null);
}
}