1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
22 #include "DAVProperties.hxx"
23 #include "UCBDeadPropertyValue.hxx"
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/sequence.hxx>
28 #include <cppuhelper/implbase.hxx>
29 #include <com/sun/star/xml/sax/Parser.hpp>
30 #include <com/sun/star/xml/sax/InputSource.hpp>
31 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
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 <com/sun/star/ucb/Lock.hpp>
37 #include <unordered_map>
38 #include <rtl/ref.hxx>
39 #include <rtl/uri.hxx>
40 #include <sal/log.hxx>
41 #include <o3tl/string_view.hxx>
43 using namespace com::sun::star
;
44 using namespace http_dav_ucp
;
47 // WebDAVNamespace enum and StringToEnum converter
52 WebDAVNamespace_unknown
= 0,
54 WebDAVNamespace_ucb_openoffice_org_dav_props
,
59 WebDAVNamespace
StrToWebDAVNamespace(::std::u16string_view rStr
)
63 return WebDAVNamespace_DAV
;
65 else if (rStr
== u
"http://ucb.openoffice.org/dav/props/")
67 return WebDAVNamespace_ucb_openoffice_org_dav_props
;
70 return WebDAVNamespace_unknown
;
72 } // end of anonymous namespace
74 // WebDAVName enum and StringToEnum converter using unordered_map
79 WebDAVName_unknown
= 0,
80 WebDAVName_activelock
,
81 WebDAVName_lockdiscovery
,
82 WebDAVName_multistatus
,
87 WebDAVName_resourcetype
,
88 WebDAVName_collection
,
89 WebDAVName_getcontenttype
,
90 WebDAVName_supportedlock
,
102 WebDAVName_getlastmodified
,
103 WebDAVName_creationdate
,
104 WebDAVName_getcontentlength
,
112 WebDAVName
StrToWebDAVName(const OUString
& rStr
)
114 typedef std::unordered_map
< OUString
, WebDAVName
> WebDAVNameMapper
;
115 typedef std::pair
< OUString
, WebDAVName
> WebDAVNameValueType
;
116 static WebDAVNameMapper aWebDAVNameMapperList
;
118 if(aWebDAVNameMapperList
.empty())
120 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"activelock"_ustr
, WebDAVName_activelock
));
121 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"lockdiscovery"_ustr
, WebDAVName_lockdiscovery
));
122 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"multistatus"_ustr
, WebDAVName_multistatus
));
123 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"response"_ustr
, WebDAVName_response
));
124 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"href"_ustr
, WebDAVName_href
));
125 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"propstat"_ustr
, WebDAVName_propstat
));
126 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"prop"_ustr
, WebDAVName_prop
));
127 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"resourcetype"_ustr
, WebDAVName_resourcetype
));
128 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"collection"_ustr
, WebDAVName_collection
));
129 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"getcontenttype"_ustr
, WebDAVName_getcontenttype
));
130 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"supportedlock"_ustr
, WebDAVName_supportedlock
));
131 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"lockentry"_ustr
, WebDAVName_lockentry
));
132 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"lockscope"_ustr
, WebDAVName_lockscope
));
133 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"depth"_ustr
, WebDAVName_depth
));
134 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"locktoken"_ustr
, WebDAVName_locktoken
));
135 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"exclusive"_ustr
, WebDAVName_exclusive
));
136 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"locktype"_ustr
, WebDAVName_locktype
));
137 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"owner"_ustr
, WebDAVName_owner
));
138 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"timeout"_ustr
, WebDAVName_timeout
));
139 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"write"_ustr
, WebDAVName_write
));
140 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"shared"_ustr
, WebDAVName_shared
));
141 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"status"_ustr
, WebDAVName_status
));
142 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"getlastmodified"_ustr
, WebDAVName_getlastmodified
));
143 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"creationdate"_ustr
, WebDAVName_creationdate
));
144 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"getcontentlength"_ustr
, WebDAVName_getcontentlength
));
145 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"type"_ustr
, WebDAVName_type
));
146 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"value"_ustr
, WebDAVName_value
));
147 aWebDAVNameMapperList
.insert(WebDAVNameValueType(u
"ucbprop"_ustr
, WebDAVName_ucbprop
));
150 const WebDAVNameMapper::const_iterator
aResult(aWebDAVNameMapperList
.find(rStr
));
152 if(aResult
== aWebDAVNameMapperList
.end())
154 return WebDAVName_unknown
;
158 return aResult
->second
;
161 } // end of anonymous namespace
164 // WebDAVContext, holding information for each start/endElement pair
168 typedef std::map
< OUString
, OUString
> NamespaceMap
;
173 WebDAVContext
* mpParent
;
174 NamespaceMap maNamespaceMap
;
175 OUString maWhiteSpace
;
177 OUString maNamespace
;
180 WebDAVNamespace maWebDAVNamespace
;
181 WebDAVName maWebDAVName
;
184 void parseForNamespaceTokens(const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
);
185 OUString
mapNamespaceToken(const OUString
& rToken
) const;
186 void splitName(const OUString
& rSource
);
189 WebDAVContext(WebDAVContext
* pParent
, const OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
);
191 WebDAVContext
* getParent() const { return mpParent
; }
192 OUString
& getWhiteSpace() { return maWhiteSpace
; }
193 void setWhiteSpace(const OUString
& rNew
) { maWhiteSpace
= rNew
; }
195 const OUString
& getNamespace() const { return maNamespace
; }
196 const OUString
& getName() const { return maName
; }
197 const WebDAVNamespace
& getWebDAVNamespace() const { return maWebDAVNamespace
; }
198 const WebDAVName
& getWebDAVName() const { return maWebDAVName
; }
201 void WebDAVContext::parseForNamespaceTokens(const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
)
203 const sal_Int16
nAttributes(xAttribs
->getLength());
205 for(sal_Int16
a(0); a
< nAttributes
; a
++)
207 const OUString
aName(xAttribs
->getNameByIndex(a
));
208 const sal_Int32
nLen(aName
.getLength());
212 if(aName
.startsWith("xmlns"))
214 const sal_Int32
nIndex(aName
.indexOf(':', 0));
216 if(-1 != nIndex
&& nIndex
+ 1 < nLen
)
218 const OUString
aToken(aName
.copy(nIndex
+ 1));
220 maNamespaceMap
.emplace(aToken
, xAttribs
->getValueByIndex(a
));
227 OUString
WebDAVContext::mapNamespaceToken(const OUString
& rToken
) const
229 NamespaceMap::const_iterator iter
= maNamespaceMap
.find(rToken
);
231 if(maNamespaceMap
.end() == iter
)
235 return getParent()->mapNamespaceToken(rToken
);
244 return (*iter
).second
;
248 void WebDAVContext::splitName(const OUString
& rSource
)
250 const sal_Int32
nLen(rSource
.getLength());
256 const sal_Int32
nIndex(rSource
.indexOf(':', 0));
258 if(nIndex
> 0 && ((nIndex
+ 1) < nLen
))
260 maNamespace
= mapNamespaceToken(rSource
.copy(0, nIndex
));
261 maName
= rSource
.copy(nIndex
+ 1);
266 WebDAVContext::WebDAVContext(WebDAVContext
* pParent
, const OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
)
272 maWebDAVNamespace(WebDAVNamespace_unknown
),
273 maWebDAVName(WebDAVName_unknown
)
275 const sal_Int16
nAttributes(xAttribs
->getLength());
279 // parse evtl. namespace entries
280 parseForNamespaceTokens(xAttribs
);
283 // split name to namespace and name
286 // evaluate enums for namespace and name
287 maWebDAVNamespace
= StrToWebDAVNamespace(maNamespace
);
288 maWebDAVName
= StrToWebDAVName(maName
);
290 } // end of anonymous namespace
293 // the Xml parser itself
297 enum WebDAVResponseParserMode
299 WebDAVResponseParserMode_PropFind
= 0,
300 WebDAVResponseParserMode_PropName
,
301 WebDAVResponseParserMode_Lock
304 class WebDAVResponseParser
: public cppu::WeakImplHelper
< css::xml::sax::XDocumentHandler
>
307 std::vector
< ucb::Lock
> maResult_Lock
;
308 std::vector
< http_dav_ucp::DAVResource
> maResult_PropFind
;
309 std::vector
< http_dav_ucp::DAVResourceInfo
> maResult_PropName
;
311 WebDAVContext
* mpContext
;
316 std::vector
< http_dav_ucp::DAVPropertyValue
> maResponseProperties
;
317 std::vector
< http_dav_ucp::DAVPropertyValue
> maPropStatProperties
;
318 std::vector
< OUString
> maResponseNames
;
319 std::vector
< OUString
> maPropStatNames
;
320 uno::Sequence
< ucb::LockEntry
> maLockEntries
;
321 ucb::LockScope maLockScope
;
322 ucb::LockType maLockType
;
324 WebDAVResponseParserMode meWebDAVResponseParserMode
;
326 bool mbResourceTypeCollection
: 1;
327 bool mbLockScopeSet
: 1;
328 bool mbLockTypeSet
: 1;
331 bool whitespaceIsAvailable() const
333 return mpContext
&& mpContext
->getWhiteSpace().getLength();
335 bool hasParent(WebDAVName aWebDAVName
) const
337 return mpContext
&& mpContext
->getParent() && aWebDAVName
== mpContext
->getParent()->getWebDAVName();
339 bool propertyIsReady() const
341 return hasParent(WebDAVName_prop
) && whitespaceIsAvailable();
343 bool isCollectingProperties() const
345 return WebDAVResponseParserMode_PropFind
== meWebDAVResponseParserMode
;
347 bool isCollectingPropNames() const
349 return WebDAVResponseParserMode_PropName
== meWebDAVResponseParserMode
;
351 bool collectThisPropertyAsName() const
353 return isCollectingPropNames() && hasParent(WebDAVName_prop
);
359 WebDAVContext
* pTemp
= mpContext
;
360 mpContext
= mpContext
->getParent();
365 SAL_WARN( "ucb.ucp.webdav", "Parser context pop without context (!)");
370 explicit WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode
);
371 virtual ~WebDAVResponseParser() override
;
373 // Methods XDocumentHandler
374 virtual void SAL_CALL
startDocument( ) override
;
375 virtual void SAL_CALL
endDocument( ) override
;
376 virtual void SAL_CALL
startElement( const OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
) override
;
377 virtual void SAL_CALL
endElement( const OUString
& aName
) override
;
378 virtual void SAL_CALL
characters( const OUString
& aChars
) override
;
379 virtual void SAL_CALL
ignorableWhitespace( const OUString
& aWhitespaces
) override
;
380 virtual void SAL_CALL
processingInstruction( const OUString
& aTarget
, const OUString
& aData
) override
;
381 virtual void SAL_CALL
setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& xLocator
) override
;
383 const std::vector
< ucb::Lock
>& getResult_Lock() const { return maResult_Lock
; }
384 const std::vector
< http_dav_ucp::DAVResource
>& getResult_PropFind() const { return maResult_PropFind
; }
385 const std::vector
< http_dav_ucp::DAVResourceInfo
>& getResult_PropName() const { return maResult_PropName
; }
388 WebDAVResponseParser::WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode
)
389 : maResult_PropFind(),
394 maResponseProperties(),
395 maPropStatProperties(),
399 maLockScope(ucb::LockScope_EXCLUSIVE
),
400 maLockType(ucb::LockType_WRITE
),
401 meWebDAVResponseParserMode(eWebDAVResponseParserMode
),
402 mbResourceTypeCollection(false),
403 mbLockScopeSet(false),
408 WebDAVResponseParser::~WebDAVResponseParser()
410 SAL_WARN_IF(mpContext
, "ucb.ucp.webdav", "Parser destructed with existing content (!)");
417 void SAL_CALL
WebDAVResponseParser::startDocument( )
419 SAL_WARN_IF(mpContext
, "ucb.ucp.webdav", "Parser start with existing content (!)");
422 void SAL_CALL
WebDAVResponseParser::endDocument( )
424 SAL_WARN_IF(mpContext
, "ucb.ucp.webdav", "Parser end with existing content (!)");
427 void SAL_CALL
WebDAVResponseParser::startElement( const OUString
& aName
, const uno::Reference
< xml::sax::XAttributeList
>& xAttribs
)
429 const sal_Int32
nLen(aName
.getLength());
433 // create new context (push)
434 mpContext
= new WebDAVContext(mpContext
, aName
, xAttribs
);
436 if(collectThisPropertyAsName())
438 // When collecting property names and parent is prop there is no need
439 // to handle the content of this property deeper (evtl. preparations)
443 switch(mpContext
->getWebDAVNamespace())
445 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled
449 case WebDAVNamespace_DAV
:
451 switch(mpContext
->getWebDAVName())
453 default: // WebDAVName_unknown, WebDAVName_last or unhandled
457 case WebDAVName_propstat
:
460 if(isCollectingProperties())
462 // reset maPropStatProperties
463 maPropStatProperties
.clear();
467 // when collecting properties reset maPropStatNames
468 maPropStatNames
.clear();
472 case WebDAVName_response
:
474 // response start, reset Href and status and maResponseProperties
478 if(isCollectingProperties())
480 // reset maResponseProperties
481 maResponseProperties
.clear();
485 // reset maResponseNames when collecting properties
486 maResponseNames
.clear();
490 case WebDAVName_resourcetype
:
492 // resourcetype start, reset collection
493 mbResourceTypeCollection
= false;
496 case WebDAVName_supportedlock
:
498 // supportedlock start, reset maLockEntries
499 maLockEntries
.realloc(0);
502 case WebDAVName_lockentry
:
504 // lockentry start, reset maLockEntries
505 mbLockScopeSet
= false;
506 mbLockTypeSet
= false;
509 case WebDAVName_activelock
:
511 maLock
= ucb::Lock();
517 case WebDAVNamespace_ucb_openoffice_org_dav_props
:
526 OUString
MakePropertyName(WebDAVContext
const& rContext
)
529 OString
const name(OUStringToOString(rContext
.getName(), RTL_TEXTENCODING_UTF8
));
530 OString
const nameSpace(OUStringToOString(rContext
.getNamespace(), RTL_TEXTENCODING_UTF8
));
531 DAVProperties::createUCBPropName(nameSpace
.getStr(), name
.getStr(), ret
);
535 void SAL_CALL
WebDAVResponseParser::endElement( const OUString
& aName
)
537 const sal_Int32
nLen(aName
.getLength());
538 SAL_WARN_IF(!mpContext
, "ucb.ucp.webdav", "Parser EndElement without content (!)");
540 if(mpContext
&& nLen
)
542 if(collectThisPropertyAsName())
544 // name must be encoded as expected by createSerfPropName()
545 OUString
const name(MakePropertyName(*mpContext
));
546 maPropStatNames
.emplace_back(name
);
550 switch(mpContext
->getWebDAVNamespace())
552 default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled
556 case WebDAVNamespace_DAV
:
558 switch(mpContext
->getWebDAVName())
560 default: // WebDAVName_unknown, WebDAVName_last or unhandled
564 case WebDAVName_href
:
566 // href end, save it if we have whitespace
567 if(whitespaceIsAvailable())
569 // Sharepoint 2016 workaround: apparently
570 // the result is an IRI (RFC 3987 possibly?)
571 // so try to encode the non-ASCII chars
572 // without changing anything else
573 maHref
= ::rtl::Uri::encode(mpContext
->getWhiteSpace(),
574 rtl_UriCharClassUric
, rtl_UriEncodeKeepEscapes
,
575 RTL_TEXTENCODING_UTF8
);
579 case WebDAVName_status
:
581 // status end, save it if we have whitespace
582 if(whitespaceIsAvailable())
584 maStatus
= mpContext
->getWhiteSpace();
588 case WebDAVName_getlastmodified
:
590 // getlastmodified end, safe if content is correct
591 if(propertyIsReady())
593 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
595 aDAVPropertyValue
.Name
= "DAV:getlastmodified";
596 aDAVPropertyValue
.Value
<<= mpContext
->getWhiteSpace();
597 maPropStatProperties
.push_back(aDAVPropertyValue
);
601 case WebDAVName_creationdate
:
603 // creationdate end, safe if content is correct
604 if(propertyIsReady())
606 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
608 aDAVPropertyValue
.Name
= "DAV:creationdate";
609 aDAVPropertyValue
.Value
<<= mpContext
->getWhiteSpace();
610 maPropStatProperties
.push_back(aDAVPropertyValue
);
614 case WebDAVName_collection
:
616 // collection end, check and set
617 if(hasParent(WebDAVName_resourcetype
))
619 mbResourceTypeCollection
= true;
623 case WebDAVName_resourcetype
:
625 // resourcetype end, check for collection
626 if(hasParent(WebDAVName_prop
))
628 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
630 aDAVPropertyValue
.Name
= "DAV:resourcetype";
631 aDAVPropertyValue
.Value
<<= (mbResourceTypeCollection
? u
"collection"_ustr
: OUString());
632 maPropStatProperties
.push_back(aDAVPropertyValue
);
636 case WebDAVName_getcontentlength
:
638 // getcontentlength end, safe if content is correct
639 if(propertyIsReady())
641 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
643 aDAVPropertyValue
.Name
= "DAV:getcontentlength";
644 aDAVPropertyValue
.Value
<<= mpContext
->getWhiteSpace();
645 maPropStatProperties
.push_back(aDAVPropertyValue
);
649 case WebDAVName_getcontenttype
:
651 // getcontenttype end, safe if content is correct
652 if(propertyIsReady())
654 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
656 aDAVPropertyValue
.Name
= "DAV:getcontenttype";
657 aDAVPropertyValue
.Value
<<= mpContext
->getWhiteSpace();
658 maPropStatProperties
.push_back(aDAVPropertyValue
);
662 case WebDAVName_supportedlock
:
665 if(hasParent(WebDAVName_prop
) && maLockEntries
.hasElements())
667 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
669 aDAVPropertyValue
.Name
= "DAV:supportedlock";
670 aDAVPropertyValue
.Value
<<= maLockEntries
;
671 maPropStatProperties
.push_back(aDAVPropertyValue
);
675 case WebDAVName_lockentry
:
678 if(hasParent(WebDAVName_supportedlock
) && (mbLockScopeSet
&& mbLockTypeSet
))
680 const sal_Int32
nLength(maLockEntries
.getLength());
681 ucb::LockEntry aEntry
;
683 aEntry
.Scope
= maLockScope
;
684 aEntry
.Type
= maLockType
;
685 maLockEntries
.realloc(nLength
+ 1);
686 maLockEntries
.getArray()[nLength
] = aEntry
;
690 case WebDAVName_owner
:
692 maLock
.Owner
<<= mpContext
->getWhiteSpace();
695 case WebDAVName_timeout
:
697 const OUString
sTimeout(mpContext
->getWhiteSpace());
698 if (sTimeout
== "Infinite")
700 else if (sTimeout
.startsWith("Second-"))
701 maLock
.Timeout
= o3tl::toInt64(sTimeout
.subView(7));
704 case WebDAVName_locktoken
:
706 const OUString
sLockToken(maHref
);
707 SAL_WARN_IF(!sLockToken
.startsWith("opaquelocktoken:"), "ucb.ucp.webdav",
708 "Parser error: wrong 'locktoken' value.");
709 const sal_Int32
nLength(maLock
.LockTokens
.getLength());
710 maLock
.LockTokens
.realloc(nLength
+1);
711 maLock
.LockTokens
.getArray()[nLength
] = sLockToken
;
714 case WebDAVName_exclusive
:
716 // exclusive lockscope end
717 if(hasParent(WebDAVName_lockscope
))
719 maLockScope
= ucb::LockScope_EXCLUSIVE
;
720 mbLockScopeSet
= true;
724 case WebDAVName_shared
:
726 // shared lockscope end
727 if(hasParent(WebDAVName_lockscope
))
729 maLockScope
= ucb::LockScope_SHARED
;
730 mbLockScopeSet
= true;
734 case WebDAVName_write
:
736 // write locktype end
737 if(hasParent(WebDAVName_locktype
))
739 maLockType
= ucb::LockType_WRITE
;
740 mbLockTypeSet
= true;
744 case WebDAVName_depth
:
746 OUString
const chars(mpContext
->getWhiteSpace());
749 maLock
.Depth
= ucb::LockDepth_ZERO
;
751 else if (chars
== "1")
753 maLock
.Depth
= ucb::LockDepth_ONE
;
755 else if (chars
== "infinity")
757 maLock
.Depth
= ucb::LockDepth_INFINITY
;
761 case WebDAVName_activelock
:
763 maLock
.Type
= maLockType
;
764 maLock
.Scope
= maLockScope
;
765 maResult_Lock
.push_back(maLock
);
768 case WebDAVName_lockdiscovery
:
770 // lockdiscovery may be requested via PROPFIND,
771 // in addition to LOCK! so return it 2 ways
772 if (isCollectingProperties())
774 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
776 aDAVPropertyValue
.Name
= "DAV:lockdiscovery";
777 aDAVPropertyValue
.Value
<<= ::comphelper::containerToSequence(maResult_Lock
);
778 maPropStatProperties
.push_back(aDAVPropertyValue
);
782 case WebDAVName_propstat
:
784 // propstat end, check status
785 if(maStatus
.getLength())
787 if(maStatus
== "HTTP/1.1 200 OK")
789 if(isCollectingProperties())
791 if(!maPropStatProperties
.empty())
793 // append to maResponseProperties if okay
794 maResponseProperties
.insert(maResponseProperties
.end(), maPropStatProperties
.begin(), maPropStatProperties
.end());
799 if(!maPropStatNames
.empty())
801 // when collecting properties append to
802 maResponseNames
.insert(maResponseNames
.end(), maPropStatNames
.begin(), maPropStatNames
.end());
809 case WebDAVName_response
:
812 if(maHref
.getLength())
814 if(isCollectingProperties())
816 // create DAVResource when we have content
817 if(!maResponseProperties
.empty())
819 http_dav_ucp::DAVResource aDAVResource
;
821 aDAVResource
.uri
= maHref
;
822 aDAVResource
.properties
= maResponseProperties
;
823 maResult_PropFind
.push_back(aDAVResource
);
828 // when collecting properties add them to result when there are some
829 if(!maResponseNames
.empty())
831 http_dav_ucp::DAVResourceInfo aDAVResourceInfo
;
833 aDAVResourceInfo
.properties
= maResponseNames
;
834 maResult_PropName
.push_back(aDAVResourceInfo
);
843 case WebDAVNamespace_ucb_openoffice_org_dav_props
:
845 switch(mpContext
->getWebDAVName())
847 case WebDAVName_type
:
849 m_UCBType
= mpContext
->getWhiteSpace();
852 case WebDAVName_value
:
854 m_UCBValue
= mpContext
->getWhiteSpace();
857 case WebDAVName_ucbprop
:
859 if (!m_UCBType
.isEmpty()
860 && isCollectingProperties())
862 http_dav_ucp::DAVPropertyValue aDAVPropertyValue
;
863 aDAVPropertyValue
.Name
= MakePropertyName(*mpContext
->getParent());
864 if (UCBDeadPropertyValue::createFromXML(m_UCBType
, m_UCBValue
, aDAVPropertyValue
.Value
))
866 maPropStatProperties
.push_back(aDAVPropertyValue
);
870 SAL_INFO("ucb.ucp.webdav.curl", "cannot parse property value");
885 // destroy last context (pop)
890 void SAL_CALL
WebDAVResponseParser::characters( const OUString
& aChars
)
892 // collect whitespace over evtl. several calls in mpContext
893 SAL_WARN_IF(!mpContext
, "ucb.ucp.webdav", "Parser characters without content (!)");
894 const sal_Int32
nLen(aChars
.getLength());
896 if(mpContext
&& nLen
)
898 // remove leading/trailing blanks and CRLF
899 const OUString
aTrimmedChars(aChars
.trim());
901 if(aTrimmedChars
.getLength())
903 OUString
aNew(mpContext
->getWhiteSpace());
907 // add one char when appending (see html1.1 spec)
911 aNew
+= aTrimmedChars
;
912 mpContext
->setWhiteSpace(aNew
);
917 void SAL_CALL
WebDAVResponseParser::ignorableWhitespace( const OUString
& /*aWhitespaces*/ )
921 void SAL_CALL
WebDAVResponseParser::processingInstruction( const OUString
& /*aTarget*/, const OUString
& /*aData*/ )
925 void SAL_CALL
WebDAVResponseParser::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& /*xLocator*/ )
928 } // end of anonymous namespace
931 // wrapper for various calls to the parser
936 void parseWebDAVResponse(
937 const uno::Reference
< io::XInputStream
>& xInputStream
,
938 std::vector
< T
>& rResult
,
939 WebDAVResponseParserMode eWebDAVResponseParserMode
,
940 std::vector
<T
> const & (WebDAVResponseParser::* fn
)() const)
942 if(xInputStream
.is())
946 // prepare ParserInputSource
947 xml::sax::InputSource myInputSource
;
948 myInputSource
.aInputStream
= xInputStream
;
951 uno::Reference
< xml::sax::XParser
> xParser
= xml::sax::Parser::create(
952 comphelper::getProcessComponentContext() );
954 // create parser; connect parser and filter
955 rtl::Reference
<WebDAVResponseParser
> const pWebDAVResponseParser(
956 new WebDAVResponseParser(eWebDAVResponseParserMode
));
957 uno::Reference
< xml::sax::XDocumentHandler
> xWebDAVHdl(pWebDAVResponseParser
);
958 xParser
->setDocumentHandler(xWebDAVHdl
);
960 // finally, parse the stream
961 xParser
->parseStream(myInputSource
);
964 rResult
= (pWebDAVResponseParser
.get()->*fn
)();
966 catch(uno::Exception
&)
968 SAL_WARN("ucb.ucp.webdav", "WebDAV Parse error (!)");
972 } // end of anonymous namespace
975 // helper to parse a XML WebDAV response
977 namespace http_dav_ucp
979 std::vector
< ucb::Lock
> parseWebDAVLockResponse(const uno::Reference
< io::XInputStream
>& xInputStream
)
981 std::vector
< ucb::Lock
> aResult
;
982 parseWebDAVResponse
< ucb::Lock
>(xInputStream
, aResult
, WebDAVResponseParserMode_Lock
, &WebDAVResponseParser::getResult_Lock
);
986 std::vector
< DAVResource
> parseWebDAVPropFindResponse(const uno::Reference
< io::XInputStream
>& xInputStream
)
988 std::vector
< DAVResource
> aResult
;
989 parseWebDAVResponse
< DAVResource
>(xInputStream
, aResult
, WebDAVResponseParserMode_PropFind
, &WebDAVResponseParser::getResult_PropFind
);
993 std::vector
< DAVResourceInfo
> parseWebDAVPropNameResponse(const uno::Reference
< io::XInputStream
>& xInputStream
)
995 std::vector
< DAVResourceInfo
> aResult
;
996 parseWebDAVResponse
< DAVResourceInfo
>(xInputStream
, aResult
, WebDAVResponseParserMode_PropName
, &WebDAVResponseParser::getResult_PropName
);
999 } // namespace http_dav_ucp
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */