1 23 24 25 package org.apache.webdav.lib.methods; 26 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.StringWriter ; 30 import java.util.Enumeration ; 31 import java.util.Hashtable ; 32 import java.util.Vector ; 33 34 import javax.xml.parsers.DocumentBuilder ; 35 import javax.xml.parsers.DocumentBuilderFactory ; 36 import javax.xml.parsers.ParserConfigurationException ; 37 38 import org.apache.commons.httpclient.Header; 39 import org.apache.commons.httpclient.HttpConnection; 40 import org.apache.commons.httpclient.HttpException; 41 import org.apache.commons.httpclient.HttpState; 42 import org.apache.commons.httpclient.HttpStatus; 43 import org.apache.commons.httpclient.URIException; 44 import org.apache.commons.httpclient.util.URIUtil; 45 46 import org.apache.webdav.lib.Property; 47 import org.apache.webdav.lib.ResponseEntity; 48 import org.apache.webdav.lib.properties.PropertyFactory; 49 import org.apache.webdav.lib.util.DOMUtils; 50 import org.apache.webdav.lib.util.DOMWriter; 51 import org.apache.webdav.lib.util.WebdavStatus; 52 import org.apache.webdav.lib.util.XMLDebugOutputer; 53 import org.w3c.dom.Document ; 54 import org.w3c.dom.Element ; 55 import org.w3c.dom.Node ; 56 import org.w3c.dom.NodeList ; 57 import org.xml.sax.ErrorHandler ; 58 import org.xml.sax.InputSource ; 59 import org.xml.sax.SAXException ; 60 import org.xml.sax.SAXParseException ; 61 62 66 public abstract class XMLResponseMethodBase 67 extends HttpRequestBodyMethodBase { 68 69 71 72 private int debug = 0; 74 75 76 78 79 82 public XMLResponseMethodBase() { 83 super(); 84 } 85 86 87 92 public XMLResponseMethodBase(String uri) { 93 super(uri); 94 95 } 96 97 98 100 103 private XMLDebugOutputer xo = new XMLDebugOutputer(); 104 105 106 109 private Document responseDocument = null; 110 111 112 115 protected DocumentBuilder builder = null; 116 117 118 121 private Hashtable responseHashtable = null; 122 123 128 protected Vector responseURLs = null; 129 130 protected String decodeResponseHrefs = null; 131 132 134 135 140 public Document getResponseDocument() { 141 return this.responseDocument; 142 } 143 144 145 151 public Enumeration getResponses() { 152 return getResponseHashtable().elements(); 153 } 154 155 156 158 163 public void setDebug(int debug) { 164 this.debug = debug; 165 166 xo.setDebug((debug > 0)); 167 } 168 169 173 public int getDebug() { 174 return this.debug; 175 } 176 177 184 public void setDecodeResponseHrefs(String encoding) { 185 this.decodeResponseHrefs = encoding; 186 } 187 188 192 public void recycle() { 193 super.recycle(); 194 responseHashtable = null; 195 responseURLs = null; 196 } 197 198 protected void readResponseBody(HttpState state, HttpConnection conn) 199 throws IOException , HttpException { 200 201 super.readResponseBody(state, conn); 202 InputStream inStream = getResponseBodyAsStream(); 203 if (inStream != null) { 204 parseResponse(inStream, state, conn); 205 inStream.close(); 206 } 207 } 208 209 224 protected int getRequestContentLength() { 225 if (!isRequestContentAlreadySet()) { 226 String contents = generateRequestBody(); 227 if (contents == null) 230 contents = ""; 231 232 setRequestBody(contents); 233 234 235 if (debug > 0) { 236 System.out.println("\n>>>>>>> to server ---------------------------------------------------"); 237 System.out.println(getName() + " " + 238 getPath() + (getQueryString() != null ? "?" + getQueryString() : "") + " " + "HTTP/1.1"); 239 240 Header[] headers = getRequestHeaders(); 241 for (int i = 0; i < headers.length; i++) { 242 Header header = headers[i]; 243 System.out.print(header.toString()); 244 } 245 System.out.println("Content-Length: "+super.getRequestContentLength()); 246 247 if (this instanceof DepthSupport) { 248 System.out.println("Depth: "+((DepthSupport)this).getDepth()); 249 } 250 251 System.out.println(); 252 xo.print(contents); 253 System.out.println("------------------------------------------------------------------------"); 254 } 255 256 } 257 258 return super.getRequestContentLength(); 259 } 260 261 262 263 264 270 protected String generateRequestBody() { 271 return ""; 272 } 273 274 288 protected boolean writeRequestBody(HttpState state, HttpConnection conn) 289 throws IOException , HttpException { 290 291 if (getRequestContentLength() > 0) { 292 return super.writeRequestBody(state, conn); 293 } 294 return true; 295 } 296 297 302 public void parseResponse(InputStream input, HttpState state, HttpConnection conn) 303 throws IOException , HttpException { 304 if (getStatusCode() == WebdavStatus.SC_MULTI_STATUS 307 || (this instanceof PropFindMethod || this instanceof ReportMethod) 308 && getStatusCode() == HttpStatus.SC_OK) { 309 try { 310 parseXMLResponse(input); 311 } catch (IOException e) { 312 } 314 } 315 } 316 317 318 protected void parseXMLResponse(InputStream input) 319 throws IOException , HttpException { 320 321 if (builder == null) { 322 try { 323 DocumentBuilderFactory factory = 325 DocumentBuilderFactory.newInstance(); 326 factory.setNamespaceAware(true); 327 builder = factory.newDocumentBuilder(); 328 } catch (ParserConfigurationException e) { 329 throw new HttpException 330 ("XML Parser Configuration error: " + e.getMessage()); 331 } 332 } 333 334 try { 335 336 builder.setErrorHandler(new DummyErrorHandler()); 338 responseDocument = builder.parse(new InputSource (input)); 339 340 if (debug > 0) { 341 System.out.println("\n<<<<<<< from server ---------------------------------------------------"); 342 System.out.println(getStatusLine()); 343 344 Header[] headers = getResponseHeaders(); 345 for (int i = 0; i < headers.length; i++) { 346 Header header = headers[i]; 347 System.out.print(header.toString()); 348 } 349 350 System.out.println(); 351 352 xo.print(responseDocument); 353 System.out.println("------------------------------------------------------------------------"); 354 } 355 356 357 } catch (Exception e) { 358 throw new IOException 359 ("XML parsing error; response stream is not valid XML: " 360 + e.getMessage()); 361 } 362 363 364 369 370 } 371 372 373 protected Hashtable getResponseHashtable() { 374 checkUsed(); 375 if (responseHashtable == null) { 376 initResponseHashtable(); 377 } 378 return responseHashtable; 379 } 380 381 protected Vector getResponseURLs() { 382 checkUsed(); 383 if (responseHashtable == null) { 384 initResponseHashtable(); 385 } 386 return responseURLs; 387 } 388 389 private synchronized void initResponseHashtable() { 390 if (responseHashtable == null) { 391 392 responseHashtable = new Hashtable (); 393 responseURLs = new Vector (); 394 int status = getStatusLine().getStatusCode(); 395 396 if (status == WebdavStatus.SC_MULTI_STATUS 399 || (this instanceof PropFindMethod 400 || this instanceof ReportMethod) 401 && status == HttpStatus.SC_OK) { 402 403 404 Document rdoc = getResponseDocument(); 405 406 NodeList list = null; 407 if (rdoc != null) { 408 Element multistatus = getResponseDocument().getDocumentElement(); 409 list = multistatus.getChildNodes(); 410 } 411 412 if (list != null) { 413 for (int i = 0; i < list.getLength(); i++) { 414 try { 415 Element child = (Element ) list.item(i); 416 String name = DOMUtils.getElementLocalName(child); 417 String namespace = DOMUtils.getElementNamespaceURI 418 (child); 419 if (Response.TAG_NAME.equals(name) && 420 "DAV:".equals(namespace)) { 421 Response response = 422 new ResponseWithinMultistatus(child); 423 String href = getHref(response); 424 responseHashtable.put(href,response); 425 responseURLs.add(href); 426 } 427 } catch (ClassCastException e) { 428 } 429 } 430 } 431 } else if (responseDocument != null) { 432 Response response = new SingleResponse(responseDocument, 433 getPath(), status); 434 String href = getHref(response); 435 responseHashtable.put(href, response); 436 responseURLs.add(href); 437 } 438 } 439 } 440 441 442 private String getHref(Response response) { 443 String href = response.getHref(); 444 if (this.decodeResponseHrefs != null) { 445 try { 446 href = URIUtil.decode(href, this.decodeResponseHrefs); 447 } 448 catch (URIException e1) { 449 e1.printStackTrace(); 451 } 452 } 453 return href; 454 } 455 456 457 463 protected static Property convertElementToProperty( 464 Response response, Element element) { 465 466 return PropertyFactory.create(response, element); 467 468 } 469 470 471 473 474 477 public abstract class Response implements ResponseEntity { 478 479 protected Node node = null; 480 481 Response(Node node) { 482 this.node = node; 483 } 484 485 public static final String TAG_NAME = "response"; 486 public abstract int getStatusCode(); 487 public abstract String getHref(); 488 489 public Enumeration getHistories(){ 490 Vector result = new Vector (); 491 return result.elements(); 492 } 493 public Enumeration getWorkspaces(){ 494 Vector result = new Vector (); 495 return result.elements(); 496 } 497 public Enumeration getProperties() { 498 NodeList list = 499 DOMUtils.getElementsByTagNameNS(node, "prop", "DAV:"); 500 Vector vector = new Vector (); 501 for (int i = 0; list != null && i < list.getLength(); i++ ) { 502 Element element = (Element ) list.item(i); 503 NodeList children = element.getChildNodes(); 504 for (int j = 0; children != null && j < children.getLength(); 505 j++) { 506 try { 507 Element child = (Element ) children.item(j); 508 vector.addElement(XMLResponseMethodBase. 509 convertElementToProperty(this, child)); 510 } catch (ClassCastException e) { 511 } 512 } 513 } 514 return vector.elements(); 515 } 516 517 public String toString () { 518 StringWriter tmp = new StringWriter (); 519 DOMWriter domWriter = new DOMWriter(tmp, true); 520 domWriter.print(node); 521 return tmp.getBuffer().toString(); 522 } 523 } 524 525 526 529 class ResponseWithinMultistatus extends Response { 530 531 public ResponseWithinMultistatus(Element element) { 532 super(element); 533 } 534 535 public int getStatusCode() { 536 539 Element propstat = getFirstElement("DAV:", "propstat"); 549 if (propstat != null ) { 550 Element status = DOMUtils.getFirstElement(propstat,"DAV:", "status"); 551 if (status != null) { 552 return DOMUtils.parseStatus(DOMUtils.getTextValue(status)); 553 } 554 } 555 556 Element status = getFirstElement("DAV:", "status"); 564 if (status != null) { 565 return DOMUtils.parseStatus(DOMUtils.getTextValue(status)); 566 } 567 568 return -1; 569 } 570 571 public String getHref() { 572 Element href = getFirstElement("DAV:", "href"); 573 if (href != null) { 574 return DOMUtils.getTextValue(href); 575 } else { 576 return ""; 577 } 578 579 } 580 581 protected Element getFirstElement(String namespace, String name) { 582 return DOMUtils.getFirstElement(this.node, namespace, name); 583 } 584 } 585 586 class SingleResponse extends Response { 587 588 private int statusCode = -1; 589 private String href = null; 590 591 SingleResponse(Document document, String href, int statusCode) { 592 super(document); 593 this.statusCode = statusCode; 594 this.href = href; 595 } 596 597 public int getStatusCode() { 598 return this.statusCode; 599 } 600 601 public String getHref() { 602 return this.href; 603 } 604 } 605 606 class OptionsResponse extends SingleResponse{ 607 608 OptionsResponse(Document document, String href, int statusCode) { 609 super(document, href, statusCode); 610 611 } 612 613 614 public Enumeration getWorkspaces(){ 615 616 617 Node root = responseDocument.cloneNode(true).getFirstChild(); 618 620 String sPrefix = root.getPrefix(); 621 Vector result = new Vector (); 622 623 Node child = root.getFirstChild(); 624 while (child!=null && !child.getNodeName().equalsIgnoreCase(sPrefix+":workspace-collection-set")){ 625 child = child.getNextSibling(); 626 } 627 628 if (child!=null && child.getNodeName().equalsIgnoreCase(sPrefix+":workspace-collection-set")){ 629 child = child.getFirstChild(); 630 while (child!=null){ 631 result.add(child.getFirstChild().getNodeValue()); 632 child = child.getNextSibling(); 633 } 634 } 635 636 return result.elements(); 637 } 638 639 public Enumeration getHistories(){ 640 Node root = responseDocument.cloneNode(true).getFirstChild(); 641 643 String sPrefix = root.getPrefix(); 644 Vector result = new Vector (); 645 646 648 Node child = root.getFirstChild(); 649 while (child!=null && !child.getNodeName().equalsIgnoreCase(sPrefix+":version-history-collection-set")){ 650 child = child.getNextSibling(); 651 } 652 653 if (child!=null && child.getNodeName().equalsIgnoreCase(sPrefix+":version-history-collection-set")){ 654 child = child.getFirstChild(); 655 while (child!=null){ 656 result.add(child.getFirstChild().getNodeValue()); 657 child = child.getNextSibling(); 658 } 659 } 660 661 return result.elements(); 662 } 663 664 } 665 protected void setDocument(Document doc){ 666 responseDocument = doc; 667 } 668 protected void setResponseHashtable(Hashtable h){ 669 responseHashtable = h; 670 } 671 672 673 674 675 private static class DummyErrorHandler implements ErrorHandler { 676 677 678 698 public void warning(SAXParseException exception) throws SAXException 699 { 700 } 702 703 728 public void error(SAXParseException exception) throws SAXException 729 { 730 } 732 733 753 public void fatalError(SAXParseException exception) throws SAXException 754 { 755 } 757 758 } 759 760 761 762 763 } 764 765 | Popular Tags |