001: /*
002: * Copyright 2005 Hippo Webworks.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package nl.hippo.slide.webdav.method;
017:
018: import java.io.IOException;
019: import java.text.ParseException;
020: import java.text.SimpleDateFormat;
021: import java.util.Date;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Locale;
025: import java.util.TimeZone;
026:
027: import org.apache.lucene.document.Document;
028: import org.apache.lucene.search.Hits;
029: import org.apache.lucene.search.IndexSearcher;
030: import org.apache.lucene.search.Query;
031: import org.apache.lucene.search.Sort;
032: import org.apache.slide.common.NamespaceAccessToken;
033: import org.apache.slide.common.RequestedProperties;
034: import org.apache.slide.common.RequestedProperty;
035: import org.apache.slide.common.SlideException;
036: import org.apache.slide.index.lucene.Index;
037: import org.apache.slide.index.lucene.IndexConfiguration;
038: import org.apache.slide.index.lucene.LuceneOrderBy;
039: import org.apache.slide.index.lucene.expressions.AbstractLuceneExpression;
040: import org.apache.slide.search.BadGatewayException;
041: import org.apache.slide.search.BadQueryException;
042: import org.apache.slide.search.InvalidQueryException;
043: import org.apache.slide.search.InvalidScopeException;
044: import org.apache.slide.search.QueryScope;
045: import org.apache.slide.search.RequestedResource;
046: import org.apache.slide.search.Search;
047: import org.apache.slide.search.SearchException;
048: import org.apache.slide.search.SearchQuery;
049: import org.apache.slide.search.SearchQueryResult;
050: import org.apache.slide.search.basic.BasicQueryImpl;
051: import org.apache.slide.search.basic.IBasicQuery;
052: import org.apache.slide.search.basic.Literals;
053: import org.apache.slide.search.basic.LuceneBasicQuery;
054: import org.apache.slide.security.AccessDeniedException;
055: import org.apache.slide.structure.ObjectNotFoundException;
056: import org.apache.slide.util.Configuration;
057: import org.apache.slide.webdav.WebdavException;
058: import org.apache.slide.webdav.WebdavServletConfig;
059: import org.apache.slide.webdav.method.AbstractWebdavMethod;
060: import org.apache.slide.webdav.method.ReadMethod;
061: import org.apache.slide.webdav.util.ComputedPropertyProvider;
062: import org.apache.slide.webdav.util.PropertyRetriever;
063: import org.apache.slide.webdav.util.WebdavConstants;
064: import org.apache.slide.webdav.util.WebdavStatus;
065: import org.apache.slide.webdav.util.WebdavUtils;
066: import org.jdom.Element;
067: import org.jdom.JDOMException;
068: import org.jdom.Namespace;
069: import org.jdom.output.XMLOutputter;
070:
071: /**
072: * SEARCH-NOACL method.
073: *
074: */
075: public class SearchNoACLMethod extends AbstractWebdavMethod implements
076: WebdavConstants, ReadMethod {
077:
078: public static final Namespace HIPPO_NS = Namespace.getNamespace(
079: "hippo", "http://hippo.nl/slide");
080: public static final Namespace DAV_NS = Namespace.getNamespace("D",
081: "DAV:");
082: public static final Namespace SLIDE_NS = Namespace.getNamespace(
083: "S", "http://jakarta.apache.org/slide/");
084:
085: // ----------------------------------------------------- Instance variables
086:
087: private SearchQuery searchQuery = null;
088: private Search searchHelper = null;
089: private LuceneOrderBy luceneOrderBy = null;
090: private int offset = 0;
091: private int limit = Integer.MAX_VALUE;
092:
093: private RequestedProperties requestedProperties = null;
094: /** if true, an ALL_PROP request will include computed props */
095: protected boolean extendedAllprop = false;
096:
097: public SearchNoACLMethod(NamespaceAccessToken token,
098: WebdavServletConfig config) {
099: super (token, config);
100: }
101:
102: /**
103: * Method parseRequest
104: *
105: * @throws WebdavException
106: */
107: protected void parseRequest() throws WebdavException {
108:
109: searchHelper = token.getSearchHelper();
110:
111: String slidePath = null;
112: extendedAllprop = getBooleanInitParameter("extendedAllprop");
113:
114: if (Configuration.useSearch()) {
115: try {
116: Element queryElement = getQueryElement();
117: String grammarNamespace = queryElement
118: .getNamespaceURI();
119:
120: Element limitElement = queryElement.getChild(
121: Literals.LIMIT, queryElement.getNamespace());
122: setLimitOffset(limitElement);
123:
124: Element orderByElement = queryElement.getChild(
125: Literals.ORDERBY, queryElement.getNamespace());
126:
127: if (orderByElement != null) {
128: luceneOrderBy = new LuceneOrderBy();
129: luceneOrderBy.init(orderByElement);
130: }
131:
132: int maxDepth = getConfig().getDepthLimit();
133:
134: searchQuery = searchHelper.createSearchQuery(
135: grammarNamespace, queryElement, slideToken,
136: maxDepth, new ComputedPropertyProvider(token,
137: slideToken, getSlideContextPath(),
138: getConfig()), req.getRequestURI());
139:
140: requestedProperties = searchQuery.requestedProperties();
141:
142: if (searchQuery instanceof IBasicQuery) {
143: QueryScope scope = ((IBasicQuery) searchQuery)
144: .getScope();
145: slidePath = ((IBasicQuery) searchQuery)
146: .getSlidePath();
147: // check, if scope is accessible (ACL)
148: token.getContentHelper().retrieve(slideToken,
149: slidePath);
150:
151: scope.setIsCollection(WebdavUtils.isCollection(
152: token, slideToken, slidePath));
153: }
154: } catch (JDOMException e) {
155: resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
156: resp.setContentType(TEXT_XML_UTF_8);
157: createErrorResult(SearchQueryResult.STATUS_BAD_QUERY, e
158: .getMessage());
159: throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
160: } catch (InvalidQueryException e) {
161: resp.setStatus(WebdavStatus.SC_UNPROCESSABLE_ENTITY);
162: resp.setContentType(TEXT_XML_UTF_8);
163: createErrorResult(
164: SearchQueryResult.STATUS_UNPROCESSABLE_ENTITY,
165: e.getMessage());
166: throw new WebdavException(
167: WebdavStatus.SC_UNPROCESSABLE_ENTITY);
168: } catch (BadGatewayException e) {
169: resp.setStatus(WebdavStatus.SC_BAD_GATEWAY);
170: resp.setContentType(TEXT_XML_UTF_8);
171: createErrorResult(SearchQueryResult.STATUS_BAD_GATEWAY,
172: e.getMessage());
173: throw new WebdavException(WebdavStatus.SC_BAD_GATEWAY);
174: } catch (InvalidScopeException e) {
175: resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
176: resp.setContentType(TEXT_XML_UTF_8);
177: createErrorResult(
178: SearchQueryResult.STATUS_INVALID_SCOPE, e
179: .getMessage());
180:
181: throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
182: } catch (BadQueryException e) {
183: resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
184: resp.setContentType(TEXT_XML_UTF_8);
185: createErrorResult(SearchQueryResult.STATUS_BAD_QUERY, e
186: .getMessage());
187: throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
188: } catch (AccessDeniedException e) {
189:
190: String contextPath = getSlideContextPath();
191: AccessDeniedException ade = new AccessDeniedException(
192: contextPath + e.getObjectUri(), contextPath
193: + e.getSubjectUri(), contextPath
194: + e.getActionUri());
195:
196: String msg = ade.getMessage();
197: resp.setStatus(WebdavStatus.SC_FORBIDDEN);
198: resp.setContentType(TEXT_XML_UTF_8);
199: createErrorResult(SearchQueryResult.STATUS_FORBIDDEN,
200: msg);
201: throw new WebdavException(WebdavStatus.SC_FORBIDDEN);
202: } catch (ObjectNotFoundException e) {
203: resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
204: resp.setContentType(TEXT_XML_UTF_8);
205: createErrorResult(
206: SearchQueryResult.STATUS_INVALID_SCOPE,
207: "scope " + slidePath + " is invalid");
208:
209: throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
210: } catch (SlideException e) {
211: e.printStackTrace();
212: }
213: } else {
214: resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
215: resp.setContentType(TEXT_XML_UTF_8);
216: createErrorResult(SearchQueryResult.STATUS_BAD_QUERY,
217: "FACETS not implemented on this server");
218: throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
219: }
220: }
221:
222: private void setLimitOffset(Element limitElement)
223: throws BadQueryException {
224: if (limitElement != null) {
225: Element nResElem = limitElement.getChild(Literals.NRESULTS,
226: limitElement.getNamespace());
227: if (nResElem == null)
228: throw new BadQueryException(
229: BasicQueryImpl.NRESULTS_MISSING);
230: try {
231: this .limit = new Integer(nResElem.getTextTrim())
232: .intValue();
233: } catch (NumberFormatException e) {
234: throw new BadQueryException(
235: BasicQueryImpl.NRESULTS_MUST_BE_AN_INTEGER);
236: }
237: nResElem = limitElement.getChild("offset", SLIDE_NS);
238:
239: if (nResElem != null) {
240: try {
241: this .offset = new Integer(nResElem.getTextTrim())
242: .intValue();
243: if (this .offset < 0) {
244: this .offset = 0;
245: }
246: } catch (NumberFormatException e) {
247: throw new BadQueryException(
248: LuceneBasicQuery.OFFSET_MUST_BE_AN_INTEGER);
249: } catch (Exception IGNORE) {
250: } // maybe NPE if element doesn't exist
251: }
252: }
253: }
254:
255: protected void executeRequest() throws WebdavException {
256:
257: resp.setContentType(TEXT_XML_UTF_8);
258:
259: org.jdom.Element rootElement = new org.jdom.Element(
260: "multistatus", DAV_NS);
261:
262: org.jdom.Document responseDoc = new org.jdom.Document(
263: rootElement);
264:
265: if (((IBasicQuery) searchQuery).getExpression() instanceof AbstractLuceneExpression) {
266: AbstractLuceneExpression exp = (AbstractLuceneExpression) ((IBasicQuery) searchQuery)
267: .getExpression();
268:
269: Index index = exp.getIndex();
270: IndexSearcher searcher = null;
271: Query query;
272: try {
273: query = exp.getExecutableQuery();
274: searcher = index.getSearcher();
275: Hits hits = null;
276: if (index.getLogger().isDebugEnabled()) {
277: index.getLogger().debug(
278: " Lucene query is " + query.toString());
279: }
280: if (luceneOrderBy != null) {
281: Sort sort = luceneOrderBy.getSorter();
282: hits = searcher.search(query, sort);
283: } else {
284: hits = searcher.search(query);
285: }
286: int counter = 0;
287:
288: for (int i = offset, l = hits.length(); (i < l)
289: && (limit == -1 || counter < limit); i++) {
290:
291: Document doc = hits.doc(i);
292: Element davResponse = new Element("response",
293: DAV_NS);
294:
295: String uri = doc.get(Index.URI_FIELD_NAME);
296: Element hrefproperty = new Element("href", DAV_NS);
297: hrefproperty.setText(this .slideContextPath + uri);
298: davResponse.addContent(hrefproperty);
299:
300: Iterator props = requestedProperties
301: .getRequestedProperties();
302:
303: Element propstatFound = new Element("propstat",
304: DAV_NS);
305: Element propstatNotFound = new Element("propstat",
306: DAV_NS);
307: Element propsFound = new Element("prop", DAV_NS);
308: Element propsNotFound = new Element("prop", DAV_NS);
309: boolean notFoundProp = false;
310: while (props.hasNext()) {
311: RequestedProperty prop = (RequestedProperty) props
312: .next();
313: String fieldname = IndexConfiguration
314: .generateFieldName(prop.getNamespace(),
315: prop.getName());
316: Element property = new Element(prop.getName(),
317: Namespace.getNamespace(prop
318: .getNamespace()));
319:
320: if (prop.getNamespace().equals(
321: SLIDE_NS.getURI())
322: && prop.getName().equals("nrHits")) {
323: property.setText(String.valueOf(hits
324: .length()));
325: propsFound.addContent(property);
326: } else if (prop.getNamespace().equals(
327: SLIDE_NS.getURI())
328: && prop.getName().equals("hitPosition")) {
329: property.setText(String.valueOf(counter));
330: propsFound.addContent(property);
331: } else {
332: if (doc.get(fieldname) == null) {
333: notFoundProp = true;
334: propsNotFound.addContent(property);
335: } else {
336: if (index.getConfiguration()
337: .isDateProperty(
338: prop.getNamespace(),
339: prop.getName())) {
340: property
341: .setText(getOriginalDateFormat(
342: fieldname,
343: doc.get(fieldname)));
344: } else {
345: property
346: .setText(doc.get(fieldname));
347: }
348: propsFound.addContent(property);
349: }
350: }
351:
352: }
353:
354: propstatFound.addContent(propsFound);
355: propstatNotFound.addContent(propsNotFound);
356: Element statusFound = new Element("status", DAV_NS);
357: statusFound.setText("HTTP/1.1 "
358: + WebdavStatus.SC_OK + " OK");
359: propstatFound.addContent(statusFound);
360: davResponse.addContent(propstatFound);
361:
362: if (notFoundProp) {
363: Element statusNotFound = new Element("status",
364: DAV_NS);
365: statusNotFound.setText("HTTP/1.1 "
366: + WebdavStatus.SC_NOT_FOUND
367: + " Not Found");
368: propstatNotFound.addContent(statusNotFound);
369: davResponse.addContent(propstatNotFound);
370: }
371: rootElement.addContent(davResponse);
372: counter++;
373: }
374:
375: } catch (SearchException e) {
376: System.err.println(e.getMessage());
377: e.printStackTrace();
378: resp.setStatus(getErrorCode(e)); // no special handling needed
379: throw new WebdavException(WebdavStatus.SC_ACCEPTED,
380: false); // abort the TA
381: } catch (IOException e) {
382: System.err.println(e.getMessage());
383: e.printStackTrace();
384: resp.setStatus(getErrorCode(e)); // no special handling needed
385: throw new WebdavException(WebdavStatus.SC_ACCEPTED,
386: false); // abort the TA
387: } finally {
388: if (searcher != null) {
389: try {
390: index.releaseSearcher(searcher);
391: searcher = null;
392: } catch (IOException e1) {
393: }
394: }
395: }
396:
397: }
398:
399: resp.setStatus(WebdavStatus.SC_OK);
400: //System.out.println("fetching result took " + (System.currentTimeMillis() - start) + " ms");
401: try {
402: sendResult(responseDoc);
403: } catch (Exception e) {
404: e.printStackTrace();
405: }
406:
407: }
408:
409: private String getOriginalDateFormat(String fieldName,
410: String dateString) {
411: // because dates are formatted before stored I can only hardcode on property to type
412: if (dateString == null || dateString.equals("")) {
413: return "";
414: }
415:
416: try {
417: synchronized (Index.DATE_INDEX_FORMAT) {
418: if (fieldName.equals(IndexConfiguration
419: .generateFieldName("DAV:", "getlastmodified"))) {
420: return dateToIndexString(Index.DATE_INDEX_FORMAT
421: .parse(dateString), 0);
422: }
423: if (fieldName.equals(IndexConfiguration
424: .generateFieldName("DAV:", "creationdate"))) {
425: return dateToIndexString(Index.DATE_INDEX_FORMAT
426: .parse(dateString), 4);
427: }
428: if (fieldName.equals(IndexConfiguration
429: .generateFieldName("http://hippo.nl/slide",
430: "lastSaved"))) {
431: return dateToIndexString(Index.DATE_INDEX_FORMAT
432: .parse(dateString), 4);
433: }
434: if (fieldName.equals(IndexConfiguration
435: .generateFieldName("DAV:", "modificationdate"))) {
436: return dateToIndexString(Index.DATE_INDEX_FORMAT
437: .parse(dateString), 4);
438: }
439: }
440: } catch (ParseException e) {
441: return dateString;
442: }
443: return dateString;
444: }
445:
446: public static synchronized String dateToIndexString(Date date, int i) {
447: return formats[i].format(date);
448: }
449:
450: private static final SimpleDateFormat formats[] = {
451: new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",
452: Locale.US),
453: new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",
454: Locale.US),
455: new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",
456: Locale.US),
457: new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US),
458: new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") };
459:
460: static {
461: formats[0].setTimeZone(TimeZone.getTimeZone("GMT"));
462: }
463:
464: private Element getQueryElement() throws WebdavException,
465: JDOMException {
466: Element queryElement = null;
467: try {
468: org.jdom.Document document = parseRequestContent(); // TODO: check root element name
469:
470: Element rootElement = document.getRootElement();
471: List children = rootElement.getChildren();
472: if (children.size() > 0) {
473: queryElement = (Element) children.get(0);
474: }
475: return queryElement;
476:
477: } catch (IOException e) {
478: System.err.println(e.getMessage());
479: e.printStackTrace();
480: resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
481: throw new WebdavException(
482: WebdavStatus.SC_INTERNAL_SERVER_ERROR);
483: }
484: }
485:
486: private void sendResult(org.jdom.Document responseDoc)
487: throws org.jdom.JDOMException, IOException {
488: org.jdom.output.Format format = org.jdom.output.Format
489: .getPrettyFormat();
490: format.setIndent(XML_RESPONSE_INDENT);
491: XMLOutputter xmlWriter = new XMLOutputter(format);
492: xmlWriter.output(responseDoc, resp.getWriter());
493: }
494:
495: private void createErrorResult(int queryStatus, String message)
496: throws WebdavException {
497: SearchQueryResult result = new SearchQueryResult();
498: result.setStatus(queryStatus);
499: result.setDescription(message);
500: result.setHref(getSlideContextPath());
501:
502: try {
503: WebdavResult webdavResult = new WebdavResult(result, null);
504: org.jdom.Document responseDoc = webdavResult
505: .getWebdavResultDocument();
506: sendResult(responseDoc);
507: } catch (Exception e) {
508: System.err.println(e.getMessage());
509: e.printStackTrace();
510: resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
511: throw new WebdavException(
512: WebdavStatus.SC_INTERNAL_SERVER_ERROR);
513: }
514: }
515:
516: /**
517: * Represents the webdav result for a SEARCH. It encapsulates the response
518: * body, and the status of the response. It contains a list of response
519: * elements with propstat elements and optional a response element with
520: * an error status and a responsedescription
521: */
522: class WebdavResult {
523:
524: private SearchQueryResult queryResult;
525: private org.jdom.Document responseDoc;
526:
527: /** the status of the response */
528: private int webdavStatus = WebdavStatus.SC_MULTI_STATUS;
529:
530: /**
531: * constructs a WebdavResult
532: *
533: * @param queryResult the result of the query
534: * @param retriever the retriever to get the properties
535: *
536: * @throws JDOMException
537: * @throws SlideException
538: *
539: */
540: WebdavResult(SearchQueryResult queryResult,
541: PropertyRetriever retriever)
542: throws org.jdom.JDOMException, SlideException {
543: this .queryResult = queryResult;
544: init();
545: }
546:
547: /**
548: * Method getWebdavStatus
549: *
550: * @return an int
551: *
552: */
553: int getWebdavStatus() {
554: return webdavStatus;
555: }
556:
557: /**
558: * Method getWebdabResultDocument
559: *
560: * @return a Document
561: *
562: */
563: org.jdom.Document getWebdavResultDocument() {
564: return responseDoc;
565: }
566:
567: /**
568: * Method init
569: *
570: * @throws JDOMException
571: * @throws SlideException
572: *
573: */
574: private void init() throws org.jdom.JDOMException,
575: SlideException {
576:
577: String href = null;
578: int errorStatus = webdavStatus;
579:
580: org.jdom.Element rootElement = new org.jdom.Element(
581: E_MULTISTATUS, DNSP);
582:
583: responseDoc = new org.jdom.Document(rootElement);
584:
585: Iterator it = queryResult.iterator();
586: while (it.hasNext()) {
587:
588: org.jdom.Element responseElement = new org.jdom.Element(
589: E_RESPONSE, DNSP);
590:
591: rootElement.addContent(responseElement);
592: org.jdom.Element hrefElement = new org.jdom.Element(
593: E_HREF, DNSP);
594:
595: RequestedResource resource = (RequestedResource) it
596: .next();
597: String internalUri = resource.getUri();
598:
599: String absUri = WebdavUtils.getAbsolutePath(
600: internalUri, req, getConfig());
601:
602: hrefElement.addContent(absUri);
603:
604: responseElement.addContent(hrefElement);
605:
606: }
607:
608: int status = queryResult.getStatus();
609: if (status != SearchQueryResult.STATUS_OK) {
610:
611: //String webdavStatusText = null;
612:
613: switch (status) {
614: case SearchQueryResult.STATUS_BAD_QUERY:
615: webdavStatus = WebdavStatus.SC_BAD_REQUEST;
616: errorStatus = WebdavStatus.SC_BAD_REQUEST;
617: href = queryResult.getHref();
618: break;
619:
620: case SearchQueryResult.STATUS_INVALID_SCOPE:
621: webdavStatus = WebdavStatus.SC_BAD_REQUEST;
622: errorStatus = WebdavStatus.SC_NOT_FOUND;
623: href = queryResult.getHref();
624: break;
625:
626: case SearchQueryResult.STATUS_PARTIAL_RESULT:
627: errorStatus = WebdavStatus.SC_INSUFFICIENT_STORAGE;
628: href = getSlideContextPath();
629: break;
630:
631: case SearchQueryResult.STATUS_UNPROCESSABLE_ENTITY:
632: errorStatus = WebdavStatus.SC_UNPROCESSABLE_ENTITY;
633: href = getSlideContextPath();
634: break;
635:
636: case SearchQueryResult.STATUS_BAD_GATEWAY:
637: errorStatus = WebdavStatus.SC_BAD_GATEWAY;
638: href = queryResult.getHref();
639: break;
640:
641: case SearchQueryResult.STATUS_FORBIDDEN:
642: errorStatus = WebdavStatus.SC_FORBIDDEN;
643: href = queryResult.getHref();
644: break;
645:
646: default:
647: throw new WebdavException(
648: WebdavStatus.SC_INTERNAL_SERVER_ERROR);
649:
650: }
651: org.jdom.Element responseElement = new org.jdom.Element(
652: E_RESPONSE, DNSP);
653:
654: org.jdom.Element hrefElement = new org.jdom.Element(
655: E_HREF, DNSP);
656:
657: hrefElement.addContent(href);
658:
659: org.jdom.Element statusElement = new org.jdom.Element(
660: E_STATUS, DNSP);
661:
662: statusElement.addContent(getStatusText(errorStatus));
663: responseElement.addContent(hrefElement);
664: responseElement.addContent(statusElement);
665:
666: String description = queryResult.getDescription();
667: if (description != null) {
668: org.jdom.Element responseDescriptionElement = new org.jdom.Element(
669: E_RESPONSEDESCRIPTION, DNSP);
670:
671: responseDescriptionElement.addContent(description);
672: responseElement
673: .addContent(responseDescriptionElement);
674: }
675:
676: if (status == SearchQueryResult.STATUS_INVALID_SCOPE) {
677: responseElement.addContent(new org.jdom.Element(
678: "scopeerror", DNSP));
679: }
680: rootElement.addContent(responseElement);
681: }
682: }
683:
684: /**
685: * Method getStatusText
686: *
687: * @param status an int
688: *
689: * @return a String
690: *
691: */
692: private String getStatusText(int status) {
693: return "HTTP/1.1 " + status + " "
694: + WebdavStatus.getStatusText(status);
695: }
696: }
697: }
|