1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_ucb.hxx" 24 25 #include <webdavresponseparser.hxx> 26 #include <com/sun/star/xml/sax/XDocumentHandler.hpp> 27 #include <cppuhelper/implbase2.hxx> 28 #include <com/sun/star/xml/sax/XParser.hpp> 29 #include <com/sun/star/xml/sax/InputSource.hpp> 30 #include <comphelper/processfactory.hxx> 31 #include <comphelper/seqstream.hxx> 32 #include <com/sun/star/ucb/LockEntry.hpp> 33 #include <com/sun/star/ucb/LockScope.hpp> 34 #include <com/sun/star/ucb/LockType.hpp> 35 #include <map> 36 #include <hash_map> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 using namespace com::sun::star; 41 42 ////////////////////////////////////////////////////////////////////////////// 43 // WebDAVNamespace enum and StringToEnum converter 44 45 namespace 46 { 47 enum WebDAVNamespace 48 { 49 WebDAVNamespace_unknown = 0, 50 WebDAVNamespace_DAV, 51 WebDAVNamespace_ucb_openoffice_org_dav_props, 52 53 WebDAVNamespace_last 54 }; 55 56 WebDAVNamespace StrToWebDAVNamespace(const rtl::OUString& rStr) 57 { 58 static ::rtl::OUString aStrDAV(::rtl::OUString::createFromAscii("DAV:")); 59 static ::rtl::OUString aStrUcbOpenofficeOrgDAVProps(::rtl::OUString::createFromAscii("http://ucb.openoffice.org/dav/props/")); 60 61 if(rStr.equals(aStrDAV)) 62 { 63 return WebDAVNamespace_DAV; 64 } 65 else if(rStr.equals(aStrUcbOpenofficeOrgDAVProps)) 66 { 67 return WebDAVNamespace_ucb_openoffice_org_dav_props; 68 } 69 70 return WebDAVNamespace_unknown; 71 } 72 } // end of anonymous namespace 73 74 ////////////////////////////////////////////////////////////////////////////// 75 // WebDAVName enum and StringToEnum converter using hash_map 76 77 namespace 78 { 79 enum WebDAVName 80 { 81 WebDAVName_unknown = 0, 82 WebDAVName_multistatus, 83 WebDAVName_response, 84 WebDAVName_href, 85 WebDAVName_propstat, 86 WebDAVName_prop, 87 WebDAVName_resourcetype, 88 WebDAVName_collection, 89 WebDAVName_getcontenttype, 90 WebDAVName_supportedlock, 91 WebDAVName_lockentry, 92 WebDAVName_lockscope, 93 WebDAVName_exclusive, 94 WebDAVName_locktype, 95 WebDAVName_write, 96 WebDAVName_shared, 97 WebDAVName_status, 98 WebDAVName_getlastmodified, 99 WebDAVName_creationdate, 100 WebDAVName_getcontentlength, 101 102 WebDAVName_last 103 }; 104 105 WebDAVName StrToWebDAVName(const rtl::OUString& rStr) 106 { 107 typedef std::hash_map< rtl::OUString, WebDAVName, rtl::OUStringHash > WebDAVNameMapper; 108 typedef std::pair< rtl::OUString, WebDAVName > WebDAVNameValueType; 109 static WebDAVNameMapper aWebDAVNameMapperList; 110 111 if(aWebDAVNameMapperList.empty()) 112 { 113 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("multistatus"), WebDAVName_multistatus)); 114 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("response"), WebDAVName_response)); 115 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("href"), WebDAVName_href)); 116 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("propstat"), WebDAVName_propstat)); 117 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("prop"), WebDAVName_prop)); 118 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("resourcetype"), WebDAVName_resourcetype)); 119 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("collection"), WebDAVName_collection)); 120 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontenttype"), WebDAVName_getcontenttype)); 121 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("supportedlock"), WebDAVName_supportedlock)); 122 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockentry"), WebDAVName_lockentry)); 123 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockscope"), WebDAVName_lockscope)); 124 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("exclusive"), WebDAVName_exclusive)); 125 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("locktype"), WebDAVName_locktype)); 126 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("write"), WebDAVName_write)); 127 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("shared"), WebDAVName_shared)); 128 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("status"), WebDAVName_status)); 129 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getlastmodified"), WebDAVName_getlastmodified)); 130 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("creationdate"), WebDAVName_creationdate)); 131 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontentlength"), WebDAVName_getcontentlength)); 132 } 133 134 const WebDAVNameMapper::const_iterator aResult(aWebDAVNameMapperList.find(rStr)); 135 136 if(aResult == aWebDAVNameMapperList.end()) 137 { 138 return WebDAVName_unknown; 139 } 140 else 141 { 142 return aResult->second; 143 } 144 } 145 } // end of anonymous namespace 146 147 ////////////////////////////////////////////////////////////////////////////// 148 // WebDAVContext, holding information for each start/endElement pair 149 150 namespace 151 { 152 typedef std::map< ::rtl::OUString, ::rtl::OUString > NamespaceMap; 153 typedef std::pair< const ::rtl::OUString, ::rtl::OUString > NamespaceValueType; 154 155 class WebDAVContext 156 { 157 private: 158 WebDAVContext* mpParent; 159 NamespaceMap maNamespaceMap; 160 ::rtl::OUString maWhiteSpace; 161 162 ::rtl::OUString maNamespace; 163 ::rtl::OUString maName; 164 165 WebDAVNamespace maWebDAVNamespace; 166 WebDAVName maWebDAVName; 167 168 // local helpers 169 void parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs); 170 ::rtl::OUString mapNamespaceToken(const ::rtl::OUString& rToken) const; 171 void splitName(const ::rtl::OUString& rSource); 172 173 public: 174 WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs); 175 ~WebDAVContext(); 176 177 WebDAVContext* getParent() const { return mpParent; } 178 ::rtl::OUString& getWhiteSpace() { return maWhiteSpace; } 179 void setWhiteSpace(const ::rtl::OUString& rNew) { maWhiteSpace = rNew; } 180 181 const ::rtl::OUString& getNamespace() const { return maNamespace; } 182 const ::rtl::OUString& getName() const { return maName; } 183 WebDAVNamespace getWebDAVNamespace() const { return maWebDAVNamespace; } 184 WebDAVName getWebDAVName() const { return maWebDAVName; } 185 }; 186 187 void WebDAVContext::parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs) 188 { 189 const sal_Int16 nAttributes(xAttribs->getLength()); 190 static ::rtl::OUString aStrXmlns(::rtl::OUString::createFromAscii("xmlns")); 191 192 for(sal_Int16 a(0); a < nAttributes; a++) 193 { 194 const ::rtl::OUString aName(xAttribs->getNameByIndex(a)); 195 const sal_Int32 nLen(aName.getLength()); 196 197 if(nLen) 198 { 199 if(aName.match(aStrXmlns, 0)) 200 { 201 const sal_Int32 nIndex(aName.indexOf(sal_Unicode(':'), 0)); 202 203 if(-1 != nIndex && nIndex + 1 < nLen) 204 { 205 const ::rtl::OUString aToken(aName.copy(nIndex + 1)); 206 207 maNamespaceMap.insert(NamespaceValueType(aToken, xAttribs->getValueByIndex(a))); 208 } 209 } 210 } 211 } 212 } 213 214 ::rtl::OUString WebDAVContext::mapNamespaceToken(const ::rtl::OUString& rToken) const 215 { 216 NamespaceMap::const_iterator iter = maNamespaceMap.find(rToken); 217 218 if(maNamespaceMap.end() == iter) 219 { 220 if(getParent()) 221 { 222 return getParent()->mapNamespaceToken(rToken); 223 } 224 else 225 { 226 return rToken; 227 } 228 } 229 else 230 { 231 return (*iter).second; 232 } 233 } 234 235 void WebDAVContext::splitName(const ::rtl::OUString& rSource) 236 { 237 const sal_Int32 nLen(rSource.getLength()); 238 maNamespace = ::rtl::OUString(); 239 maName = rSource; 240 241 if(nLen) 242 { 243 const sal_Int32 nIndex(rSource.indexOf(sal_Unicode(':'), 0)); 244 245 if(-1 != nIndex && nIndex > 0 && nIndex + 1 < nLen) 246 { 247 maNamespace = mapNamespaceToken(rSource.copy(0, nIndex)); 248 maName = rSource.copy(nIndex + 1); 249 } 250 } 251 } 252 253 WebDAVContext::WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs) 254 : mpParent(pParent), 255 maNamespaceMap(), 256 maWhiteSpace(), 257 maNamespace(), 258 maName(), 259 maWebDAVNamespace(WebDAVNamespace_unknown), 260 maWebDAVName(WebDAVName_unknown) 261 { 262 const sal_Int16 nAttributes(xAttribs->getLength()); 263 264 if(nAttributes) 265 { 266 // parse evtl. namespace entries 267 parseForNamespaceTokens(xAttribs); 268 } 269 270 // split name to namespace and name 271 splitName(aName); 272 273 // evaluate enums for namespace and name 274 maWebDAVNamespace = StrToWebDAVNamespace(maNamespace); 275 maWebDAVName = StrToWebDAVName(maName); 276 } 277 278 WebDAVContext::~WebDAVContext() 279 { 280 } 281 } // end of anonymous namespace 282 283 ////////////////////////////////////////////////////////////////////////////// 284 // the Xml parser itself 285 286 namespace 287 { 288 enum WebDAVResponseParserMode 289 { 290 WebDAVResponseParserMode_PropFind = 0, 291 WebDAVResponseParserMode_PropName 292 }; 293 294 class WebDAVResponseParser : public cppu::WeakImplHelper1< com::sun::star::xml::sax::XDocumentHandler > 295 { 296 private: 297 std::vector< http_dav_ucp::DAVResource > maResult_PropFind; 298 std::vector< http_dav_ucp::DAVResourceInfo > maResult_PropName; 299 300 WebDAVContext* mpContext; 301 ::rtl::OUString maHref; 302 ::rtl::OUString maStatus; 303 std::vector< http_dav_ucp::DAVPropertyValue > maResponseProperties; 304 std::vector< http_dav_ucp::DAVPropertyValue > maPropStatProperties; 305 std::vector< ::rtl::OUString > maResponseNames; 306 std::vector< ::rtl::OUString > maPropStatNames; 307 uno::Sequence< ucb::LockEntry > maLockEntries; 308 ucb::LockScope maLockScope; 309 ucb::LockType maLockType; 310 WebDAVResponseParserMode meWebDAVResponseParserMode; 311 312 // bitfield 313 bool mbResourceTypeCollection : 1; 314 bool mbLockScopeSet : 1; 315 bool mbLockTypeSet : 1; 316 317 // local helpers 318 bool whitespaceIsAvailable() const 319 { 320 return mpContext && mpContext->getWhiteSpace().getLength(); 321 } 322 bool hasParent(WebDAVName aWebDAVName) const 323 { 324 return mpContext && mpContext->getParent() && aWebDAVName == mpContext->getParent()->getWebDAVName(); 325 } 326 bool propertyIsReady() const 327 { 328 return hasParent(WebDAVName_prop) && whitespaceIsAvailable(); 329 } 330 bool isCollectingProperties() const 331 { 332 return WebDAVResponseParserMode_PropFind == meWebDAVResponseParserMode; 333 } 334 bool isCollectingPropNames() const 335 { 336 return WebDAVResponseParserMode_PropName == meWebDAVResponseParserMode; 337 } 338 bool collectThisPropertyAsName() const 339 { 340 return isCollectingPropNames() && hasParent(WebDAVName_prop); 341 } 342 void pop_context() 343 { 344 if(mpContext) 345 { 346 WebDAVContext* pTemp = mpContext; 347 mpContext = mpContext->getParent(); 348 delete pTemp; 349 } 350 else 351 { 352 OSL_ENSURE(false, "Parser context pop without context (!)"); 353 } 354 } 355 356 public: 357 WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode); 358 ~WebDAVResponseParser(); 359 360 // Methods XDocumentHandler 361 virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException); 362 virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException); 363 virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException); 364 virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException); 365 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException); 366 virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException); 367 virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (xml::sax::SAXException, uno::RuntimeException); 368 virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException); 369 370 const std::vector< http_dav_ucp::DAVResource >& getResult_PropFind() const { return maResult_PropFind; } 371 const std::vector< http_dav_ucp::DAVResourceInfo >& getResult_PropName() const { return maResult_PropName; } 372 }; 373 374 WebDAVResponseParser::WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode) 375 : maResult_PropFind(), 376 maResult_PropName(), 377 mpContext(0), 378 maHref(), 379 maStatus(), 380 maResponseProperties(), 381 maPropStatProperties(), 382 maResponseNames(), 383 maPropStatNames(), 384 maLockEntries(), 385 maLockScope(ucb::LockScope_EXCLUSIVE), 386 maLockType(ucb::LockType_WRITE), 387 meWebDAVResponseParserMode(eWebDAVResponseParserMode), 388 mbResourceTypeCollection(false), 389 mbLockScopeSet(false), 390 mbLockTypeSet(false) 391 { 392 } 393 394 WebDAVResponseParser::~WebDAVResponseParser() 395 { 396 OSL_ENSURE(!mpContext, "Parser destructed with existing content (!)"); 397 while(mpContext) 398 { 399 pop_context(); 400 } 401 } 402 403 void SAL_CALL WebDAVResponseParser::startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 404 { 405 OSL_ENSURE(!mpContext, "Parser start with existing content (!)"); 406 } 407 408 void SAL_CALL WebDAVResponseParser::endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 409 { 410 OSL_ENSURE(!mpContext, "Parser end with existing content (!)"); 411 } 412 413 void SAL_CALL WebDAVResponseParser::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException) 414 { 415 const sal_Int32 nLen(aName.getLength()); 416 417 if(nLen) 418 { 419 // create new context (push) 420 mpContext = new WebDAVContext(mpContext, aName, xAttribs); 421 422 if(collectThisPropertyAsName()) 423 { 424 // When collecting property names and parent is prop there is no need 425 // to handle the content of this property deeper (evtl. preparations) 426 } 427 else 428 { 429 switch(mpContext->getWebDAVNamespace()) 430 { 431 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled 432 { 433 break; 434 } 435 case WebDAVNamespace_DAV: 436 { 437 switch(mpContext->getWebDAVName()) 438 { 439 default: // WebDAVName_unknown, WebDAVName_last or unhandled 440 { 441 break; 442 } 443 case WebDAVName_propstat: 444 { 445 // propstat start 446 if(isCollectingProperties()) 447 { 448 // reset maPropStatProperties 449 maPropStatProperties.clear(); 450 } 451 else 452 { 453 // when collecting properties reset maPropStatNames 454 maPropStatNames.clear(); 455 } 456 break; 457 } 458 case WebDAVName_response: 459 { 460 // response start, reset Href and status and maResponseProperties 461 maHref = maStatus = ::rtl::OUString(); 462 463 if(isCollectingProperties()) 464 { 465 // reset maResponseProperties 466 maResponseProperties.clear(); 467 } 468 else 469 { 470 // reset maResponseNames when collecting properties 471 maResponseNames.clear(); 472 } 473 break; 474 } 475 case WebDAVName_resourcetype: 476 { 477 // resourcetype start, reset collection 478 mbResourceTypeCollection = false; 479 break; 480 } 481 case WebDAVName_supportedlock: 482 { 483 // supportedlock start, reset maLockEntries 484 maLockEntries.realloc(0); 485 break; 486 } 487 case WebDAVName_lockentry: 488 { 489 // lockentry start, reset maLockEntries 490 mbLockScopeSet = false; 491 mbLockTypeSet = false; 492 break; 493 } 494 } 495 break; 496 } 497 case WebDAVNamespace_ucb_openoffice_org_dav_props: 498 { 499 break; 500 } 501 } 502 } 503 } 504 } 505 506 void SAL_CALL WebDAVResponseParser::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException) 507 { 508 const sal_Int32 nLen(aName.getLength()); 509 OSL_ENSURE(mpContext, "Parser EndElement without content (!)"); 510 511 if(mpContext && nLen) 512 { 513 if(collectThisPropertyAsName()) 514 { 515 // When collecting property names and parent is prop, just append the prop name 516 // to the collection, no need to parse deeper 517 maPropStatNames.push_back(mpContext->getNamespace() + mpContext->getName()); 518 } 519 else 520 { 521 switch(mpContext->getWebDAVNamespace()) 522 { 523 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled 524 { 525 break; 526 } 527 case WebDAVNamespace_DAV: 528 { 529 switch(mpContext->getWebDAVName()) 530 { 531 default: // WebDAVName_unknown, WebDAVName_last or unhandled 532 { 533 break; 534 } 535 case WebDAVName_href: 536 { 537 // href end, save it if we have whitespace 538 if(whitespaceIsAvailable()) 539 { 540 maHref = mpContext->getWhiteSpace(); 541 } 542 break; 543 } 544 case WebDAVName_status: 545 { 546 // status end, save it if we have whitespace 547 if(whitespaceIsAvailable()) 548 { 549 maStatus = mpContext->getWhiteSpace(); 550 } 551 break; 552 } 553 case WebDAVName_getlastmodified: 554 { 555 // getlastmodified end, safe if content is correct 556 if(propertyIsReady()) 557 { 558 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getlastmodified")); 559 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 560 561 aDAVPropertyValue.Name = aStr; 562 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); 563 maPropStatProperties.push_back(aDAVPropertyValue); 564 } 565 break; 566 } 567 case WebDAVName_creationdate: 568 { 569 // creationdate end, safe if content is correct 570 if(propertyIsReady()) 571 { 572 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:creationdate")); 573 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 574 575 aDAVPropertyValue.Name = aStr; 576 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); 577 maPropStatProperties.push_back(aDAVPropertyValue); 578 } 579 break; 580 } 581 case WebDAVName_collection: 582 { 583 // collection end, check and set 584 if(hasParent(WebDAVName_resourcetype)) 585 { 586 mbResourceTypeCollection = true; 587 } 588 break; 589 } 590 case WebDAVName_resourcetype: 591 { 592 // resourcetype end, check for collection 593 if(hasParent(WebDAVName_prop)) 594 { 595 static rtl::OUString aStrA(rtl::OUString::createFromAscii("DAV:resourcetype")); 596 static rtl::OUString aStrB(rtl::OUString::createFromAscii("collection")); 597 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 598 599 aDAVPropertyValue.Name = aStrA; 600 aDAVPropertyValue.Value <<= (mbResourceTypeCollection ? aStrB : rtl::OUString()); 601 maPropStatProperties.push_back(aDAVPropertyValue); 602 } 603 break; 604 } 605 case WebDAVName_getcontentlength: 606 { 607 // getcontentlength end, safe if content is correct 608 if(propertyIsReady()) 609 { 610 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontentlength")); 611 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 612 613 aDAVPropertyValue.Name = aStr; 614 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); 615 maPropStatProperties.push_back(aDAVPropertyValue); 616 } 617 break; 618 } 619 case WebDAVName_getcontenttype: 620 { 621 // getcontenttype end, safe if content is correct 622 if(propertyIsReady()) 623 { 624 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontenttype")); 625 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 626 627 aDAVPropertyValue.Name = aStr; 628 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); 629 maPropStatProperties.push_back(aDAVPropertyValue); 630 } 631 break; 632 } 633 case WebDAVName_supportedlock: 634 { 635 // supportedlock end 636 if(hasParent(WebDAVName_prop) && maLockEntries.hasElements()) 637 { 638 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:supportedlock")); 639 http_dav_ucp::DAVPropertyValue aDAVPropertyValue; 640 641 aDAVPropertyValue.Name = aStr; 642 aDAVPropertyValue.Value <<= maLockEntries; 643 maPropStatProperties.push_back(aDAVPropertyValue); 644 } 645 break; 646 } 647 case WebDAVName_lockentry: 648 { 649 // lockentry end 650 if(hasParent(WebDAVName_supportedlock) && (mbLockScopeSet && mbLockTypeSet)) 651 { 652 const sal_Int32 nLength(maLockEntries.getLength()); 653 ucb::LockEntry aEntry; 654 655 aEntry.Scope = maLockScope; 656 aEntry.Type = maLockType; 657 maLockEntries.realloc(nLength + 1); 658 maLockEntries[nLength] = aEntry; 659 } 660 break; 661 } 662 case WebDAVName_exclusive: 663 { 664 // exclusive lockscope end 665 if(hasParent(WebDAVName_lockscope)) 666 { 667 maLockScope = ucb::LockScope_EXCLUSIVE; 668 mbLockScopeSet = true; 669 } 670 break; 671 } 672 case WebDAVName_shared: 673 { 674 // shared lockscope end 675 if(hasParent(WebDAVName_lockscope)) 676 { 677 maLockScope = ucb::LockScope_SHARED; 678 mbLockScopeSet = true; 679 } 680 break; 681 } 682 case WebDAVName_write: 683 { 684 // write locktype end 685 if(hasParent(WebDAVName_locktype)) 686 { 687 maLockType = ucb::LockType_WRITE; 688 mbLockTypeSet = true; 689 } 690 break; 691 } 692 case WebDAVName_propstat: 693 { 694 // propstat end, check status 695 if(maStatus.getLength()) 696 { 697 static ::rtl::OUString aStrStatusOkay(::rtl::OUString::createFromAscii("HTTP/1.1 200 OK")); 698 699 if(maStatus.equals(aStrStatusOkay)) 700 { 701 if(isCollectingProperties()) 702 { 703 if(maPropStatProperties.size()) 704 { 705 // append to maResponseProperties if okay 706 maResponseProperties.insert(maResponseProperties.end(), maPropStatProperties.begin(), maPropStatProperties.end()); 707 } 708 } 709 else 710 { 711 if(maPropStatNames.size()) 712 { 713 // when collecting properties append to 714 maResponseNames.insert(maResponseNames.end(), maPropStatNames.begin(), maPropStatNames.end()); 715 } 716 } 717 } 718 } 719 break; 720 } 721 case WebDAVName_response: 722 { 723 // respose end 724 if(maHref.getLength()) 725 { 726 if(isCollectingProperties()) 727 { 728 // create DAVResource when we have content 729 if(maResponseProperties.size()) 730 { 731 http_dav_ucp::DAVResource aDAVResource; 732 733 aDAVResource.uri = maHref; 734 aDAVResource.properties = maResponseProperties; 735 maResult_PropFind.push_back(aDAVResource); 736 } 737 } 738 else 739 { 740 // when collecting properties add them to result when there are some 741 if(maResponseNames.size()) 742 { 743 http_dav_ucp::DAVResourceInfo aDAVResourceInfo(maHref); 744 745 aDAVResourceInfo.properties = maResponseNames; 746 maResult_PropName.push_back(aDAVResourceInfo); 747 } 748 } 749 } 750 break; 751 } 752 } 753 break; 754 } 755 case WebDAVNamespace_ucb_openoffice_org_dav_props: 756 { 757 break; 758 } 759 } 760 } 761 762 // destroy last context (pop) 763 pop_context(); 764 } 765 } 766 767 void SAL_CALL WebDAVResponseParser::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException) 768 { 769 // collect whitespace over evtl. several calls in mpContext 770 OSL_ENSURE(mpContext, "Parser characters without content (!)"); 771 const sal_Int32 nLen(aChars.getLength()); 772 773 if(mpContext && nLen) 774 { 775 // remove leading/trailing blanks and CRLF 776 const ::rtl::OUString aTrimmedChars(aChars.trim()); 777 778 if(aTrimmedChars.getLength()) 779 { 780 ::rtl::OUString aNew(mpContext->getWhiteSpace()); 781 782 if(aNew.getLength()) 783 { 784 // add one char when appending (see html1.1 spec) 785 aNew += ::rtl::OUString(sal_Unicode(' ')); 786 } 787 788 aNew += aTrimmedChars; 789 mpContext->setWhiteSpace(aNew); 790 } 791 } 792 } 793 794 void SAL_CALL WebDAVResponseParser::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ ) throw (xml::sax::SAXException, uno::RuntimeException) 795 { 796 } 797 798 void SAL_CALL WebDAVResponseParser::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) throw (xml::sax::SAXException, uno::RuntimeException) 799 { 800 } 801 802 void SAL_CALL WebDAVResponseParser::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) throw (xml::sax::SAXException, uno::RuntimeException) 803 { 804 } 805 } // end of anonymous namespace 806 807 ////////////////////////////////////////////////////////////////////////////// 808 // wrapper for various calls to the parser 809 810 namespace 811 { 812 void parseWebDAVPropNameResponse( 813 const uno::Reference< io::XInputStream >& xInputStream, 814 std::vector< http_dav_ucp::DAVResource >& rPropFind, 815 std::vector< http_dav_ucp::DAVResourceInfo >& rPropName, 816 WebDAVResponseParserMode eWebDAVResponseParserMode) 817 { 818 if(xInputStream.is()) 819 { 820 try 821 { 822 // prepare ParserInputSrouce 823 xml::sax::InputSource myInputSource; 824 myInputSource.aInputStream = xInputStream; 825 826 // get parser 827 uno::Reference< xml::sax::XParser > xParser( 828 comphelper::getProcessServiceFactory()->createInstance( 829 rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), 830 uno::UNO_QUERY_THROW ); 831 832 // create parser; connect parser and filter 833 WebDAVResponseParser* pWebDAVResponseParser = new WebDAVResponseParser(eWebDAVResponseParserMode); 834 uno::Reference< xml::sax::XDocumentHandler > xWebDAVHdl(pWebDAVResponseParser); 835 xParser->setDocumentHandler(xWebDAVHdl); 836 837 // finally, parse the stream 838 xParser->parseStream(myInputSource); 839 840 // get result 841 switch(eWebDAVResponseParserMode) 842 { 843 case WebDAVResponseParserMode_PropFind: 844 { 845 rPropFind = pWebDAVResponseParser->getResult_PropFind(); 846 break; 847 } 848 case WebDAVResponseParserMode_PropName: 849 { 850 rPropName = pWebDAVResponseParser->getResult_PropName(); 851 break; 852 } 853 } 854 } 855 catch(uno::Exception&) 856 { 857 OSL_ENSURE(false, "WebDAV Parse error (!)"); 858 } 859 } 860 } 861 } // end of anonymous namespace 862 863 ////////////////////////////////////////////////////////////////////////////// 864 // helper to parse a XML WebDAV response 865 866 namespace http_dav_ucp 867 { 868 std::vector< DAVResource > parseWebDAVPropFindResponse(const uno::Reference< io::XInputStream >& xInputStream) 869 { 870 std::vector< DAVResource > aRetval; 871 std::vector< DAVResourceInfo > aFoo; 872 873 parseWebDAVPropNameResponse(xInputStream, aRetval, aFoo, WebDAVResponseParserMode_PropFind); 874 return aRetval; 875 } 876 877 std::vector< DAVResourceInfo > parseWebDAVPropNameResponse(const uno::Reference< io::XInputStream >& xInputStream) 878 { 879 std::vector< DAVResource > aFoo; 880 std::vector< DAVResourceInfo > aRetval; 881 882 parseWebDAVPropNameResponse(xInputStream, aFoo, aRetval, WebDAVResponseParserMode_PropName); 883 return aRetval; 884 } 885 } // namespace http_dav_ucp 886 887 ////////////////////////////////////////////////////////////////////////////// 888 // eof 889