Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.cxx Thu Sep 24 23:52:34 2015 @@ -53,6 +53,7 @@ #include <com/sun/star/ucb/InsertCommandArgument.hpp> #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#include <com/sun/star/ucb/InteractiveLockingLockNotAvailableException.hpp> #include <com/sun/star/ucb/InteractiveLockingLockedException.hpp> #include <com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp> #include <com/sun/star/ucb/InteractiveLockingNotLockedException.hpp> @@ -84,6 +85,7 @@ #include "ContentProperties.hxx" #include "SerfUri.hxx" #include "UCBDeadPropertyValue.hxx" +#include <boost/current_function.hpp> using namespace com::sun::star; using namespace http_dav_ucp; @@ -728,23 +730,19 @@ uno::Any SAL_CALL Content::execute( post( aArg, Environment ); } else if ( aCommand.Name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM( "lock" ) ) && - supportsExclusiveWriteLock( Environment ) ) + RTL_CONSTASCII_STRINGPARAM( "lock" ) ) ) { ////////////////////////////////////////////////////////////////// // lock ////////////////////////////////////////////////////////////////// - lock( Environment ); } else if ( aCommand.Name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) && - supportsExclusiveWriteLock( Environment ) ) + RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) ) { ////////////////////////////////////////////////////////////////// // unlock ////////////////////////////////////////////////////////////////// - unlock( Environment ); } else if ( aCommand.Name.equalsAsciiL( @@ -1454,7 +1452,8 @@ uno::Reference< sdbc::XRow > Content::ge if ( !bHasAll ) { - // Only DAV resources support PROPFIND + // Only DAV resources support PROPFIND, + // check already done above in the outer 'if' head std::vector< rtl::OUString > aPropNames; uno::Sequence< beans::Property > aProperties( @@ -1475,17 +1474,16 @@ uno::Reference< sdbc::XRow > Content::ge while ( it != end ) { - if ( *it == rName ) + if ( *it == rName ) { + //the failed property in cache is the same as the requested one + //add to the requested properties list + aProperties[ nProps ] = rProperties[ n ]; + nProps++; break; + } ++it; } - - if ( it == end ) - { - aProperties[ nProps ] = rProperties[ n ]; - nProps++; - } } aProperties.realloc( nProps ); @@ -3013,6 +3011,23 @@ void Content::lock( const uno::Reference< ucb::XCommandEnvironment >& Environment ) throw( uno::Exception ) { + // i126305 TODO: add a check to see if this is really a DAV resource ? + // currently if the lock is not supported + // we got an error from the server that should be checked by the client (framework) + rtl::OUString aURL; + if ( m_bTransient ) + { + aURL = getParentURL(); + if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) ) + aURL += rtl::OUString::createFromAscii( "/" ); + + aURL += m_aEscapedTitle; + } + else + { + aURL = m_xIdentifier->getContentIdentifier(); + } + try { std::auto_ptr< DAVResourceAccess > xResAccess; @@ -3021,16 +3036,33 @@ void Content::lock( xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); } + // TODO i126305 to discuss: + // the owner string is the string that will be returned when the lock will be + // interrogated, via lockdiscovery. + // It should tell a user who is holding the document lock. + // The string currently set as owner is the one most useful now, telling what application locked the resource. + // May be it would be better put here something better ? + // Some string be added to office config? Or name of the user there? Or a document property user selectable? + // in case of adding it in config, the lock command should be added a string for the owner, and this + // will be in turn filled in by the framework (e.g. the ucb client). + // Of course in case of a configuration item, the string should be checked against internationalization + // and how to manage it in webdav protocol, this was not checked while solving i126305. uno::Any aOwnerAny; aOwnerAny - <<= rtl::OUString::createFromAscii( "http://ucb.openoffice.org" ); + <<= rtl::OUString::createFromAscii( "Apache OpenOffice - https://www.openoffice.org" ); + // TODO i126305 to discuss: + // on some webdav server, the 180 time formerly used appears to be too long, + // in this case, in response to a lock refresh operation we receive an error + // as 'Connection reset by peer', meaning the session was timed out by the other end. + // For now drop the defaul time to 120 seconds, seems better. + // In the future, another way of keeping the connection alive should be devised. ucb::Lock aLock( ucb::LockScope_EXCLUSIVE, ucb::LockType_WRITE, ucb::LockDepth_ZERO, aOwnerAny, - 180, // lock timeout in secs + 120, // lock timeout in secs //-1, // infinite lock uno::Sequence< ::rtl::OUString >() ); @@ -3043,6 +3075,44 @@ void Content::lock( } catch ( DAVException const & e ) { + switch(e.getStatus()) + { + case SC_LOCKED: + { + rtl::OUString aOwner( getLockOwner( Environment ) ); + + throw(ucb::InteractiveLockingLockedException( + rtl::OUString::createFromAscii( "Locked!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + aURL, + e.getExtendedError(), + sal_False, + aOwner )); + } + break; + case SC_METHOD_NOT_ALLOWED: + // this it's not always received, but the RFC4918 (which supersed RFC2518) + // tells about this in: + // http://tools.ietf.org/html/rfc4918#appendix-D.1 + // throw exception, will be interpreted by the lock requester (framework) + // it is actually a info, not an error + throw ucb::InteractiveLockingLockNotAvailableException( e.getData(), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_INFO, + aURL, + e.getExtendedError() ); + break; + //i126305 TODO + //see http://tools.ietf.org/html/rfc4918#section-9.10.6 + //not sure how to handle them, for the time being a dialog box is shown, + //the client (framework) should manage it + case SC_CONFLICT: + case SC_PRECONDITION_FAILED: + default: + //fallthrou + ; + } cancelCommandExecution( e, Environment, sal_False ); // Unreachable } @@ -3070,8 +3140,15 @@ void Content::unlock( } catch ( DAVException const & e ) { - cancelCommandExecution( e, Environment, sal_False ); + //i126305 TODO need to rise an exception of the right type ? + //meaning that the lock can not be released, since there is no such + //exception we use ucb::InteractiveNetworkReadException + throw ucb::InteractiveNetworkReadException( e.getData(), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_INFO, + e.getData() );//perhaps a more better should be used ? // Unreachable + cancelCommandExecution( e, Environment, sal_False ); } } @@ -3292,7 +3369,9 @@ uno::Any Content::MapDAVException( const static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, aURL, - sal_False ); // not SelfOwned + e.getExtendedError(), + sal_False, // not SelfOwned + rtl::OUString() ); #else { uno::Sequence< uno::Any > aArgs( 1 ); @@ -3319,7 +3398,9 @@ uno::Any Content::MapDAVException( const static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, aURL, - sal_True ); // SelfOwned + e.getExtendedError(), + sal_True, // SelfOwned + e.getOwner() ); break; case DAVException::DAV_NOT_LOCKED: @@ -3328,7 +3409,8 @@ uno::Any Content::MapDAVException( const rtl::OUString::createFromAscii( "Not locked!" ), static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, - aURL ); + aURL, + rtl::OUString() );//no extended info here break; case DAVException::DAV_LOCK_EXPIRED: @@ -3337,13 +3419,20 @@ uno::Any Content::MapDAVException( const rtl::OUString::createFromAscii( "Lock expired!" ), static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, - aURL ); + aURL, + rtl::OUString() );//no extended info here break; default: + rtl::OUStringBuffer buf( 512 ); + buf.appendAscii( BOOST_CURRENT_FUNCTION ); + buf.appendAscii( ":" ); + buf.append( (sal_Int32) __LINE__ ); + buf.appendAscii( " - Unknown DAV error: " ); + buf.append( (sal_Int32) e.getError() ); aException <<= ucb::InteractiveNetworkGeneralException( - rtl::OUString(), + rtl::OUString(buf.makeStringAndClear()), static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR ); break; @@ -3450,7 +3539,7 @@ const Content::ResourceType & Content::g // this is a DAV resource. std::vector< DAVResource > resources; std::vector< rtl::OUString > aPropNames; - uno::Sequence< beans::Property > aProperties( 5 ); + uno::Sequence< beans::Property > aProperties( 6 ); aProperties[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); aProperties[ 1 ].Name @@ -3461,6 +3550,9 @@ const Content::ResourceType & Content::g = rtl::OUString::createFromAscii( "MediaType" ); aProperties[ 4 ].Name = DAVProperties::SUPPORTEDLOCK; + //we will need this to check for existing locks + aProperties[ 5 ].Name + = DAVProperties::LOCKDISCOVERY; ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames ); @@ -3469,8 +3561,13 @@ const Content::ResourceType & Content::g DAVZERO, aPropNames, resources, xEnv ); // TODO - is this really only one? + // only one resource is received, see at: + // WebDAVResponseParser::endElement() + // case WebDAVName_response + //in file: ucb/source/ucp/webdav/webdavresponseparser.cxx: if ( resources.size() == 1 ) { + // there is a single resource m_xCachedProps.reset( new CachableContentProperties( resources[ 0 ] ) ); m_xCachedProps->containsAllNames( @@ -3507,3 +3604,38 @@ const Content::ResourceType & Content::g { return getResourceType( xEnv, m_xResAccess ); } + +rtl::OUString Content::getLockOwner( const uno::Reference< ucb::XCommandEnvironment >& Environment ) +{ + rtl::OUString aOwner; + try + { + //DAVProperties::LOCKDISCOVERY is not cached, need to get it from the server + uno::Sequence< beans::Property > aProperties( 1 ); + aProperties[ 0 ].Name = DAVProperties::LOCKDISCOVERY; + aProperties[ 0 ].Handle = -1; + + uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, Environment ) ); + + sal_Int32 nCount = aProperties.getLength(); + uno::Sequence< uno::Any > aValues( nCount ); + uno::Any* pValues = aValues.getArray(); + pValues[ 0 ] = xRow->getObject( 1, uno::Reference< container::XNameAccess >() ); + + uno::Sequence< ::com::sun::star::ucb::Lock > aLocks; + + if(aValues.getConstArray()[ 0 ] >>= aLocks) + if(aLocks.getLength() > 0) + { + ucb::Lock aLock = aLocks[0]; + aLock.Owner >>= aOwner; + OSL_TRACE("Content::getLockOwner - aOwner: '%s', <<<<<<<<<<<<<<<<<<<<<<<<<<<<<", + rtl::OUStringToOString(aOwner, RTL_TEXTENCODING_UTF8).getStr()); + + } + } + catch ( uno::Exception&) + { } + + return aOwner; +}
Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavcontent.hxx Thu Sep 24 23:52:34 2015 @@ -83,6 +83,7 @@ class Content : public ::ucbhelper::Cont rtl::OUString m_aEscapedTitle; ResourceType m_eResourceType; ContentProvider* m_pProvider; // No need for a ref, base class holds object + // True if the DEV resource is a 'unmapped URL' as it is named in RFC4918 bool m_bTransient; bool m_bCollection; bool m_bDidGetOrHead; @@ -137,20 +138,20 @@ private: const std::auto_ptr< DAVResourceAccess > & rResAccess ) throw ( ::com::sun::star::uno::Exception ); - // Command "open" + /// Command "open" com::sun::star::uno::Any open( const com::sun::star::ucb::OpenCommandArgument2 & rArg, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv ) throw( ::com::sun::star::uno::Exception ); - // Command "post" + /// Command "post" void post( const com::sun::star::ucb::PostCommandArgument2 & rArg, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv ) throw( ::com::sun::star::uno::Exception ); - // Command "insert" + /// Command "insert" void insert( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & xInputStream, sal_Bool bReplaceExisting, @@ -158,22 +159,22 @@ private: com::sun::star::ucb::XCommandEnvironment >& Environment ) throw( ::com::sun::star::uno::Exception ); - // Command "transfer" + /// Command "transfer" void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ) throw( ::com::sun::star::uno::Exception ); - // Command "delete" + /// Command "delete" void destroy( sal_Bool bDeletePhysical ) throw( ::com::sun::star::uno::Exception ); - // Command "lock" + /// Command "lock" void lock( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ) throw( ::com::sun::star::uno::Exception ); - // Command "unlock" + /// Command "unlock" void unlock( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ) throw( ::com::sun::star::uno::Exception ); @@ -193,7 +194,7 @@ private: const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ); - // XPropertyContainer replacement + /// XPropertyContainer replacement void addProperty( const com::sun::star::ucb::PropertyCommandArgument &aCmdArg, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ) @@ -226,13 +227,13 @@ public: throw ( ::com::sun::star::ucb::ContentCreationException ); virtual ~Content(); - // XInterface + /// XInterface XINTERFACE_DECL() - // XTypeProvider + /// XTypeProvider XTYPEPROVIDER_DECL() - // XServiceInfo + /// XServiceInfo virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ); @@ -241,12 +242,12 @@ public: getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ); - // XContent + /// XContent virtual rtl::OUString SAL_CALL getContentType() throw( com::sun::star::uno::RuntimeException ); - // XCommandProcessor + /// XCommandProcessor virtual com::sun::star::uno::Any SAL_CALL execute( const com::sun::star::ucb::Command& aCommand, sal_Int32 CommandId, @@ -259,7 +260,7 @@ public: abort( sal_Int32 CommandId ) throw( com::sun::star::uno::RuntimeException ); - // XPropertyContainer + /// XPropertyContainer virtual void SAL_CALL addProperty( const rtl::OUString& Name, sal_Int16 Attributes, @@ -295,7 +296,7 @@ public: DAVResourceAccess & getResourceAccess() { return *m_xResAccess; } - // Called from resultset data supplier. + /** Called from resultset data supplier. */ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > getPropertyValues( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMgr, @@ -305,6 +306,9 @@ public: const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, const ::rtl::OUString& rContentId ); + + /** returns the owner of current resource lock */ + rtl::OUString getLockOwner( const uno::Reference< ucb::XCommandEnvironment >& Environment ); }; } Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavprovider.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavprovider.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavprovider.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavprovider.cxx Thu Sep 24 23:52:34 2015 @@ -47,6 +47,7 @@ using namespace http_dav_ucp; rtl::OUString &WebDAVUserAgent::operator()() const { rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Apache " )); aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "$ooName/$ooSetupVersion" )); #if OSL_DEBUG_LEVEL > 0 #ifdef APR_VERSION Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.cxx Thu Sep 24 23:52:34 2015 @@ -29,6 +29,8 @@ #include <com/sun/star/xml/sax/InputSource.hpp> #include <comphelper/processfactory.hxx> #include <comphelper/seqstream.hxx> +#include <com/sun/star/ucb/Lock.hpp> +#include <com/sun/star/ucb/LockDepth.hpp> #include <com/sun/star/ucb/LockEntry.hpp> #include <com/sun/star/ucb/LockScope.hpp> #include <com/sun/star/ucb/LockType.hpp> @@ -94,6 +96,12 @@ namespace WebDAVName_locktype, WebDAVName_write, WebDAVName_shared, + WebDAVName_lockdiscovery, + WebDAVName_activelock, + WebDAVName_depth, + WebDAVName_owner, + WebDAVName_timeout, + WebDAVName_locktoken, WebDAVName_status, WebDAVName_getlastmodified, WebDAVName_creationdate, @@ -125,6 +133,12 @@ namespace 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("lockdiscovery"), WebDAVName_lockdiscovery)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("activelock"), WebDAVName_activelock)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("depth"), WebDAVName_depth)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("owner"), WebDAVName_owner)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("timeout"), WebDAVName_timeout)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(rtl::OUString::createFromAscii("locktoken"), WebDAVName_locktoken)); 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)); @@ -288,7 +302,8 @@ namespace enum WebDAVResponseParserMode { WebDAVResponseParserMode_PropFind = 0, - WebDAVResponseParserMode_PropName + WebDAVResponseParserMode_PropName, + WebDAVResponseParserMode_LockResponse }; class WebDAVResponseParser : public cppu::WeakImplHelper1< com::sun::star::xml::sax::XDocumentHandler > @@ -296,23 +311,36 @@ namespace private: std::vector< http_dav_ucp::DAVResource > maResult_PropFind; std::vector< http_dav_ucp::DAVResourceInfo > maResult_PropName; + http_dav_ucp::DAVPropertyValue maResult_Lock; WebDAVContext* mpContext; ::rtl::OUString maHref; + ::rtl::OUString maHrefLocks; //this is used for locks, when lockdiscoveryactive + ::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< ::rtl::OUString > maLockTokens; uno::Sequence< ucb::LockEntry > maLockEntries; + uno::Sequence< ucb::Lock > maLocks; //the returned locks following a lockdiscovery request ucb::LockScope maLockScope; ucb::LockType maLockType; - WebDAVResponseParserMode meWebDAVResponseParserMode; + ucb::LockDepth maLockDepth; + ::rtl::OUString maLockOwner; + sal_Int64 maLockTimeout; + ::rtl::OUString maLockToken; + + WebDAVResponseParserMode meWebDAVResponseParserMode; // bitfield bool mbResourceTypeCollection : 1; bool mbLockScopeSet : 1; bool mbLockTypeSet : 1; + bool mbLockTokenSet : 1; + //TODO: add other flag to manage reading od token, depth, timeout, owner + bool mbLockDiscoveryActive : 1; // local helpers bool whitespaceIsAvailable() const @@ -323,8 +351,8 @@ namespace { return mpContext && mpContext->getParent() && aWebDAVName == mpContext->getParent()->getWebDAVName(); } - bool propertyIsReady() const - { + bool propertyIsReady() const + { return hasParent(WebDAVName_prop) && whitespaceIsAvailable(); } bool isCollectingProperties() const @@ -335,6 +363,10 @@ namespace { return WebDAVResponseParserMode_PropName == meWebDAVResponseParserMode; } + bool isWaitingLockResponse() const + { + return WebDAVResponseParserMode_LockResponse == meWebDAVResponseParserMode; + } bool collectThisPropertyAsName() const { return isCollectingPropNames() && hasParent(WebDAVName_prop); @@ -360,7 +392,8 @@ namespace // 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 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); @@ -369,25 +402,34 @@ namespace 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; } + const http_dav_ucp::DAVPropertyValue& getResult_Lock() const { return maResult_Lock; } }; WebDAVResponseParser::WebDAVResponseParser(WebDAVResponseParserMode eWebDAVResponseParserMode) : maResult_PropFind(), maResult_PropName(), + maResult_Lock(), mpContext(0), maHref(), + maHrefLocks(), maStatus(), maResponseProperties(), maPropStatProperties(), maResponseNames(), maPropStatNames(), + maLockTokens(), maLockEntries(), + maLocks(), maLockScope(ucb::LockScope_EXCLUSIVE), maLockType(ucb::LockType_WRITE), + maLockDepth(ucb::LockDepth_ZERO), + maLockOwner(), + maLockTimeout(0), meWebDAVResponseParserMode(eWebDAVResponseParserMode), mbResourceTypeCollection(false), mbLockScopeSet(false), - mbLockTypeSet(false) + mbLockTypeSet(false), + mbLockDiscoveryActive(false) { } @@ -410,7 +452,8 @@ namespace 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) + 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()); @@ -418,7 +461,7 @@ namespace { // create new context (push) mpContext = new WebDAVContext(mpContext, aName, xAttribs); - + if(collectThisPropertyAsName()) { // When collecting property names and parent is prop there is no need @@ -491,6 +534,28 @@ namespace mbLockTypeSet = false; break; } + case WebDAVName_lockdiscovery: + { + // lockentry start, reset maLocks + maLocks.realloc(0); + mbLockDiscoveryActive = true; + break; + } + case WebDAVName_activelock: + { + // activelockstart, reset vars + mbLockScopeSet = false; + mbLockTypeSet = false; + mbLockTokenSet = false; + maLockTokens.realloc(0); + maHrefLocks = ::rtl::OUString(); + break; + } + case WebDAVName_locktoken: + { + mbLockTokenSet = true; + break; + } } break; } @@ -537,7 +602,14 @@ namespace // href end, save it if we have whitespace if(whitespaceIsAvailable()) { - maHref = mpContext->getWhiteSpace(); + if(mbLockDiscoveryActive) + { + maHrefLocks = mpContext->getWhiteSpace(); + } + else + { + maHref = mpContext->getWhiteSpace(); + } } break; } @@ -662,7 +734,7 @@ namespace case WebDAVName_exclusive: { // exclusive lockscope end - if(hasParent(WebDAVName_lockscope)) + if(hasParent(WebDAVName_lockscope) || hasParent(WebDAVName_activelock)) { maLockScope = ucb::LockScope_EXCLUSIVE; mbLockScopeSet = true; @@ -672,7 +744,7 @@ namespace case WebDAVName_shared: { // shared lockscope end - if(hasParent(WebDAVName_lockscope)) + if(hasParent(WebDAVName_lockscope) || hasParent(WebDAVName_activelock)) { maLockScope = ucb::LockScope_SHARED; mbLockScopeSet = true; @@ -682,13 +754,117 @@ namespace case WebDAVName_write: { // write locktype end - if(hasParent(WebDAVName_locktype)) + if(hasParent(WebDAVName_locktype) || hasParent(WebDAVName_activelock)) { maLockType = ucb::LockType_WRITE; mbLockTypeSet = true; } break; } + case WebDAVName_lockdiscovery: + { + // lockdiscovery end + if(hasParent(WebDAVName_prop)) + { + static ::rtl::OUString aStr(rtl::OUString::createFromAscii("DAV:lockdiscovery")); + if(isWaitingLockResponse()) + { + maResult_Lock.Name = aStr; + maResult_Lock.Value <<= maLocks; + } + else + { + ::http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = aStr; + aDAVPropertyValue.Value <<= maLocks; + maPropStatProperties.push_back(aDAVPropertyValue); + } + } + mbLockDiscoveryActive = false; + break; + } + case WebDAVName_activelock: + { + if(hasParent(WebDAVName_lockdiscovery) && + mbLockScopeSet && mbLockTypeSet && mbLockTokenSet) + { + const sal_Int32 nLength(maLocks.getLength()); + ucb::Lock aLock; + + aLock.Scope = maLockScope; + aLock.Type = maLockType; + //add tokens, depth, timeout, owner + aLock.LockTokens = maLockTokens; + aLock.Depth = maLockDepth; + aLock.Owner <<= maLockOwner; + aLock.Timeout = maLockTimeout; + maLocks.realloc(nLength + 1); + maLocks[nLength] = aLock; + } + break; + } + case WebDAVName_locktoken: + { + if(hasParent(WebDAVName_activelock)) + { + //add a token to the list of tokens + const sal_Int32 nLength(maLockTokens.getLength()); + maLockTokens.realloc(nLength + 1); + maLockTokens[nLength] = maHrefLocks; + mbLockTokenSet = true; + } + break; + } + case WebDAVName_timeout: + { + if(hasParent(WebDAVName_activelock)) + { + ::rtl::OUString aStr( mpContext->getWhiteSpace().toAsciiLowerCase()); + static ::rtl::OUString aInfinite( ::rtl::OUString::createFromAscii( "infinite" ) ); + static ::rtl::OUString aSecond( ::rtl::OUString::createFromAscii( "second-" ) ); + //look for infinity + sal_Int32 secondIndex; + if(aStr.indexOf(aInfinite) != -1) + { + maLockTimeout = -1; + } + else if((secondIndex = aStr.indexOf(aSecond)) != -1) + { + secondIndex += aSecond.getLength(); + maLockTimeout = aStr.copy(secondIndex).toInt64(); + } + } + break; + } + case WebDAVName_owner: + { + if(whitespaceIsAvailable()) + { + if(hasParent(WebDAVName_activelock)) + { + maLockOwner = mpContext->getWhiteSpace(); + } + } + break; + } + case WebDAVName_depth: + { + if(hasParent(WebDAVName_activelock)) + { + //set depth, one of three values + ::rtl::OUString aStr( mpContext->getWhiteSpace() ); + //default to zero, if not found + maLockDepth = ucb::LockDepth_ZERO; + if(aStr.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("0"))) + maLockDepth = ucb::LockDepth_ZERO; + else if(aStr.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("1"))) + maLockDepth = ucb::LockDepth_ONE; + else if(aStr.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("infinity"))) + maLockDepth = ucb::LockDepth_INFINITY; + } + break; + } case WebDAVName_propstat: { // propstat end, check status @@ -720,7 +896,7 @@ namespace } case WebDAVName_response: { - // respose end + // response end if(maHref.getLength()) { if(isCollectingProperties()) @@ -728,7 +904,7 @@ namespace // create DAVResource when we have content if(maResponseProperties.size()) { - http_dav_ucp::DAVResource aDAVResource; + ::http_dav_ucp::DAVResource aDAVResource; aDAVResource.uri = maHref; aDAVResource.properties = maResponseProperties; @@ -795,7 +971,8 @@ namespace { } - void SAL_CALL WebDAVResponseParser::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) 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) { } @@ -813,6 +990,7 @@ namespace const uno::Reference< io::XInputStream >& xInputStream, std::vector< http_dav_ucp::DAVResource >& rPropFind, std::vector< http_dav_ucp::DAVResourceInfo >& rPropName, + http_dav_ucp::DAVPropertyValue& rPropValue, WebDAVResponseParserMode eWebDAVResponseParserMode) { if(xInputStream.is()) @@ -822,18 +1000,18 @@ namespace // 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); @@ -850,6 +1028,11 @@ namespace rPropName = pWebDAVResponseParser->getResult_PropName(); break; } + case WebDAVResponseParserMode_LockResponse: + { + rPropValue = pWebDAVResponseParser->getResult_Lock(); + break; + } } } catch(uno::Exception&) @@ -869,19 +1052,33 @@ namespace http_dav_ucp { std::vector< DAVResource > aRetval; std::vector< DAVResourceInfo > aFoo; + DAVPropertyValue aFoo2; - parseWebDAVPropNameResponse(xInputStream, aRetval, aFoo, WebDAVResponseParserMode_PropFind); + parseWebDAVPropNameResponse(xInputStream, aRetval, aFoo, aFoo2, WebDAVResponseParserMode_PropFind); return aRetval; } - + std::vector< DAVResourceInfo > parseWebDAVPropNameResponse(const uno::Reference< io::XInputStream >& xInputStream) { std::vector< DAVResource > aFoo; std::vector< DAVResourceInfo > aRetval; + DAVPropertyValue aFoo2; + + parseWebDAVPropNameResponse(xInputStream, aFoo, aRetval, aFoo2, WebDAVResponseParserMode_PropName); + return aRetval; + } - parseWebDAVPropNameResponse(xInputStream, aFoo, aRetval, WebDAVResponseParserMode_PropName); + http_dav_ucp::DAVPropertyValue parseWebDAVLockResponse(const uno::Reference< io::XInputStream >& xInputStream) + { + std::vector< DAVResource > aFoo2; + std::vector< DAVResourceInfo > aFoo; + http_dav_ucp::DAVPropertyValue aRetval; + + + parseWebDAVPropNameResponse(xInputStream, aFoo2, aFoo, aRetval, WebDAVResponseParserMode_LockResponse); return aRetval; } + } // namespace http_dav_ucp ////////////////////////////////////////////////////////////////////////////// Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/webdavresponseparser.hxx Thu Sep 24 23:52:34 2015 @@ -33,6 +33,7 @@ namespace http_dav_ucp { std::vector< DAVResource > parseWebDAVPropFindResponse(const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream); std::vector< DAVResourceInfo > parseWebDAVPropNameResponse(const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream); + DAVPropertyValue parseWebDAVLockResponse(const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream); } // namespace http_dav_ucp ////////////////////////////////////////////////////////////////////////////// Modified: openoffice/branches/AOO410/main/ucbhelper/inc/ucbhelper/content.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucbhelper/inc/ucbhelper/content.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucbhelper/inc/ucbhelper/content.hxx (original) +++ openoffice/branches/AOO410/main/ucbhelper/inc/ucbhelper/content.hxx Thu Sep 24 23:52:34 2015 @@ -1029,6 +1029,27 @@ public: throw( ::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::RuntimeException, ::com::sun::star::uno::Exception ); + //->i126305 + /** lock the resource + * + * + */ + void + lock() + throw( ::com::sun::star::ucb::CommandAbortedException, + ::com::sun::star::uno::RuntimeException, + ::com::sun::star::uno::Exception ); + + /** ulock the resource + * + * + */ + void + unlock() + throw( ::com::sun::star::ucb::CommandAbortedException, + ::com::sun::star::uno::RuntimeException, + ::com::sun::star::uno::Exception ); + //<-i126305 }; } /* namespace ucbhelper */ Modified: openoffice/branches/AOO410/main/ucbhelper/source/client/content.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucbhelper/source/client/content.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucbhelper/source/client/content.cxx (original) +++ openoffice/branches/AOO410/main/ucbhelper/source/client/content.cxx Thu Sep 24 23:52:34 2015 @@ -1627,6 +1627,41 @@ sal_Bool Content::isDocument() return sal_False; } +//->i126305 =============================================================== +void Content::lock() + throw( CommandAbortedException, RuntimeException, Exception ) +{ + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "lock" ); + aCommand.Handle = -1; // n/a + // aCommand.Argument <<= aArg; + + m_xImpl->executeCommand( aCommand ); + + // return xSink->getInputStream(); +} + +//========================================================================= +void Content::unlock() + throw( CommandAbortedException, RuntimeException, Exception ) +{ + + // OpenCommandArgument2 aArg; + //aArg.Mode = OpenMode::DOCUMENT_SHARE_DENY_NONE; + //aArg.Priority = 0; // unused + //aArg.Sink = xSink; + //aArg.Properties = Sequence< Property >( 0 ); // unused + + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "unlock" ); + aCommand.Handle = -1; // n/a + // aCommand.Argument <<= aArg; + + m_xImpl->executeCommand( aCommand ); + +} +//<-i126305 + //========================================================================= //========================================================================= //