diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-10-04 11:25:41 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-10-04 20:16:37 +0100 |
commit | 015b29b74aaf16f5bdf6a90f6e7d5c1d210fe281 (patch) | |
tree | 3fb0abccc28bb0e97213793ab3426e2d215651f2 /ucb/source/ucp/webdav/webdavresponseparser.cxx | |
parent | 03ded70913f957460f90608465e4d0a182879074 (diff) |
re-base on ALv2 code. Includes:
clarify Option->Language UI option
Patch contributed by Herbert Duerr
http://svn.apache.org/viewvc?view=revision&revision=1173991
cws mba34issues01: #i117712#: fix several resource errors introduced
by IAccessible2 implementation
Patch contributed by Mathias Bauer
http://svn.apache.org/viewvc?view=revision&revision=1173991
cws mba34issues01: #i117709#: add missing string resource
Patch contributed by Mathias Bauer
http://svn.apache.org/viewvc?view=revision&revision=1172348
cws mba34issues01: #i117716#: fix missing resources my removing unused code
Patch contributed by Mathias Bauer
http://svn.apache.org/viewvc?view=revision&revision=1172345
re-add Crystal, Tango, Oxygen icon theme listings.
correct method signature
Patch contributed by Jean-Louis 'Hans' Fuchs
http://svn.apache.org/viewvc?view=revision&revision=1306725
i#119063 - correct serf integration
Patch contributed by Oliver-Rainer Wittmann
http://svn.apache.org/viewvc?view=revision&revision=1300521
i#119036 - adapt serf integration
-- use transfer-encoding 'chunked' on HTTPS
-- switch transfer-encoding between 'chunked' and none on 413 HTTP status code
-- refactoring
-- improve user experience of certification dialog - only shown once
Patch contributed by Oliver-Rainer Wittmann
http://svn.apache.org/viewvc?view=revision&revision=1299727
118569: Use whole certification chain for verification.
Patch contributed by Andre Fischer
http://svn.apache.org/viewvc?view=revision&revision=1295493
serf integration: improve credential input handling
Patch contributed by Oliver-Rainer Wittmann
http://svn.apache.org/viewvc?view=revision&revision=1294557
warning-free ucb/source/ucp/webdav
Patch contributed by Pavel Janik
http://svn.apache.org/viewvc?view=revision&revision=1294086
some refactoring to PROPPATCH and PROPFIND requests
Patch contributed by Oliver-Rainer Wittmann
http://svn.apache.org/viewvc?view=revision&revision=1293281
i#118569: Replace neon with serf
Patch contributed by Oliver-Rainer Wittmann
http://svn.apache.org/viewvc?view=revision&revision=1292832
http://svn.apache.org/viewvc?view=revision&revision=1292794
remove OS/2 conditionals for now.
re-enable webdav unit tests.
Diffstat (limited to 'ucb/source/ucp/webdav/webdavresponseparser.cxx')
-rw-r--r-- | ucb/source/ucp/webdav/webdavresponseparser.cxx | 888 |
1 files changed, 888 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav/webdavresponseparser.cxx b/ucb/source/ucp/webdav/webdavresponseparser.cxx new file mode 100644 index 000000000000..cc28ef1039da --- /dev/null +++ b/ucb/source/ucp/webdav/webdavresponseparser.cxx @@ -0,0 +1,888 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" + +#include <webdavresponseparser.hxx> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/seqstream.hxx> +#include <com/sun/star/ucb/LockEntry.hpp> +#include <com/sun/star/ucb/LockScope.hpp> +#include <com/sun/star/ucb/LockType.hpp> +#include <map> +#include <hash_map> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// +// WebDAVNamespace enum and StringToEnum converter + +namespace +{ + enum WebDAVNamespace + { + WebDAVNamespace_unknown = 0, + WebDAVNamespace_DAV, + WebDAVNamespace_ucb_openoffice_org_dav_props, + + WebDAVNamespace_last + }; + + WebDAVNamespace StrToWebDAVNamespace(const rtl::OUString& rStr) + { + static ::rtl::OUString aStrDAV(::rtl::OUString::createFromAscii("DAV:")); + static ::rtl::OUString aStrUcbOpenofficeOrgDAVProps(::rtl::OUString::createFromAscii("http://ucb.openoffice.org/dav/props/")); + + if(rStr.equals(aStrDAV)) + { + return WebDAVNamespace_DAV; + } + else if(rStr.equals(aStrUcbOpenofficeOrgDAVProps)) + { + return WebDAVNamespace_ucb_openoffice_org_dav_props; + } + + return WebDAVNamespace_unknown; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// +// WebDAVName enum and StringToEnum converter using hash_map + +namespace +{ + enum WebDAVName + { + WebDAVName_unknown = 0, + WebDAVName_multistatus, + WebDAVName_response, + WebDAVName_href, + WebDAVName_propstat, + WebDAVName_prop, + WebDAVName_resourcetype, + WebDAVName_collection, + WebDAVName_getcontenttype, + WebDAVName_supportedlock, + WebDAVName_lockentry, + WebDAVName_lockscope, + WebDAVName_exclusive, + WebDAVName_locktype, + WebDAVName_write, + WebDAVName_shared, + WebDAVName_status, + WebDAVName_getlastmodified, + WebDAVName_creationdate, + WebDAVName_getcontentlength, + + WebDAVName_last + }; + + WebDAVName StrToWebDAVName(const rtl::OUString& rStr) + { + typedef std::hash_map< rtl::OUString, WebDAVName, rtl::OUStringHash > WebDAVNameMapper; + typedef std::pair< rtl::OUString, WebDAVName > WebDAVNameValueType; + static WebDAVNameMapper aWebDAVNameMapperList; + + if(aWebDAVNameMapperList.empty()) + { + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("multistatus"), WebDAVName_multistatus)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("response"), WebDAVName_response)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("href"), WebDAVName_href)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("propstat"), WebDAVName_propstat)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("prop"), WebDAVName_prop)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("resourcetype"), WebDAVName_resourcetype)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("collection"), WebDAVName_collection)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontenttype"), WebDAVName_getcontenttype)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("supportedlock"), WebDAVName_supportedlock)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockentry"), WebDAVName_lockentry)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("lockscope"), WebDAVName_lockscope)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("exclusive"), WebDAVName_exclusive)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("locktype"), WebDAVName_locktype)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("write"), WebDAVName_write)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("shared"), WebDAVName_shared)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("status"), WebDAVName_status)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getlastmodified"), WebDAVName_getlastmodified)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("creationdate"), WebDAVName_creationdate)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("getcontentlength"), WebDAVName_getcontentlength)); + } + + const WebDAVNameMapper::const_iterator aResult(aWebDAVNameMapperList.find(rStr)); + + if(aResult == aWebDAVNameMapperList.end()) + { + return WebDAVName_unknown; + } + else + { + return aResult->second; + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// +// WebDAVContext, holding information for each start/endElement pair + +namespace +{ + typedef std::map< ::rtl::OUString, ::rtl::OUString > NamespaceMap; + typedef std::pair< const ::rtl::OUString, ::rtl::OUString > NamespaceValueType; + + class WebDAVContext + { + private: + WebDAVContext* mpParent; + NamespaceMap maNamespaceMap; + ::rtl::OUString maWhiteSpace; + + ::rtl::OUString maNamespace; + ::rtl::OUString maName; + + WebDAVNamespace maWebDAVNamespace; + WebDAVName maWebDAVName; + + // local helpers + void parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs); + ::rtl::OUString mapNamespaceToken(const ::rtl::OUString& rToken) const; + void splitName(const ::rtl::OUString& rSource); + + public: + WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs); + ~WebDAVContext(); + + WebDAVContext* getParent() const { return mpParent; } + ::rtl::OUString& getWhiteSpace() { return maWhiteSpace; } + void setWhiteSpace(const ::rtl::OUString& rNew) { maWhiteSpace = rNew; } + + const ::rtl::OUString& getNamespace() const { return maNamespace; } + const ::rtl::OUString& getName() const { return maName; } + const WebDAVNamespace getWebDAVNamespace() const { return maWebDAVNamespace; } + const WebDAVName getWebDAVName() const { return maWebDAVName; } + }; + + void WebDAVContext::parseForNamespaceTokens(const uno::Reference< xml::sax::XAttributeList >& xAttribs) + { + const sal_Int16 nAttributes(xAttribs->getLength()); + static ::rtl::OUString aStrXmlns(::rtl::OUString::createFromAscii("xmlns")); + + for(sal_Int16 a(0); a < nAttributes; a++) + { + const ::rtl::OUString aName(xAttribs->getNameByIndex(a)); + const sal_Int32 nLen(aName.getLength()); + + if(nLen) + { + if(aName.match(aStrXmlns, 0)) + { + const sal_Int32 nIndex(aName.indexOf(sal_Unicode(':'), 0)); + + if(-1 != nIndex && nIndex + 1 < nLen) + { + const ::rtl::OUString aToken(aName.copy(nIndex + 1)); + + maNamespaceMap.insert(NamespaceValueType(aToken, xAttribs->getValueByIndex(a))); + } + } + } + } + } + + ::rtl::OUString WebDAVContext::mapNamespaceToken(const ::rtl::OUString& rToken) const + { + NamespaceMap::const_iterator iter = maNamespaceMap.find(rToken); + + if(maNamespaceMap.end() == iter) + { + if(getParent()) + { + return getParent()->mapNamespaceToken(rToken); + } + else + { + return rToken; + } + } + else + { + return (*iter).second; + } + } + + void WebDAVContext::splitName(const ::rtl::OUString& rSource) + { + const sal_Int32 nLen(rSource.getLength()); + maNamespace = ::rtl::OUString(); + maName = rSource; + + if(nLen) + { + const sal_Int32 nIndex(rSource.indexOf(sal_Unicode(':'), 0)); + + if(-1 != nIndex && nIndex > 0 && nIndex + 1 < nLen) + { + maNamespace = mapNamespaceToken(rSource.copy(0, nIndex)); + maName = rSource.copy(nIndex + 1); + } + } + } + + WebDAVContext::WebDAVContext(WebDAVContext* pParent, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs) + : mpParent(pParent), + maNamespaceMap(), + maWhiteSpace(), + maNamespace(), + maName(), + maWebDAVNamespace(WebDAVNamespace_unknown), + maWebDAVName(WebDAVName_unknown) + { + const sal_Int16 nAttributes(xAttribs->getLength()); + + if(nAttributes) + { + // parse evtl. namespace entries + parseForNamespaceTokens(xAttribs); + } + + // split name to namespace and name + splitName(aName); + + // evaluate enums for namespace and name + maWebDAVNamespace = StrToWebDAVNamespace(maNamespace); + maWebDAVName = StrToWebDAVName(maName); + } + + WebDAVContext::~WebDAVContext() + { + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// +// the Xml parser itself + +namespace +{ + enum WebDAVResponseParserMode + { + WebDAVResponseParserMode_PropFind = 0, + WebDAVResponseParserMode_PropName + }; + + class WebDAVResponseParser : public cppu::WeakImplHelper1< com::sun::star::xml::sax::XDocumentHandler > + { + private: + std::vector< http_dav_ucp::DAVResource > maResult_PropFind; + std::vector< http_dav_ucp::DAVResourceInfo > maResult_PropName; + + WebDAVContext* mpContext; + ::rtl::OUString maHref; + ::rtl::OUString maStatus; + std::vector< http_dav_ucp::DAVPropertyValue > maResponseProperties; + std::vector< http_dav_ucp::DAVPropertyValue > maPropStatProperties; + std::vector< ::rtl::OUString > maResponseNames; + std::vector< ::rtl::OUString > maPropStatNames; + uno::Sequence< ucb::LockEntry > maLockEntries; + ucb::LockScope maLockScope; + ucb::LockType maLockType; + WebDAVResponseParserMode meWebDAVResponseParserMode; + + // bitfield + bool mbResourceTypeCollection : 1; + bool mbLockScopeSet : 1; + bool mbLockTypeSet : 1; + + // local helpers + bool whitespaceIsAvailable() const + { + return mpContext && mpContext->getWhiteSpace().getLength(); + } + bool hasParent(WebDAVName aWebDAVName) const + { + return mpContext && mpContext->getParent() && aWebDAVName == mpContext->getParent()->getWebDAVName(); + } + bool propertyIsReady() const + { + return hasParent(WebDAVName_prop) && whitespaceIsAvailable(); + } + bool isCollectingProperties() const + { + return WebDAVResponseParserMode_PropFind == meWebDAVResponseParserMode; + } + bool isCollectingPropNames() const + { + return WebDAVResponseParserMode_PropName == meWebDAVResponseParserMode; + } + bool collectThisPropertyAsName() const + { + return isCollectingPropNames() && hasParent(WebDAVName_prop); + } + void pop_context() + { + if(mpContext) + { + WebDAVContext* pTemp = mpContext; + mpContext = mpContext->getParent(); + delete pTemp; + } + else + { + OSL_ENSURE(false, "Parser context pop without context (!)"); + } + } + + public: + WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode); + ~WebDAVResponseParser(); + + // Methods XDocumentHandler + virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (xml::sax::SAXException, uno::RuntimeException); + virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException); + + const std::vector< http_dav_ucp::DAVResource >& getResult_PropFind() const { return maResult_PropFind; } + const std::vector< http_dav_ucp::DAVResourceInfo >& getResult_PropName() const { return maResult_PropName; } + }; + + WebDAVResponseParser::WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode) + : maResult_PropFind(), + maResult_PropName(), + mpContext(0), + maHref(), + maStatus(), + maResponseProperties(), + maPropStatProperties(), + maResponseNames(), + maPropStatNames(), + maLockEntries(), + maLockScope(ucb::LockScope_EXCLUSIVE), + maLockType(ucb::LockType_WRITE), + meWebDAVResponseParserMode(eWebDAVResponseParserMode), + mbResourceTypeCollection(false), + mbLockScopeSet(false), + mbLockTypeSet(false) + { + } + + WebDAVResponseParser::~WebDAVResponseParser() + { + OSL_ENSURE(!mpContext, "Parser destructed with existing content (!)"); + while(mpContext) + { + pop_context(); + } + } + + void SAL_CALL WebDAVResponseParser::startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) + { + OSL_ENSURE(!mpContext, "Parser start with existing content (!)"); + } + + void SAL_CALL WebDAVResponseParser::endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) + { + OSL_ENSURE(!mpContext, "Parser end with existing content (!)"); + } + + void SAL_CALL WebDAVResponseParser::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException) + { + const sal_Int32 nLen(aName.getLength()); + + if(nLen) + { + // create new context (push) + mpContext = new WebDAVContext(mpContext, aName, xAttribs); + + if(collectThisPropertyAsName()) + { + // When collecting property names and parent is prop there is no need + // to handle the content of this property deeper (evtl. preparations) + } + else + { + switch(mpContext->getWebDAVNamespace()) + { + default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled + { + break; + } + case WebDAVNamespace_DAV: + { + switch(mpContext->getWebDAVName()) + { + default: // WebDAVName_unknown, WebDAVName_last or unhandled + { + break; + } + case WebDAVName_propstat: + { + // propstat start + if(isCollectingProperties()) + { + // reset maPropStatProperties + maPropStatProperties.clear(); + } + else + { + // when collecting properties reset maPropStatNames + maPropStatNames.clear(); + } + break; + } + case WebDAVName_response: + { + // response start, reset Href and status and maResponseProperties + maHref = maStatus = ::rtl::OUString(); + + if(isCollectingProperties()) + { + // reset maResponseProperties + maResponseProperties.clear(); + } + else + { + // reset maResponseNames when collecting properties + maResponseNames.clear(); + } + break; + } + case WebDAVName_resourcetype: + { + // resourcetype start, reset collection + mbResourceTypeCollection = false; + break; + } + case WebDAVName_supportedlock: + { + // supportedlock start, reset maLockEntries + maLockEntries.realloc(0); + break; + } + case WebDAVName_lockentry: + { + // lockentry start, reset maLockEntries + mbLockScopeSet = false; + mbLockTypeSet = false; + break; + } + } + break; + } + case WebDAVNamespace_ucb_openoffice_org_dav_props: + { + break; + } + } + } + } + } + + void SAL_CALL WebDAVResponseParser::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException) + { + const sal_Int32 nLen(aName.getLength()); + OSL_ENSURE(mpContext, "Parser EndElement without content (!)"); + + if(mpContext && nLen) + { + if(collectThisPropertyAsName()) + { + // When collecting property names and parent is prop, just append the prop name + // to the collection, no need to parse deeper + maPropStatNames.push_back(mpContext->getNamespace() + mpContext->getName()); + } + else + { + switch(mpContext->getWebDAVNamespace()) + { + default: // WebDAVNamespace_unknown, WebDAVNamespace_last or unhandled + { + break; + } + case WebDAVNamespace_DAV: + { + switch(mpContext->getWebDAVName()) + { + default: // WebDAVName_unknown, WebDAVName_last or unhandled + { + break; + } + case WebDAVName_href: + { + // href end, save it if we have whitespace + if(whitespaceIsAvailable()) + { + maHref = mpContext->getWhiteSpace(); + } + break; + } + case WebDAVName_status: + { + // status end, save it if we have whitespace + if(whitespaceIsAvailable()) + { + maStatus = mpContext->getWhiteSpace(); + } + break; + } + case WebDAVName_getlastmodified: + { + // getlastmodified end, safe if content is correct + if(propertyIsReady()) + { + static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getlastmodified")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_creationdate: + { + // creationdate end, safe if content is correct + if(propertyIsReady()) + { + static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:creationdate")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_collection: + { + // collection end, check and set + if(hasParent(WebDAVName_resourcetype)) + { + mbResourceTypeCollection = true; + } + break; + } + case WebDAVName_resourcetype: + { + // resourcetype end, check for collection + if(hasParent(WebDAVName_prop)) + { + static rtl::OUString aStrA(rtl::OUString::createFromAscii("DAV:resourcetype")); + static rtl::OUString aStrB(rtl::OUString::createFromAscii("collection")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStrA; + aDAVPropertyValue.Value <<= (mbResourceTypeCollection ? aStrB : rtl::OUString()); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_getcontentlength: + { + // getcontentlength end, safe if content is correct + if(propertyIsReady()) + { + static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontentlength")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_getcontenttype: + { + // getcontenttype end, safe if content is correct + if(propertyIsReady()) + { + static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:getcontenttype")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= mpContext->getWhiteSpace(); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_supportedlock: + { + // supportedlock end + if(hasParent(WebDAVName_prop) && maLockEntries.hasElements()) + { + static rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:supportedlock")); + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= maLockEntries; + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } + case WebDAVName_lockentry: + { + // lockentry end + if(hasParent(WebDAVName_supportedlock) && (mbLockScopeSet && mbLockTypeSet)) + { + const sal_Int32 nLength(maLockEntries.getLength()); + ucb::LockEntry aEntry; + + aEntry.Scope = maLockScope; + aEntry.Type = maLockType; + maLockEntries.realloc(nLength + 1); + maLockEntries[nLength] = aEntry; + } + break; + } + case WebDAVName_exclusive: + { + // exclusive lockscope end + if(hasParent(WebDAVName_lockscope)) + { + maLockScope = ucb::LockScope_EXCLUSIVE; + mbLockScopeSet = true; + } + break; + } + case WebDAVName_shared: + { + // shared lockscope end + if(hasParent(WebDAVName_lockscope)) + { + maLockScope = ucb::LockScope_SHARED; + mbLockScopeSet = true; + } + break; + } + case WebDAVName_write: + { + // write locktype end + if(hasParent(WebDAVName_locktype)) + { + maLockType = ucb::LockType_WRITE; + mbLockTypeSet = true; + } + break; + } + case WebDAVName_propstat: + { + // propstat end, check status + if(maStatus.getLength()) + { + static ::rtl::OUString aStrStatusOkay(::rtl::OUString::createFromAscii("HTTP/1.1 200 OK")); + + if(maStatus.equals(aStrStatusOkay)) + { + if(isCollectingProperties()) + { + if(maPropStatProperties.size()) + { + // append to maResponseProperties if okay + maResponseProperties.insert(maResponseProperties.end(), maPropStatProperties.begin(), maPropStatProperties.end()); + } + } + else + { + if(maPropStatNames.size()) + { + // when collecting properties append to + maResponseNames.insert(maResponseNames.end(), maPropStatNames.begin(), maPropStatNames.end()); + } + } + } + } + break; + } + case WebDAVName_response: + { + // respose end + if(maHref.getLength()) + { + if(isCollectingProperties()) + { + // create DAVResource when we have content + if(maResponseProperties.size()) + { + http_dav_ucp::DAVResource aDAVResource; + + aDAVResource.uri = maHref; + aDAVResource.properties = maResponseProperties; + maResult_PropFind.push_back(aDAVResource); + } + } + else + { + // when collecting properties add them to result when there are some + if(maResponseNames.size()) + { + http_dav_ucp::DAVResourceInfo aDAVResourceInfo(maHref); + + aDAVResourceInfo.properties = maResponseNames; + maResult_PropName.push_back(aDAVResourceInfo); + } + } + } + break; + } + } + break; + } + case WebDAVNamespace_ucb_openoffice_org_dav_props: + { + break; + } + } + } + + // destroy last context (pop) + pop_context(); + } + } + + void SAL_CALL WebDAVResponseParser::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException) + { + // collect whitespace over evtl. several calls in mpContext + OSL_ENSURE(mpContext, "Parser characters without content (!)"); + const sal_Int32 nLen(aChars.getLength()); + + if(mpContext && nLen) + { + // remove leading/trailing blanks and CRLF + const ::rtl::OUString aTrimmedChars(aChars.trim()); + + if(aTrimmedChars.getLength()) + { + ::rtl::OUString aNew(mpContext->getWhiteSpace()); + + if(aNew.getLength()) + { + // add one char when appending (see html1.1 spec) + aNew += ::rtl::OUString(sal_Unicode(' ')); + } + + aNew += aTrimmedChars; + mpContext->setWhiteSpace(aNew); + } + } + } + + void SAL_CALL WebDAVResponseParser::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ ) throw (xml::sax::SAXException, uno::RuntimeException) + { + } + + void SAL_CALL WebDAVResponseParser::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) throw (xml::sax::SAXException, uno::RuntimeException) + { + } + + void SAL_CALL WebDAVResponseParser::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) throw (xml::sax::SAXException, uno::RuntimeException) + { + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// +// wrapper for various calls to the parser + +namespace +{ + void parseWebDAVPropNameResponse( + const uno::Reference< io::XInputStream >& xInputStream, + std::vector< http_dav_ucp::DAVResource >& rPropFind, + std::vector< http_dav_ucp::DAVResourceInfo >& rPropName, + WebDAVResponseParserMode eWebDAVResponseParserMode) + { + if(xInputStream.is()) + { + try + { + // prepare ParserInputSrouce + xml::sax::InputSource myInputSource; + myInputSource.aInputStream = xInputStream; + + // get parser + uno::Reference< xml::sax::XParser > xParser( + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), + uno::UNO_QUERY_THROW ); + + // create parser; connect parser and filter + WebDAVResponseParser* pWebDAVResponseParser = new WebDAVResponseParser(eWebDAVResponseParserMode); + uno::Reference< xml::sax::XDocumentHandler > xWebDAVHdl(pWebDAVResponseParser); + xParser->setDocumentHandler(xWebDAVHdl); + + // finally, parse the stream + xParser->parseStream(myInputSource); + + // get result + switch(eWebDAVResponseParserMode) + { + case WebDAVResponseParserMode_PropFind: + { + rPropFind = pWebDAVResponseParser->getResult_PropFind(); + break; + } + case WebDAVResponseParserMode_PropName: + { + rPropName = pWebDAVResponseParser->getResult_PropName(); + break; + } + } + } + catch(uno::Exception&) + { + OSL_ENSURE(false, "WebDAV Parse error (!)"); + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// +// helper to parse a XML WebDAV response + +namespace http_dav_ucp +{ + std::vector< DAVResource > parseWebDAVPropFindResponse(const uno::Reference< io::XInputStream >& xInputStream) + { + std::vector< DAVResource > aRetval; + std::vector< DAVResourceInfo > aFoo; + + parseWebDAVPropNameResponse(xInputStream, aRetval, aFoo, WebDAVResponseParserMode_PropFind); + return aRetval; + } + + std::vector< DAVResourceInfo > parseWebDAVPropNameResponse(const uno::Reference< io::XInputStream >& xInputStream) + { + std::vector< DAVResource > aFoo; + std::vector< DAVResourceInfo > aRetval; + + parseWebDAVPropNameResponse(xInputStream, aFoo, aRetval, WebDAVResponseParserMode_PropName); + return aRetval; + } +} // namespace http_dav_ucp + +////////////////////////////////////////////////////////////////////////////// +// eof + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |