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.logging.*;
019:
020: import javax.servlet.http.*;
021: import javax.xml.parsers.*;
022:
023: import org.w3c.dom.*;
024:
025: import com.ibm.webdav.*;
026: import com.ibm.webdav.impl.*;
027:
028: /** Executes the WebDAV LOCK method.
029: * @author Jim Amsden <jamsden@us.ibm.com>
030: */
031: public class LockMethod extends WebDAVMethod {
032:
033: private static Logger m_logger = Logger.getLogger(LockMethod.class
034: .getName());
035:
036: /** Construct a LockMethod.
037: * @param request the servlet request
038: * @param response the servlet response
039: * @exception com.ibm.webdav.WebDAVException
040: */
041: public LockMethod(HttpServletRequest request,
042: HttpServletResponse response) throws WebDAVException {
043: super (request, response);
044: methodName = "LOCK";
045: }
046:
047: /** Execute the method.
048: * @return the result status code
049: */
050: public WebDAVStatus execute() {
051:
052: try {
053: setStatusCode(WebDAVStatus.SC_OK);
054:
055: // get information from the headers
056: String depth = context.getRequestContext().depth();
057: if (depth == null) {
058: depth = Collection.deep;
059: }
060: if (!(depth.equals(Collection.shallow) || depth
061: .equals(Collection.deep))) {
062: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
063: "Depth header must be 0 or infinity");
064: }
065:
066: int timeout = context.getRequestContext().getTimeout();
067: context.setMethodName(methodName);
068: String lockToken = null;
069: Precondition precondition = context.getRequestContext()
070: .precondition();
071: if (precondition != null) {
072: lockToken = context.getRequestContext().precondition()
073: .toString();
074: }
075: if (lockToken != null && lockToken.length() > 2) {
076: // strip off the (<...>) delimiters
077: lockToken = lockToken.substring(2,
078: lockToken.length() - 2);
079: }
080:
081: // get the request entity body and lock or refresh the lock
082: // on the resource
083: Element lockinfo = null;
084: // don't attempt to read an empty request body if there's a
085: // lock token. It must be a refresh which doesn't have a request
086: // entity body.
087: if (lockToken == null) {
088: WebDAVErrorHandler errorHandler = new WebDAVErrorHandler(
089: resource.getURL().toString());
090: /*Parser xmlParser = new Parser(resource.getURL().toString(), errorListener, null);
091: xmlParser.setWarningNoDoctypeDecl(false);
092: xmlParser.setProcessNamespace(true);
093: Document contents = xmlParser.readStream(request.getReader());*/
094: DocumentBuilderFactory factory = DocumentBuilderFactory
095: .newInstance();
096: factory.setNamespaceAware(true);
097: DocumentBuilder docbuilder = factory
098: .newDocumentBuilder();
099: docbuilder.setErrorHandler(errorHandler);
100:
101: Document contents = docbuilder
102: .parse(new org.xml.sax.InputSource(request
103: .getReader()));
104: if (errorHandler.getErrorCount() > 0) {
105: throw new WebDAVException(
106: WebDAVStatus.SC_BAD_REQUEST,
107: "Syntax error in LOCK request entity body");
108: }
109: lockinfo = (Element) contents.getDocumentElement();
110: }
111:
112: MultiStatus multiStatus = null;
113: if (lockinfo != null) { // doing a lock
114:
115: Element lockscope = (Element) lockinfo
116: .getElementsByTagNameNS("DAV:", "lockscope")
117: .item(0);
118:
119: String type = null;
120: Element locktype = (Element) lockinfo
121: .getElementsByTagNameNS("DAV:", "locktype")
122: .item(0);
123: String scope = null;
124: if (lockscope != null) {
125: if (lockscope.getElementsByTagNameNS("DAV:",
126: "exclusive").item(0) != null) {
127: scope = ActiveLock.exclusive;
128: } else if (lockscope.getElementsByTagNameNS("DAV:",
129: "shared").item(0) != null) {
130: scope = ActiveLock.shared;
131: }
132: }
133:
134: if (locktype != null) {
135: if (locktype
136: .getElementsByTagNameNS("DAV:", "write")
137: .item(0) != null) {
138: type = ActiveLock.writeLock;
139: }
140: }
141: Element owner = (Element) lockinfo
142: .getElementsByTagNameNS("DAV:", "owner")
143: .item(0);
144: if (resource.exists() && resource.isCollection()) {
145: multiStatus = ((CollectionImpl) resource)
146: .lock(context, scope, type, timeout, owner,
147: depth);
148: } else {
149: multiStatus = resource.lock(context, scope, type,
150: timeout, owner);
151: }
152:
153: } else {
154:
155: if (lockToken != null) { // doing a refresh
156: multiStatus = resource.refreshLock(context,
157: lockToken, timeout);
158: } else { // bad lock request
159: throw new WebDAVException(
160: WebDAVStatus.SC_BAD_REQUEST,
161: "LOCK missing Lock-Token header or bad LOCK request entity body");
162: }
163:
164: }
165: if (multiStatus.getResponses().hasMoreElements()) {
166: context.getResponseContext().contentType("text/xml");
167: setResponseHeaders();
168:
169: // output the results as an XML document
170: // if the lock request is on a single resource (depth=shallow),
171: // output a document with a prop containing a lockdiscovery on the
172: // resource as the document element. Otherwise, use a multistatus.
173: //
174: Document results = null;
175: if (depth.equals(Collection.shallow)) {
176: results = DocumentBuilderFactory.newInstance()
177: .newDocumentBuilder().newDocument();
178: //results.setVersion(Resource.XMLVersion);
179: Element prop = results.createElementNS("DAV:",
180: "D:prop");
181: prop.setAttribute("xmlns:D", "DAV:");
182: results.appendChild(prop);
183: // the property must be a lockdiscovery property
184: PropertyResponse response = (PropertyResponse) multiStatus
185: .getResponses().nextElement();
186: PropertyValue lockDiscovery = response
187: .getProperty(PropertyName.pnLockdiscovery);
188: if (lockDiscovery != null) {
189: prop.appendChild(results.importNode(
190: lockDiscovery.value, true));
191: }
192: } else {
193: setStatusCode(WebDAVStatus.SC_MULTI_STATUS);
194: results = (Document) multiStatus.asXML();
195: }
196: //((Document) results).setEncoding(getResponseCharset());
197: PrintWriter pout = new PrintWriter(
198: response.getWriter(), false);
199: pout.print(XMLUtility.printNode(results
200: .getDocumentElement()));
201: //((Document) results).print(pout);
202: pout.close();
203: } else {
204: setResponseHeaders();
205: }
206: } catch (WebDAVException exc) {
207: m_logger.log(Level.INFO, exc.getLocalizedMessage() + " - "
208: + request.getQueryString());
209: setStatusCode(exc.getStatusCode());
210: } catch (Exception exc) {
211: m_logger.log(Level.WARNING, exc.getMessage(), exc);
212: setStatusCode(WebDAVStatus.SC_INTERNAL_SERVER_ERROR);
213: }
214: return context.getStatusCode();
215: }
216: }
|