Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / webdav / webdavresponseparser.cxx
blobffa4881079050f9dce5ea35b912112f66b5da978
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <webdavresponseparser.hxx>
21 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
22 #include <cppuhelper/implbase2.hxx>
23 #include <com/sun/star/xml/sax/XParser.hpp>
24 #include <com/sun/star/xml/sax/InputSource.hpp>
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/seqstream.hxx>
27 #include <com/sun/star/ucb/LockEntry.hpp>
28 #include <com/sun/star/ucb/LockScope.hpp>
29 #include <com/sun/star/ucb/LockType.hpp>
30 #include <map>
31 #include <hash_map>
33 //////////////////////////////////////////////////////////////////////////////
35 using namespace com::sun::star;
37 //////////////////////////////////////////////////////////////////////////////
38 // WebDAVNamespace enum and StringToEnum converter
40 namespace
42 enum WebDAVNamespace
44 WebDAVNamespace_unknown = 0,
45 WebDAVNamespace_DAV,
46 WebDAVNamespace_ucb_openoffice_org_dav_props,
48 WebDAVNamespace_last
51 WebDAVNamespace StrToWebDAVNamespace(const rtl::OUString& rStr)
53 static ::rtl::OUString aStrDAV(::rtl::OUString::createFromAscii("DAV:"));
54 static ::rtl::OUString aStrUcbOpenofficeOrgDAVProps(::rtl::OUString::createFromAscii("http://ucb.openoffice.org/dav/props/"));
56 if(rStr.equals(aStrDAV))
58 return WebDAVNamespace_DAV;
60 else if(rStr.equals(aStrUcbOpenofficeOrgDAVProps))
62 return WebDAVNamespace_ucb_openoffice_org_dav_props;
65 return WebDAVNamespace_unknown;
67 } // end of anonymous namespace
69 //////////////////////////////////////////////////////////////////////////////
70 // WebDAVName enum and StringToEnum converter using hash_map
72 namespace
74 enum WebDAVName
76 WebDAVName_unknown = 0,
77 WebDAVName_multistatus,
78 WebDAVName_response,
79 WebDAVName_href,
80 WebDAVName_propstat,
81 WebDAVName_prop,
82 WebDAVName_resourcetype,
83 WebDAVName_collection,
84 WebDAVName_getcontenttype,
85 WebDAVName_supportedlock,
86 WebDAVName_lockentry,
87 WebDAVName_lockscope,
88 WebDAVName_exclusive,
89 WebDAVName_locktype,
90 WebDAVName_write,
91 WebDAVName_shared,
92 WebDAVName_status,
93 WebDAVName_getlastmodified,
94 WebDAVName_creationdate,
95 WebDAVName_getcontentlength,
97 WebDAVName_last
100 WebDAVName StrToWebDAVName(const rtl::OUString& rStr)
102 typedef std::hash_map< rtl::OUString, WebDAVName, rtl::OUStringHash > WebDAVNameMapper;
103 typedef std::pair< rtl::OUString, WebDAVName > WebDAVNameValueType;
104 static WebDAVNameMapper aWebDAVNameMapperList;
106 if(aWebDAVNameMapperList.empty())
108 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("multistatus"), WebDAVName_multistatus));
109 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("response"), WebDAVName_response));
110 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("href"), WebDAVName_href));
111 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("propstat"), WebDAVName_propstat));
112 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("prop"), WebDAVName_prop));
113 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("resourcetype"), WebDAVName_resourcetype));
114 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("collection"), WebDAVName_collection));
115 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontenttype"), WebDAVName_getcontenttype));
116 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("supportedlock"), WebDAVName_supportedlock));
117 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockentry"), WebDAVName_lockentry));
118 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockscope"), WebDAVName_lockscope));
119 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("exclusive"), WebDAVName_exclusive));
120 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("locktype"), WebDAVName_locktype));
121 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("write"), WebDAVName_write));
122 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("shared"), WebDAVName_shared));
123 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("status"), WebDAVName_status));
124 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getlastmodified"), WebDAVName_getlastmodified));
125 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("creationdate"), WebDAVName_creationdate));
126 aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontentlength"), WebDAVName_getcontentlength));
129 const WebDAVNameMapper::const_iterator aResult(aWebDAVNameMapperList.find(rStr));
131 if(aResult == aWebDAVNameMapperList.end())
133 return WebDAVName_unknown;
135 else
137 return aResult->second;
140 } // end of anonymous namespace
142 //////////////////////////////////////////////////////////////////////////////
143 // WebDAVContext, holding information for each start/endElement pair
145 namespace
147 typedef std::map< ::rtl::OUString, ::rtl::OUString > NamespaceMap;
148 typedef std::pair< const ::rtl::OUString, ::rtl::OUString > NamespaceValueType;
150 class WebDAVContext
152 private:
153 WebDAVContext* mpParent;
154 NamespaceMap maNamespaceMap;
155 ::rtl::OUString maWhiteSpace;
157 ::rtl::OUString maNamespace;
158 ::rtl::OUString maName;
160 WebDAVNamespace maWebDAVNamespace;
161 WebDAVName maWebDAVName;
163 // local helpers
164 void parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs);
165 ::rtl::OUString mapNamespaceToken(const ::rtl::OUString& rToken) const;
166 void splitName(const ::rtl::OUString& rSource);
168 public:
169 WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs);
170 ~WebDAVContext();
172 WebDAVContext* getParent() const { return mpParent; }
173 ::rtl::OUString& getWhiteSpace() { return maWhiteSpace; }
174 void setWhiteSpace(const ::rtl::OUString& rNew) { maWhiteSpace = rNew; }
176 const ::rtl::OUString& getNamespace() const { return maNamespace; }
177 const ::rtl::OUString& getName() const { return maName; }
178 const WebDAVNamespace getWebDAVNamespace() const { return maWebDAVNamespace; }
179 const WebDAVName getWebDAVName() const { return maWebDAVName; }
182 void WebDAVContext::parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs)
184 const sal_Int16 nAttributes(xAttribs->getLength());
185 static ::rtl::OUString aStrXmlns(::rtl::OUString::createFromAscii("xmlns"));
187 for(sal_Int16 a(0); a < nAttributes; a++)
189 const ::rtl::OUString aName(xAttribs->getNameByIndex(a));
190 const sal_Int32 nLen(aName.getLength());
192 if(nLen)
194 if(aName.match(aStrXmlns, 0))
196 const sal_Int32 nIndex(aName.indexOf(sal_Unicode(':'), 0));
198 if(-1 != nIndex && nIndex + 1 < nLen)
200 const ::rtl::OUString aToken(aName.copy(nIndex + 1));
202 maNamespaceMap.insert(NamespaceValueType(aToken, xAttribs->getValueByIndex(a)));
209 ::rtl::OUString WebDAVContext::mapNamespaceToken(const ::rtl::OUString& rToken) const
211 NamespaceMap::const_iterator iter = maNamespaceMap.find(rToken);
213 if(maNamespaceMap.end() == iter)
215 if(getParent())
217 return getParent()->mapNamespaceToken(rToken);
219 else
221 return rToken;
224 else
226 return (*iter).second;
230 void WebDAVContext::splitName(const ::rtl::OUString& rSource)
232 const sal_Int32 nLen(rSource.getLength());
233 maNamespace = ::rtl::OUString();
234 maName = rSource;
236 if(nLen)
238 const sal_Int32 nIndex(rSource.indexOf(sal_Unicode(':'), 0));
240 if(-1 != nIndex && nIndex > 0 && nIndex + 1 < nLen)
242 maNamespace = mapNamespaceToken(rSource.copy(0, nIndex));
243 maName = rSource.copy(nIndex + 1);
248 WebDAVContext::WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs)
249 : mpParent(pParent),
250 maNamespaceMap(),
251 maWhiteSpace(),
252 maNamespace(),
253 maName(),
254 maWebDAVNamespace(WebDAVNamespace_unknown),
255 maWebDAVName(WebDAVName_unknown)
257 const sal_Int16 nAttributes(xAttribs->getLength());
259 if(nAttributes)
261 // parse evtl. namespace entries
262 parseForNamespaceTokens(xAttribs);
265 // split name to namespace and name
266 splitName(aName);
268 // evaluate enums for namespace and name
269 maWebDAVNamespace = StrToWebDAVNamespace(maNamespace);
270 maWebDAVName = StrToWebDAVName(maName);
273 WebDAVContext::~WebDAVContext()
276 } // end of anonymous namespace
278 //////////////////////////////////////////////////////////////////////////////
279 // the Xml parser itself
281 namespace
283 enum WebDAVResponseParserMode
285 WebDAVResponseParserMode_PropFind = 0,
286 WebDAVResponseParserMode_PropName
289 class WebDAVResponseParser : public cppu::WeakImplHelper1< com::sun::star::xml::sax::XDocumentHandler >
291 private:
292 std::vector< http_dav_ucp::DAVResource > maResult_PropFind;
293 std::vector< http_dav_ucp::DAVResourceInfo > maResult_PropName;
295 WebDAVContext* mpContext;
296 ::rtl::OUString maHref;
297 ::rtl::OUString maStatus;
298 std::vector< http_dav_ucp::DAVPropertyValue > maResponseProperties;
299 std::vector< http_dav_ucp::DAVPropertyValue > maPropStatProperties;
300 std::vector< ::rtl::OUString > maResponseNames;
301 std::vector< ::rtl::OUString > maPropStatNames;
302 uno::Sequence< ucb::LockEntry > maLockEntries;
303 ucb::LockScope maLockScope;
304 ucb::LockType maLockType;
305 WebDAVResponseParserMode meWebDAVResponseParserMode;
307 // bitfield
308 bool mbResourceTypeCollection : 1;
309 bool mbLockScopeSet : 1;
310 bool mbLockTypeSet : 1;
312 // local helpers
313 bool whitespaceIsAvailable() const
315 return mpContext && mpContext->getWhiteSpace().getLength();
317 bool hasParent(WebDAVName aWebDAVName) const
319 return mpContext && mpContext->getParent() && aWebDAVName == mpContext->getParent()->getWebDAVName();
321 bool propertyIsReady() const
323 return hasParent(WebDAVName_prop) && whitespaceIsAvailable();
325 bool isCollectingProperties() const
327 return WebDAVResponseParserMode_PropFind == meWebDAVResponseParserMode;
329 bool isCollectingPropNames() const
331 return WebDAVResponseParserMode_PropName == meWebDAVResponseParserMode;
333 bool collectThisPropertyAsName() const
335 return isCollectingPropNames() && hasParent(WebDAVName_prop);
337 void pop_context()
339 if(mpContext)
341 WebDAVContext* pTemp = mpContext;
342 mpContext = mpContext->getParent();
343 delete pTemp;
345 else
347 OSL_ENSURE(false, "Parser context pop without context (!)");
351 public:
352 WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode);
353 ~WebDAVResponseParser();
355 // Methods XDocumentHandler
356 virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException);
357 virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException);
358 virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException);
359 virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException);
360 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException);
361 virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException);
362 virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (xml::sax::SAXException, uno::RuntimeException);
363 virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException);
365 const std::vector< http_dav_ucp::DAVResource >& getResult_PropFind() const { return maResult_PropFind; }
366 const std::vector< http_dav_ucp::DAVResourceInfo >& getResult_PropName() const { return maResult_PropName; }
369 WebDAVResponseParser::WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode)
370 : maResult_PropFind(),
371 maResult_PropName(),
372 mpContext(0),
373 maHref(),
374 maStatus(),
375 maResponseProperties(),
376 maPropStatProperties(),
377 maResponseNames(),
378 maPropStatNames(),
379 maLockEntries(),
380 maLockScope(ucb::LockScope_EXCLUSIVE),
381 maLockType(ucb::LockType_WRITE),
382 meWebDAVResponseParserMode(eWebDAVResponseParserMode),
383 mbResourceTypeCollection(false),
384 mbLockScopeSet(false),
385 mbLockTypeSet(false)
389 WebDAVResponseParser::~WebDAVResponseParser()
391 OSL_ENSURE(!mpContext, "Parser destructed with existing content (!)");
392 while(mpContext)
394 pop_context();
398 void SAL_CALL WebDAVResponseParser::startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
400 OSL_ENSURE(!mpContext, "Parser start with existing content (!)");
403 void SAL_CALL WebDAVResponseParser::endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
405 OSL_ENSURE(!mpContext, "Parser end with existing content (!)");
408 void SAL_CALL WebDAVResponseParser::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException)
410 const sal_Int32 nLen(aName.getLength());
412 if(nLen)
414 // create new context (push)
415 mpContext = new WebDAVContext(mpContext, aName, xAttribs);
417 if(collectThisPropertyAsName())
419 // When collecting property names and parent is prop there is no need
420 // to handle the content of this property deeper (evtl. preparations)
422 else
424 switch(mpContext->getWebDAVNamespace())
426 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled
428 break;
430 case WebDAVNamespace_DAV:
432 switch(mpContext->getWebDAVName())
434 default: // WebDAVName_unknown, WebDAVName_last or unhandled
436 break;
438 case WebDAVName_propstat:
440 // propstat start
441 if(isCollectingProperties())
443 // reset maPropStatProperties
444 maPropStatProperties.clear();
446 else
448 // when collecting properties reset maPropStatNames
449 maPropStatNames.clear();
451 break;
453 case WebDAVName_response:
455 // response start, reset Href and status and maResponseProperties
456 maHref = maStatus = ::rtl::OUString();
458 if(isCollectingProperties())
460 // reset maResponseProperties
461 maResponseProperties.clear();
463 else
465 // reset maResponseNames when collecting properties
466 maResponseNames.clear();
468 break;
470 case WebDAVName_resourcetype:
472 // resourcetype start, reset collection
473 mbResourceTypeCollection = false;
474 break;
476 case WebDAVName_supportedlock:
478 // supportedlock start, reset maLockEntries
479 maLockEntries.realloc(0);
480 break;
482 case WebDAVName_lockentry:
484 // lockentry start, reset maLockEntries
485 mbLockScopeSet = false;
486 mbLockTypeSet = false;
487 break;
490 break;
492 case WebDAVNamespace_ucb_openoffice_org_dav_props:
494 break;
501 void SAL_CALL WebDAVResponseParser::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException)
503 const sal_Int32 nLen(aName.getLength());
504 OSL_ENSURE(mpContext, "Parser EndElement without content (!)");
506 if(mpContext && nLen)
508 if(collectThisPropertyAsName())
510 // When collecting property names and parent is prop, just append the prop name
511 // to the collection, no need to parse deeper
512 maPropStatNames.push_back(mpContext->getNamespace() + mpContext->getName());
514 else
516 switch(mpContext->getWebDAVNamespace())
518 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled
520 break;
522 case WebDAVNamespace_DAV:
524 switch(mpContext->getWebDAVName())
526 default: // WebDAVName_unknown, WebDAVName_last or unhandled
528 break;
530 case WebDAVName_href:
532 // href end, save it if we have whitespace
533 if(whitespaceIsAvailable())
535 maHref = mpContext->getWhiteSpace();
537 break;
539 case WebDAVName_status:
541 // status end, save it if we have whitespace
542 if(whitespaceIsAvailable())
544 maStatus = mpContext->getWhiteSpace();
546 break;
548 case WebDAVName_getlastmodified:
550 // getlastmodified end, safe if content is correct
551 if(propertyIsReady())
553 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getlastmodified"));
554 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
556 aDAVPropertyValue.Name = aStr;
557 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace();
558 maPropStatProperties.push_back(aDAVPropertyValue);
560 break;
562 case WebDAVName_creationdate:
564 // creationdate end, safe if content is correct
565 if(propertyIsReady())
567 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:creationdate"));
568 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
570 aDAVPropertyValue.Name = aStr;
571 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace();
572 maPropStatProperties.push_back(aDAVPropertyValue);
574 break;
576 case WebDAVName_collection:
578 // collection end, check and set
579 if(hasParent(WebDAVName_resourcetype))
581 mbResourceTypeCollection = true;
583 break;
585 case WebDAVName_resourcetype:
587 // resourcetype end, check for collection
588 if(hasParent(WebDAVName_prop))
590 static rtl::OUString aStrA(rtl::OUString::createFromAscii("DAV:resourcetype"));
591 static rtl::OUString aStrB(rtl::OUString::createFromAscii("collection"));
592 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
594 aDAVPropertyValue.Name = aStrA;
595 aDAVPropertyValue.Value <<= (mbResourceTypeCollection ? aStrB : rtl::OUString());
596 maPropStatProperties.push_back(aDAVPropertyValue);
598 break;
600 case WebDAVName_getcontentlength:
602 // getcontentlength end, safe if content is correct
603 if(propertyIsReady())
605 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontentlength"));
606 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
608 aDAVPropertyValue.Name = aStr;
609 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace();
610 maPropStatProperties.push_back(aDAVPropertyValue);
612 break;
614 case WebDAVName_getcontenttype:
616 // getcontenttype end, safe if content is correct
617 if(propertyIsReady())
619 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontenttype"));
620 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
622 aDAVPropertyValue.Name = aStr;
623 aDAVPropertyValue.Value <<= mpContext->getWhiteSpace();
624 maPropStatProperties.push_back(aDAVPropertyValue);
626 break;
628 case WebDAVName_supportedlock:
630 // supportedlock end
631 if(hasParent(WebDAVName_prop) && maLockEntries.hasElements())
633 static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:supportedlock"));
634 http_dav_ucp::DAVPropertyValue aDAVPropertyValue;
636 aDAVPropertyValue.Name = aStr;
637 aDAVPropertyValue.Value <<= maLockEntries;
638 maPropStatProperties.push_back(aDAVPropertyValue);
640 break;
642 case WebDAVName_lockentry:
644 // lockentry end
645 if(hasParent(WebDAVName_supportedlock) && (mbLockScopeSet && mbLockTypeSet))
647 const sal_Int32 nLength(maLockEntries.getLength());
648 ucb::LockEntry aEntry;
650 aEntry.Scope = maLockScope;
651 aEntry.Type = maLockType;
652 maLockEntries.realloc(nLength + 1);
653 maLockEntries[nLength] = aEntry;
655 break;
657 case WebDAVName_exclusive:
659 // exclusive lockscope end
660 if(hasParent(WebDAVName_lockscope))
662 maLockScope = ucb::LockScope_EXCLUSIVE;
663 mbLockScopeSet = true;
665 break;
667 case WebDAVName_shared:
669 // shared lockscope end
670 if(hasParent(WebDAVName_lockscope))
672 maLockScope = ucb::LockScope_SHARED;
673 mbLockScopeSet = true;
675 break;
677 case WebDAVName_write:
679 // write locktype end
680 if(hasParent(WebDAVName_locktype))
682 maLockType = ucb::LockType_WRITE;
683 mbLockTypeSet = true;
685 break;
687 case WebDAVName_propstat:
689 // propstat end, check status
690 if(maStatus.getLength())
692 static ::rtl::OUString aStrStatusOkay(::rtl::OUString::createFromAscii("HTTP/1.1 200 OK"));
694 if(maStatus.equals(aStrStatusOkay))
696 if(isCollectingProperties())
698 if(maPropStatProperties.size())
700 // append to maResponseProperties if okay
701 maResponseProperties.insert(maResponseProperties.end(), maPropStatProperties.begin(), maPropStatProperties.end());
704 else
706 if(maPropStatNames.size())
708 // when collecting properties append to
709 maResponseNames.insert(maResponseNames.end(), maPropStatNames.begin(), maPropStatNames.end());
714 break;
716 case WebDAVName_response:
718 // respose end
719 if(maHref.getLength())
721 if(isCollectingProperties())
723 // create DAVResource when we have content
724 if(maResponseProperties.size())
726 http_dav_ucp::DAVResource aDAVResource;
728 aDAVResource.uri = maHref;
729 aDAVResource.properties = maResponseProperties;
730 maResult_PropFind.push_back(aDAVResource);
733 else
735 // when collecting properties add them to result when there are some
736 if(maResponseNames.size())
738 http_dav_ucp::DAVResourceInfo aDAVResourceInfo(maHref);
740 aDAVResourceInfo.properties = maResponseNames;
741 maResult_PropName.push_back(aDAVResourceInfo);
745 break;
748 break;
750 case WebDAVNamespace_ucb_openoffice_org_dav_props:
752 break;
757 // destroy last context (pop)
758 pop_context();
762 void SAL_CALL WebDAVResponseParser::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
764 // collect whitespace over evtl. several calls in mpContext
765 OSL_ENSURE(mpContext, "Parser characters without content (!)");
766 const sal_Int32 nLen(aChars.getLength());
768 if(mpContext && nLen)
770 // remove leading/trailing blanks and CRLF
771 const ::rtl::OUString aTrimmedChars(aChars.trim());
773 if(aTrimmedChars.getLength())
775 ::rtl::OUString aNew(mpContext->getWhiteSpace());
777 if(aNew.getLength())
779 // add one char when appending (see html1.1 spec)
780 aNew += ::rtl::OUString(sal_Unicode(' '));
783 aNew += aTrimmedChars;
784 mpContext->setWhiteSpace(aNew);
789 void SAL_CALL WebDAVResponseParser::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ ) throw (xml::sax::SAXException, uno::RuntimeException)
793 void SAL_CALL WebDAVResponseParser::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) throw (xml::sax::SAXException, uno::RuntimeException)
797 void SAL_CALL WebDAVResponseParser::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) throw (xml::sax::SAXException, uno::RuntimeException)
800 } // end of anonymous namespace
802 //////////////////////////////////////////////////////////////////////////////
803 // wrapper for various calls to the parser
805 namespace
807 void parseWebDAVPropNameResponse(
808 const uno::Reference< io::XInputStream >& xInputStream,
809 std::vector< http_dav_ucp::DAVResource >& rPropFind,
810 std::vector< http_dav_ucp::DAVResourceInfo >& rPropName,
811 WebDAVResponseParserMode eWebDAVResponseParserMode)
813 if(xInputStream.is())
817 // prepare ParserInputSrouce
818 xml::sax::InputSource myInputSource;
819 myInputSource.aInputStream = xInputStream;
821 // get parser
822 uno::Reference< xml::sax::XParser > xParser(
823 comphelper::getProcessServiceFactory()->createInstance(
824 rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
825 uno::UNO_QUERY_THROW );
827 // create parser; connect parser and filter
828 WebDAVResponseParser* pWebDAVResponseParser = new WebDAVResponseParser(eWebDAVResponseParserMode);
829 uno::Reference< xml::sax::XDocumentHandler > xWebDAVHdl(pWebDAVResponseParser);
830 xParser->setDocumentHandler(xWebDAVHdl);
832 // finally, parse the stream
833 xParser->parseStream(myInputSource);
835 // get result
836 switch(eWebDAVResponseParserMode)
838 case WebDAVResponseParserMode_PropFind:
840 rPropFind = pWebDAVResponseParser->getResult_PropFind();
841 break;
843 case WebDAVResponseParserMode_PropName:
845 rPropName = pWebDAVResponseParser->getResult_PropName();
846 break;
850 catch(uno::Exception&)
852 OSL_ENSURE(false, "WebDAV Parse error (!)");
856 } // end of anonymous namespace
858 //////////////////////////////////////////////////////////////////////////////
859 // helper to parse a XML WebDAV response
861 namespace http_dav_ucp
863 std::vector< DAVResource > parseWebDAVPropFindResponse(const uno::Reference< io::XInputStream >& xInputStream)
865 std::vector< DAVResource > aRetval;
866 std::vector< DAVResourceInfo > aFoo;
868 parseWebDAVPropNameResponse(xInputStream, aRetval, aFoo, WebDAVResponseParserMode_PropFind);
869 return aRetval;
872 std::vector< DAVResourceInfo > parseWebDAVPropNameResponse(const uno::Reference< io::XInputStream >& xInputStream)
874 std::vector< DAVResource > aFoo;
875 std::vector< DAVResourceInfo > aRetval;
877 parseWebDAVPropNameResponse(xInputStream, aFoo, aRetval, WebDAVResponseParserMode_PropName);
878 return aRetval;
880 } // namespace http_dav_ucp
882 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */