001: package com.ibm.webdav.protocol.http;
002:
003: /*
004: * (C) Copyright IBM Corp. 2000 All rights reserved.
005: *
006: * The program is provided "AS IS" without any warranty express or
007: * implied, including the warranty of non-infringement and the implied
008: * warranties of merchantibility and fitness for a particular purpose.
009: * IBM will not be liable for any damages suffered by you as a result
010: * of using the Program. In no event will IBM be liable for any
011: * special, indirect or consequential damages or lost profits even if
012: * IBM has been advised of the possibility of their occurrence. IBM
013: * will not be liable for any third party claims against you.
014: *
015: * Portions Copyright (C) Simulacra Media Ltd, 2004.
016: */
017: import java.io.*;
018: import java.util.*;
019: import java.util.logging.*;
020:
021: import javax.servlet.http.*;
022: import javax.xml.parsers.*;
023:
024: import org.w3c.dom.*;
025:
026: import com.ibm.webdav.*;
027: import com.ibm.webdav.Collection;
028: import com.ibm.webdav.impl.*;
029:
030: /** Executes the WebDAV COPY method.
031: * @author Jim Amsden <jamsden@us.ibm.com>
032: */
033: public class CopyMethod extends WebDAVMethod {
034:
035: private static Logger m_logger = Logger.getLogger(CopyMethod.class
036: .getName());
037:
038: /** Construct a CopyMethod.
039: * @param request the servlet request
040: * @param response the servlet response
041: * @exception com.ibm.webdav.WebDAVException
042: */
043: public CopyMethod(HttpServletRequest request,
044: HttpServletResponse response) throws WebDAVException {
045: super (request, response);
046: methodName = "COPY";
047: }
048:
049: /** Execute the method.
050: * @return the result status code
051: */
052: public WebDAVStatus execute() {
053: setStatusCode(WebDAVStatus.SC_CREATED); // the default status code
054: MultiStatus multiStatus = null;
055: try {
056: // get any arguments out of the headers
057: String depth = context.getRequestContext().depth();
058: if (depth == null) {
059: depth = Collection.deep;
060: }
061: if (!(depth.equals(Collection.shallow) || depth
062: .equals(Collection.deep))) {
063: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
064: "Depth header must be 0 or infinity if present");
065: }
066: String destination = context.getRequestContext()
067: .destination();
068: String overwriteString = context.getRequestContext()
069: .overwrite();
070: boolean overwrite = overwriteString != null
071: && overwriteString.equals("T");
072: Vector propertiesToCopy = null;
073: if (request.getContentLength() > 0) {
074: // get the request entity body and parse it. This will contain the rules
075: // for copying properties
076: WebDAVErrorHandler errorHandler = new WebDAVErrorHandler(
077: resource.getURL().toString());
078: DocumentBuilderFactory factory = DocumentBuilderFactory
079: .newInstance();
080: factory.setNamespaceAware(true);
081: DocumentBuilder docbuilder = factory
082: .newDocumentBuilder();
083: docbuilder.setErrorHandler(errorHandler);
084: /*Parser xmlParser = new Parser(resource.getURL().toString(), errorListener, null);
085:
086: xmlParser.setProcessNamespace(true);
087: xmlParser.setWarningNoDoctypeDecl(false);
088:
089: Document document = xmlParser.readStream(request.getReader());*/
090: Document document = docbuilder
091: .parse(new org.xml.sax.InputSource(request
092: .getReader()));
093: if (errorHandler.getErrorCount() > 0) {
094: throw new WebDAVException(
095: WebDAVStatus.SC_BAD_REQUEST,
096: "Syntax error in COPY request entity body");
097: }
098: Element propertybehavior = (Element) document
099: .getDocumentElement();
100: Element keepalive = (Element) propertybehavior
101: .getElementsByTagNameNS("DAV:", "keepalive")
102: .item(0);
103: if (keepalive != null) {
104: propertiesToCopy = new Vector();
105: NodeList hrefs = keepalive.getElementsByTagNameNS(
106: "DAV:", "href");
107: Element href = null;
108: for (int i = 0; i < hrefs.getLength(); i++) {
109: href = (Element) hrefs.item(i);
110: String propertyURI = ((Text) href
111: .getFirstChild()).getData();
112: propertiesToCopy.addElement(propertyURI);
113: }
114: }
115: }
116:
117: if (ResourceImpl.debug) {
118: System.err.println("Copying " + resource.getURL()
119: + " to " + destination);
120: System.err.print("Copying properties: ");
121: if (propertiesToCopy == null) {
122: System.err.println("all");
123: } else {
124: System.err.println();
125: Enumeration propertyNames = propertiesToCopy
126: .elements();
127: while (propertyNames.hasMoreElements()) {
128: System.err.println(" "
129: + propertyNames.nextElement());
130: }
131: }
132: }
133: if (resource.isCollection()) {
134: multiStatus = ((CollectionImpl) resource)
135: .copy(context, destination, overwrite,
136: propertiesToCopy, depth);
137: } else {
138: multiStatus = resource.copy(context, destination,
139: overwrite, propertiesToCopy);
140: }
141:
142: // don't send back an empty multistatus response entity,
143: // just return the status code
144: Enumeration responses = multiStatus.getResponses();
145: if (responses.hasMoreElements()) {
146: MethodResponse methodResponse = (MethodResponse) responses
147: .nextElement();
148: if (responses.hasMoreElements()) {
149: // there's more than one response, so return a multistatus
150: context.getResponseContext()
151: .contentType("text/xml");
152: setStatusCode(WebDAVStatus.SC_MULTI_STATUS);
153: setResponseHeaders();
154:
155: // output the results as an XML document
156: Document results = multiStatus.asXML();
157: //((Document) results).setEncoding(getResponseCharset());
158: if (ResourceImpl.debug) {
159: System.err.println("copy results:");
160: PrintWriter pout = new PrintWriter(System.err);
161: pout.print(XMLUtility.printNode(results
162: .getDocumentElement()));
163: //((Document) results).printWithFormat(pout);
164: }
165: PrintWriter pout = new PrintWriter(response
166: .getWriter(), false);
167: pout.print(XMLUtility.printNode(results
168: .getDocumentElement()));
169: //((Document) results).print(pout);
170: pout.close();
171: } else {
172: // there was just one MethodResponse, so return it directly instead
173: // of wrapped in a multistatus
174: setStatusCode(methodResponse.getStatus());
175: setResponseHeaders();
176: }
177: } else {
178: setStatusCode(WebDAVStatus.SC_CREATED); // the default status code
179: setResponseHeaders();
180: }
181: } catch (WebDAVException exc) {
182: m_logger.log(Level.INFO, exc.getLocalizedMessage() + " - "
183: + request.getQueryString());
184: setStatusCode(exc.getStatusCode());
185: } catch (Exception exc) {
186: m_logger.log(Level.WARNING, exc.getMessage(), exc);
187:
188: setStatusCode(WebDAVStatus.SC_INTERNAL_SERVER_ERROR);
189: }
190: return context.getStatusCode();
191: }
192: }
|