001: /*
002: * (C) Copyright Simulacra Media Ltd, 2004. All rights reserved.
003: *
004: * The program is provided "AS IS" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * Simulacra Media Ltd will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will Simulacra Media Ltd be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * Simulacra Media Ltd has been advised of the possibility of their occurrence.
011: * Simulacra Media Ltd will not be liable for any third party claims against you.
012: *
013: */
014:
015: package com.ibm.webdav.protocol.http;
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: /**
029: * Executes the WebDAV DASL Search method.
030: *
031: * @author Michael Bell
032: * @since November 13, 2003
033: */
034: public class SearchMethod extends WebDAVMethod {
035: private static Logger m_logger = Logger
036: .getLogger(SearchMethod.class.getName());
037:
038: public static final String TAG_QUERY_SCHEMA_DISCOVERY = "query-schema-discovery";
039: public static final String TAG_SEARCHREQUEST = "searchrequest";
040:
041: /** Construct a PropFindMethod.
042: * @param request the servlet request
043: * @param response the servlet response
044: * @exception com.ibm.webdav.WebDAVException
045: */
046: public SearchMethod(HttpServletRequest request,
047: HttpServletResponse response) throws WebDAVException {
048: super (request, response);
049: methodName = "SEARCH";
050: }
051:
052: /** Execute the method.
053: * @return the result status code
054: */
055: public WebDAVStatus execute() {
056: MultiStatus multiStatus = null;
057:
058: try {
059: // get any arguments out of the headers
060: String depth = context.getRequestContext().depth();
061:
062: Document contents = null;
063:
064: if (context.getRequestContext().contentLength() > 0) {
065: // get the request entity body and parse it
066: WebDAVErrorHandler errorHandler = new WebDAVErrorHandler(
067: resource.getURL().toString());
068:
069: /*Parser xmlParser = new Parser(resource.getURL().toString(), errorListener, null);
070: xmlParser.setWarningNoDoctypeDecl(false);
071: xmlParser.setProcessNamespace(true);
072: contents = xmlParser.readStream(request.getReader());*/
073: DocumentBuilderFactory factory = DocumentBuilderFactory
074: .newInstance();
075: factory.setNamespaceAware(true);
076:
077: DocumentBuilder docbuilder = factory
078: .newDocumentBuilder();
079: docbuilder.setErrorHandler(errorHandler);
080: contents = docbuilder
081: .parse(new org.xml.sax.InputSource(request
082: .getReader()));
083:
084: if (errorHandler.getErrorCount() > 0) {
085: throw new WebDAVException(
086: WebDAVStatus.SC_BAD_REQUEST,
087: "Syntax error in SEARCH request entity body");
088: }
089: }
090:
091: // get the arguments for the getProperties() method, and figure
092: // out which method variant to call.
093: if (ResourceImpl.debug) {
094: System.err.println("property request entity:");
095:
096: PrintWriter pout = new PrintWriter(System.err);
097: pout.print(XMLUtility.printNode(contents
098: .getDocumentElement()));
099:
100: //((Document) contents).printWithFormat(pout);
101: }
102:
103: Element rootEl = (Element) ((contents == null) ? null
104: : contents.getDocumentElement());
105:
106: if (rootEl.getNamespaceURI().equals("DAV:") == false) {
107: throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,
108: "Wrong namespace for request");
109: }
110:
111: if (rootEl.getLocalName().equals(
112: SearchMethod.TAG_QUERY_SCHEMA_DISCOVERY)) {
113: Element searchEl = (Element) rootEl
114: .getElementsByTagName("*").item(0);
115:
116: SearchRequest searchReq = SearchRequestFactory
117: .getSearchRequest(searchEl);
118:
119: multiStatus = resource.getSearchSchema(context,
120: searchReq);
121:
122: } else if (rootEl.getLocalName().equals(
123: SearchMethod.TAG_SEARCHREQUEST)) {
124: Element searchEl = (Element) rootEl
125: .getElementsByTagName("*").item(0);
126:
127: SearchRequest searchReq = SearchRequestFactory
128: .getSearchRequest(searchEl);
129: try {
130: multiStatus = resource.executeSearch(context,
131: searchReq);
132: } catch (WebDAVException e) {
133: String sMsg = e.getMessage();
134: if (sMsg != null && sMsg.indexOf("scope") > 0) {
135: setStatusCode(e.getStatusCode());
136: PrintWriter pout = new PrintWriter(response
137: .getWriter(), false);
138: pout.print(this
139: .getScopeErrorResponse(searchReq));
140: pout.close();
141: }
142: throw e;
143: }
144: }
145:
146: context.getResponseContext().contentType("text/xml");
147: setResponseHeaders();
148: setStatusCode(WebDAVStatus.SC_MULTI_STATUS);
149:
150: // output the results as an XML document
151: Document results = multiStatus.asXML();
152:
153: // set the character encoding for the document to that specified by
154: // the client in the Accept header
155: //((Document) results).setEncoding(getResponseCharset());
156: if (ResourceImpl.debug) {
157: System.err.println("property results:");
158:
159: PrintWriter pout = new PrintWriter(System.err);
160: pout.print(XMLUtility.printNode(results
161: .getDocumentElement()));
162:
163: }
164:
165: PrintWriter pout = new PrintWriter(response.getWriter(),
166: false);
167: pout.print(XMLUtility.printNode(results
168: .getDocumentElement()));
169: pout.close();
170: } catch (WebDAVException exc) {
171: m_logger.log(Level.INFO, exc.getMessage() + " - "
172: + request.getQueryString());
173: setStatusCode(exc.getStatusCode());
174: } catch (Exception exc) {
175: m_logger.log(Level.WARNING, exc.getMessage(), exc);
176: setStatusCode(WebDAVStatus.SC_INTERNAL_SERVER_ERROR);
177: }
178:
179: return context.getStatusCode();
180: }
181:
182: private String getScopeErrorResponse(SearchRequest searchReq) {
183: String response = "";
184: try {
185: Document document = DocumentBuilderFactory.newInstance()
186: .newDocumentBuilder().newDocument();
187:
188: Element multiEl = document.createElementNS("DAV:",
189: "D:multistatus");
190: multiEl.setAttribute("xmlns:D", "DAV:");
191:
192: Element respEl = document.createElementNS("DAV:",
193: "D:response");
194:
195: Element hrefEl = document.createElementNS("DAV:", "D:href");
196:
197: hrefEl.appendChild(document.createTextNode(searchReq
198: .getScopeURI()));
199:
200: respEl.appendChild(hrefEl);
201:
202: Element statusEl = document.createElementNS("DAV:",
203: "D:status");
204:
205: Element scopeErrorEl = document.createElementNS("DAV:",
206: "D:scopeerror");
207:
208: statusEl.appendChild(document
209: .createTextNode("HTTP/1.1 404 Object Not Found"));
210:
211: respEl.appendChild(scopeErrorEl);
212:
213: respEl.appendChild(statusEl);
214:
215: multiEl.appendChild(respEl);
216:
217: response = XMLUtility.printNode(multiEl);
218:
219: } catch (Exception e) {
220: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
221: }
222:
223: return response;
224: }
225: }
|