ooo-build r11327 - in trunk: . patches/src680
- From: jholesovsky svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r11327 - in trunk: . patches/src680
- Date: Fri, 18 Jan 2008 21:46:31 +0000 (GMT)
Author: jholesovsky
Date: Fri Jan 18 21:46:31 2008
New Revision: 11327
URL: http://svn.gnome.org/viewvc/ooo-build?rev=11327&view=rev
Log:
2008-01-18 Jan Holesovsky <kendy suse cz>
* patches/src680/webdav-locking.diff,
patches/src680/apply: Implement locking for WebDAV UCP.
Added:
trunk/patches/src680/webdav-locking.diff
Modified:
trunk/ChangeLog
trunk/patches/src680/apply
Modified: trunk/patches/src680/apply
==============================================================================
--- trunk/patches/src680/apply (original)
+++ trunk/patches/src680/apply Fri Jan 18 21:46:31 2008
@@ -527,6 +527,10 @@
# Move gnome-vfs out of the startup sequence, load it only when needed
gnome-vfs-late-init.diff, i#84137, jholesov
+# WebDAV locking
+# It is in this section because it needs part of the gvfs-related patches
+webdav-locking.diff, n#346711, i#29152, jholesov
+
[ QuickStarter < ooh680-m2 ]
# External splash screen implementation / 2nd time accelerator
Added: trunk/patches/src680/webdav-locking.diff
==============================================================================
--- (empty file)
+++ trunk/patches/src680/webdav-locking.diff Fri Jan 18 21:46:31 2008
@@ -0,0 +1,1579 @@
+diff --git a/comphelper/source/misc/mediadescriptor.cxx b/comphelper/source/misc/mediadescriptor.cxx
+index 078309b..5e5d476 100644
+--- comphelper/source/misc/mediadescriptor.cxx
++++ comphelper/source/misc/mediadescriptor.cxx
+@@ -754,9 +754,12 @@ sal_Bool MediaDescriptor::impl_openStreamWithURL(const ::rtl::OUString& sURL)
+ throw(::com::sun::star::uno::RuntimeException)
+ {
+ // prepare the environment
++ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ css::uno::Reference< css::task::XInteractionHandler > xOrgInteraction = getUnpackedValueOrDefault(
+ MediaDescriptor::PROP_INTERACTIONHANDLER(),
+- css::uno::Reference< css::task::XInteractionHandler >());
++ css::uno::Reference< css::task::XInteractionHandler > (
++ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), css::uno::UNO_QUERY )
++ );
+
+ StillReadWriteInteraction* pInteraction = new StillReadWriteInteraction(xOrgInteraction);
+ css::uno::Reference< css::task::XInteractionHandler > xInteraction(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY);
+diff --git a/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx b/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
+index 069faa7..7efa34e 100644
+--- ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
++++ ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
+@@ -45,6 +45,10 @@
+ #include "DAVAuthListener.hxx"
+ #endif
+
++#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
++#include <com/sun/star/ucb/XCommandEnvironment.hpp>
++#endif
++
+ namespace webdav_ucp
+ {
+ typedef std::pair< rtl::OUString, rtl::OUString > DAVRequestHeader;
+@@ -57,12 +61,12 @@ struct DAVRequestEnvironment
+ // rtl::Reference< DAVStatusListener > m_xStatusListener;
+ // rtl::Reference< DAVProgressListener > m_xStatusListener;
+ DAVRequestHeaders m_aRequestHeaders;
+- uno::Reference< ucb::XCommandEnvironment > m_xEnv;
++ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+-DAVRequestEnvironment( const rtl::OUString & rRequestURI,
++ DAVRequestEnvironment( const rtl::OUString & rRequestURI,
+ const rtl::Reference< DAVAuthListener > & xListener,
+ const DAVRequestHeaders & rRequestHeaders,
+- const uno::Reference< ucb::XCommandEnvironment > & xEnv)
++ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv)
+ : m_aRequestURI( rRequestURI ),
+ m_xAuthListener( xListener ),
+ m_aRequestHeaders( rRequestHeaders ),
+diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.cxx b/ucb/source/ucp/webdav/DAVResourceAccess.cxx
+index aa1c821..668fe20 100644
+--- ucb/source/ucp/webdav/DAVResourceAccess.cxx
++++ ucb/source/ucp/webdav/DAVResourceAccess.cxx
+@@ -47,6 +47,13 @@
+ #include "DAVAuthListenerImpl.hxx"
+ #include "DAVResourceAccess.hxx"
+
++#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
++#include <comphelper/processfactory.hxx>
++#endif
++#ifndef _UCBHELPER_COMMANDENVIRONMENT_HXX
++#include <ucbhelper/commandenvironment.hxx>
++#endif
++
+ using namespace webdav_ucp;
+ using namespace com::sun::star;
+
+@@ -66,56 +73,55 @@ int DAVAuthListener_Impl::authenticate(
+ ::rtl::OUString & inoutUserName,
+ ::rtl::OUString & outPassWord )
+ {
++ uno::Reference< task::XInteractionHandler > xIH;
++
+ if ( m_xEnv.is() )
+- {
+- uno::Reference< task::XInteractionHandler > xIH
+- = m_xEnv->getInteractionHandler();
+- if ( xIH.is() )
+- {
+- // #102871# - Supply username and password from previous try.
+- // Password container service depends on this!
+- if ( inoutUserName.getLength() == 0 )
+- inoutUserName = m_aPrevUsername;
+-
+- if ( outPassWord.getLength() == 0 )
+- outPassWord = m_aPrevPassword;
+-
+- rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
+- = new ucbhelper::SimpleAuthenticationRequest( inHostName,
+- inRealm,
+- inoutUserName,
+- outPassWord );
+- xIH->handle( xRequest.get() );
+-
+- rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+- = xRequest->getSelection();
+-
+- if ( xSelection.is() )
+- {
+- // Handler handled the request.
+- uno::Reference< task::XInteractionAbort > xAbort(
+- xSelection.get(), uno::UNO_QUERY );
+- if ( !xAbort.is() )
+- {
+- const rtl::Reference<
+- ucbhelper::InteractionSupplyAuthentication > & xSupp
+- = xRequest->getAuthenticationSupplier();
+-
+- inoutUserName = xSupp->getUserName();
+- outPassWord = xSupp->getPassword();
+-
+- // #102871# - Remember username and password.
+- m_aPrevUsername = inoutUserName;
+- m_aPrevPassword = outPassWord;
+-
+- // go on.
+- return 0;
+- }
+- }
+- }
+- }
+- // Abort.
+- return -1;
++ xIH = m_xEnv->getInteractionHandler();
++ else
++ xIH = DAVResourceAccess::createCommandEnvironment()->getInteractionHandler();
++
++ if ( !xIH.is() )
++ return -1;
++
++ // #102871# - Supply username and password from previous try.
++ // Password container service depends on this!
++ if ( inoutUserName.getLength() == 0 )
++ inoutUserName = m_aPrevUsername;
++
++ if ( outPassWord.getLength() == 0 )
++ outPassWord = m_aPrevPassword;
++
++ rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
++ = new ucbhelper::SimpleAuthenticationRequest( inHostName,
++ inRealm,
++ inoutUserName,
++ outPassWord );
++ xIH->handle( xRequest.get() );
++
++ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
++ = xRequest->getSelection();
++
++ if ( !xSelection.is() )
++ return -1;
++
++ // Handler handled the request.
++ uno::Reference< task::XInteractionAbort > xAbort(
++ xSelection.get(), uno::UNO_QUERY );
++ if ( xAbort.is() )
++ return -1;
++
++ const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
++ = xRequest->getAuthenticationSupplier();
++
++ inoutUserName = xSupp->getUserName();
++ outPassWord = xSupp->getPassword();
++
++ // #102871# - Remember username and password.
++ m_aPrevUsername = inoutUserName;
++ m_aPrevPassword = outPassWord;
++
++ // go on.
++ return 0;
+ }
+
+ //=========================================================================
+@@ -435,7 +441,7 @@ void DAVResourceAccess::GET(
+ }
+
+ //=========================================================================
+-uno::Reference< io::XInputStream > DAVResourceAccess::GET(
++uno::Reference< io::XStream > DAVResourceAccess::GET(
+ const std::vector< rtl::OUString > & rHeaderNames,
+ DAVResource & rResource,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+@@ -443,7 +449,7 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET(
+ {
+ initialize();
+
+- uno::Reference< io::XInputStream > xStream;
++ uno::Reference< io::XStream > xStream;
+ bool bRetry;
+ do
+ {
+@@ -864,22 +870,44 @@ void DAVResourceAccess::DESTROY(
+
+ //=========================================================================
+ void DAVResourceAccess::LOCK (
+- const ucb::Lock & /*rLock*/,
+- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
++ ucb::Lock & rLock,
++ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+ {
+-// initialize();
+- OSL_ENSURE( sal_False, "DAVResourceAccess::LOCK - NYI" );
++ initialize();
++
++ DAVRequestHeaders aHeaders;
++ getUserRequestHeaders( xEnv,
++ getRequestURI(),
++ rtl::OUString::createFromAscii( "LOCK" ),
++ aHeaders );
++
++ m_xSession->LOCK( rLock,
++ DAVRequestEnvironment(
++ getRequestURI(),
++ new DAVAuthListener_Impl( xEnv ),
++ aHeaders, xEnv ) );
+ }
+
+ //=========================================================================
+ void DAVResourceAccess::UNLOCK (
+- const ucb::Lock & /*rLock*/,
+- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
++ ucb::Lock & rLock,
++ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+ {
+-// initialize();
+- OSL_ENSURE( sal_False, "DAVResourceAccess::UNLOCK - NYI" );
++ initialize();
++
++ DAVRequestHeaders aHeaders;
++ getUserRequestHeaders( xEnv,
++ getRequestURI(),
++ rtl::OUString::createFromAscii( "UNLOCK" ),
++ aHeaders );
++
++ m_xSession->UNLOCK( rLock,
++ DAVRequestEnvironment(
++ getRequestURI(),
++ new DAVAuthListener_Impl( xEnv ),
++ aHeaders, xEnv ) );
+ }
+
+ //=========================================================================
+@@ -984,6 +1012,18 @@ void DAVResourceAccess::getUserRequestHeaders(
+ }
+ }
+
++// static
++com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > DAVResourceAccess::createCommandEnvironment( void )
++{
++ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
++ uno::Reference< task::XInteractionHandler > xInteractionHandler = uno::Reference< task::XInteractionHandler > (
++ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), uno::UNO_QUERY );
++ ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, uno::Reference< ucb::XProgressHandler >() );
++
++ return uno::Reference< ucb::XCommandEnvironment >( static_cast< ucb::XCommandEnvironment* >( pCommandEnv ), uno::UNO_QUERY );
++}
++
++
+ //=========================================================================
+ sal_Bool DAVResourceAccess::detectRedirectCycle(
+ const rtl::OUString& rRedirectURL )
+diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.hxx b/ucb/source/ucp/webdav/DAVResourceAccess.hxx
+index 66f758c..5069ae7 100644
+--- ucb/source/ucp/webdav/DAVResourceAccess.hxx
++++ ucb/source/ucp/webdav/DAVResourceAccess.hxx
+@@ -167,7 +167,7 @@ public:
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException );
+
+- com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
++ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ GET( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
+ DAVResource & rResource,
+ const com::sun::star::uno::Reference<
+@@ -237,13 +237,13 @@ public:
+ throw( DAVException );
+
+ void
+- LOCK( const com::sun::star::ucb::Lock & rLock,
++ LOCK( com::sun::star::ucb::Lock & rLock,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException );
+
+ void
+- UNLOCK( const com::sun::star::ucb::Lock & rLock,
++ UNLOCK( com::sun::star::ucb::Lock & rLock,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException );
+@@ -256,6 +256,8 @@ public:
+ const rtl::OUString & rMethod,
+ DAVRequestHeaders & rRequestHeaders );
+
++ static com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > createCommandEnvironment( void );
++
+ private:
+ const rtl::OUString & getRequestURI() const;
+ sal_Bool detectRedirectCycle( const rtl::OUString& rRedirectURL )
+diff --git a/ucb/source/ucp/webdav/DAVSession.hxx b/ucb/source/ucp/webdav/DAVSession.hxx
+index 8462f5a..df5ac71 100644
+--- ucb/source/ucp/webdav/DAVSession.hxx
++++ ucb/source/ucp/webdav/DAVSession.hxx
+@@ -42,12 +42,18 @@
+ #include <rtl/ustring.hxx>
+ #endif
+
++#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
++#include <com/sun/star/io/XStream.hpp>
++#endif
+ #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+ #include <com/sun/star/io/XInputStream.hpp>
+ #endif
+ #ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
+ #include <com/sun/star/io/XOutputStream.hpp>
+ #endif
++#ifndef _COM_SUN_STAR_UCB_LOCK_HPP_
++#include <com/sun/star/ucb/Lock.hpp>
++#endif
+
+ #ifndef _DAVEXCEPTION_HXX_
+ #include "DAVException.hxx"
+@@ -140,7 +146,7 @@ public:
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+- virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
++ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+@@ -199,16 +205,14 @@ public:
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+- // Note: Uncomment the following if locking support is required
+- /*
+- virtual void LOCK ( const Lock & inLock,
++ virtual void LOCK ( com::sun::star::ucb::Lock & rLock,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+- virtual void UNLOCK ( const Lock & inLock,
++ virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+- */
++
+ protected:
+ rtl::Reference< DAVSessionFactory > m_xFactory;
+
+diff --git a/ucb/source/ucp/webdav/NeonInputStream.cxx b/ucb/source/ucp/webdav/NeonInputStream.cxx
+index 334e457..720bd65 100644
+--- ucb/source/ucp/webdav/NeonInputStream.cxx
++++ ucb/source/ucp/webdav/NeonInputStream.cxx
+@@ -36,24 +36,32 @@
+ // MARKER(update_precomp.py): autogen include statement, do not remove
+ #include "precompiled_ucb.hxx"
+ #include "NeonInputStream.hxx"
++#include "DAVResourceAccess.hxx"
+
+ #ifndef _RTL_MEMORY_H_
+ #include <rtl/memory.h>
+ #endif
+
++#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
++#include <comphelper/processfactory.hxx>
++#endif
++
++#include <cstdio>
++
+ using namespace cppu;
+-using namespace rtl;
+ using namespace com::sun::star::io;
+-using namespace com::sun::star::uno;
++using namespace com::sun::star;
+ using namespace webdav_ucp;
+
+
+ // -------------------------------------------------------------------
+ // Constructor
+ // -------------------------------------------------------------------
+-NeonInputStream::NeonInputStream( void )
+-: mLen( 0 ),
+- mPos( 0 )
++NeonInputStream::NeonInputStream()
++: m_nLen( 0 ),
++ m_nPos( 0 ),
++ m_bDirty( sal_False ),
++ m_pLock( NULL )
+ {
+ }
+
+@@ -62,6 +70,7 @@ NeonInputStream::NeonInputStream( void )
+ // -------------------------------------------------------------------
+ NeonInputStream::~NeonInputStream( void )
+ {
++ Unlock();
+ }
+
+ // -------------------------------------------------------------------
+@@ -70,24 +79,63 @@ NeonInputStream::~NeonInputStream( void )
+ // -------------------------------------------------------------------
+ void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen )
+ {
+- mInputBuffer.realloc( sal::static_int_cast<sal_Int32>(mLen) + inLen );
+- rtl_copyMemory( mInputBuffer.getArray() + mLen, inBuf, inLen );
+- mLen += inLen;
++ OSL_ENSURE( !m_bDirty, "Cannot AddToStream() when it was already written to it." );
++
++ m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>(m_nLen) + inLen );
++ rtl_copyMemory( m_aInputBuffer.getArray() + m_nLen, inBuf, inLen );
++ m_nLen += inLen;
++}
++
++// -------------------------------------------------------------------
++// Associate a lock with this stream
++// -------------------------------------------------------------------
++void NeonInputStream::SetLock( const com::sun::star::ucb::Lock &rLock,
++ const rtl::OUString &rURL )
++{
++ m_aURL = rURL;
++
++ if ( !m_pLock )
++ m_pLock = new ucb::Lock( rLock );
++ else
++ *m_pLock = rLock;
+ }
+
+ // -------------------------------------------------------------------
+ // queryInterface
+ // -------------------------------------------------------------------
+-Any NeonInputStream::queryInterface( const Type &type )
+- throw( RuntimeException )
++uno::Any NeonInputStream::queryInterface( const uno::Type &type )
++ throw( uno::RuntimeException )
+ {
+- Any aRet = ::cppu::queryInterface( type,
+- static_cast< XInputStream * >( this ),
+- static_cast< XSeekable * >( this ) );
++ uno::Any aRet = ::cppu::queryInterface( type,
++ static_cast< XStream * >( this ),
++ static_cast< XInputStream * >( this ),
++ static_cast< XOutputStream * >( this ),
++ static_cast< XSeekable * >( this ),
++ static_cast< XTruncate * >( this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
+ }
+
+ // -------------------------------------------------------------------
++// getInputStream
++// -------------------------------------------------------------------
++com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
++NeonInputStream::getInputStream( void )
++ throw( com::sun::star::uno::RuntimeException )
++{
++ return uno::Reference< XInputStream >( this );
++}
++
++// -------------------------------------------------------------------
++// getOutputStream
++// -------------------------------------------------------------------
++com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
++NeonInputStream::getOutputStream( void )
++ throw( com::sun::star::uno::RuntimeException )
++{
++ return uno::Reference< XOutputStream >( this );
++}
++
++// -------------------------------------------------------------------
+ // readBytes
+ // "Reads" the specified number of bytes from the stream
+ // -------------------------------------------------------------------
+@@ -100,7 +148,7 @@ sal_Int32 SAL_CALL NeonInputStream::readBytes(
+ {
+ // Work out how much we're actually going to write
+ sal_Int32 theBytes2Read = nBytesToRead;
+- sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(mLen - mPos);
++ sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(m_nLen - m_nPos);
+ if ( theBytes2Read > theBytesLeft )
+ theBytes2Read = theBytesLeft;
+
+@@ -109,10 +157,10 @@ sal_Int32 SAL_CALL NeonInputStream::readBytes(
+
+ // Write the data
+ rtl_copyMemory(
+- aData.getArray(), mInputBuffer.getConstArray() + mPos, theBytes2Read );
++ aData.getArray(), m_aInputBuffer.getConstArray() + m_nPos, theBytes2Read );
+
+ // Update our stream position for next time
+- mPos += theBytes2Read;
++ m_nPos += theBytes2Read;
+
+ return theBytes2Read;
+ }
+@@ -141,9 +189,9 @@ void SAL_CALL NeonInputStream::skipBytes( sal_Int32 nBytesToSkip )
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+ {
+- mPos += nBytesToSkip;
+- if ( mPos >= mLen )
+- mPos = mLen;
++ m_nPos += nBytesToSkip;
++ if ( m_nPos >= m_nLen )
++ m_nPos = m_nLen;
+ }
+
+ // -------------------------------------------------------------------
+@@ -155,7 +203,7 @@ sal_Int32 SAL_CALL NeonInputStream::available( )
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+ {
+- return sal::static_int_cast<sal_Int32>(mLen - mPos);
++ return sal::static_int_cast<sal_Int32>(m_nLen - m_nPos);
+ }
+
+ // -------------------------------------------------------------------
+@@ -176,12 +224,12 @@ void SAL_CALL NeonInputStream::seek( sal_Int64 location )
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+ {
+- if ( location < 0 )
+- throw ::com::sun::star::lang::IllegalArgumentException();
++ if ( location < 0 )
++ throw ::com::sun::star::lang::IllegalArgumentException();
+
+- if ( location <= mLen )
+- mPos = location;
+- else
++ if ( location <= m_nLen )
++ m_nPos = location;
++ else
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+
+@@ -192,7 +240,7 @@ sal_Int64 SAL_CALL NeonInputStream::getPosition()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+ {
+- return mPos;
++ return m_nPos;
+ }
+
+ // -------------------------------------------------------------------
+@@ -202,5 +250,107 @@ sal_Int64 SAL_CALL NeonInputStream::getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+ {
+- return mLen;
++ return m_nLen;
++}
++
++// -------------------------------------------------------------------
++// writeBytes
++// -------------------------------------------------------------------
++void SAL_CALL NeonInputStream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
++ throw( com::sun::star::io::NotConnectedException,
++ com::sun::star::io::BufferSizeExceededException,
++ com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException)
++{
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: writeBytes()\n" );
++#endif
++
++ sal_Int32 nDataLen = aData.getLength();
++ OSL_ASSERT( nDataLen >= 0 );
++
++ // Anything to do?
++ if ( nDataLen == 0 )
++ return;
++
++ // Update the length of the stream & size of the buffer
++ if ( m_nLen < m_nPos + nDataLen )
++ {
++ m_nLen = m_nPos + nDataLen;
++ if ( m_aInputBuffer.getLength() < m_nLen )
++ m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>( m_nLen ) );
++ }
++
++ rtl_copyMemory( m_aInputBuffer.getArray() + m_nPos, aData.getConstArray(), nDataLen );
++ m_nPos += nDataLen;
++
++ m_bDirty = sal_True;
++}
++
++// -------------------------------------------------------------------
++// flush
++// -------------------------------------------------------------------
++void SAL_CALL NeonInputStream::flush( void )
++ throw( NotConnectedException, BufferSizeExceededException,
++ IOException, uno::RuntimeException )
++{
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: flush()\n" );
++#endif
++ // Nothing to do, we transfer the data in closeOutput() (if dirty)
++}
++
++// -------------------------------------------------------------------
++// closeOutput
++// -------------------------------------------------------------------
++void SAL_CALL NeonInputStream::closeOutput( void )
++ throw( com::sun::star::io::NotConnectedException,
++ com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException )
++{
++ if ( m_bDirty )
++ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: TODO write on closeOutput(), the stream is dirty!\n" );
++#endif
++ }
++}
++
++// -------------------------------------------------------------------
++// truncate
++// -------------------------------------------------------------------
++void SAL_CALL NeonInputStream::truncate( void )
++ throw( com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException )
++{
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: truncate()\n" );
++#endif
++
++ if ( m_nLen > 0 )
++ {
++ m_nLen = m_nPos = 0;
++ m_bDirty = sal_True;
++ }
++}
++
++// -------------------------------------------------------------------
++// Unlock the stream & destroy the lock
++// -------------------------------------------------------------------
++void NeonInputStream::Unlock( void )
++{
++ if ( m_pLock )
++ {
++ // FIXME I guess it is a bit hacky to create the new session just for
++ // the unlock? But so far it seems I have no other chance...
++ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
++ rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
++
++ DAVResourceAccess aResourceAccess( xFactory, rDAVFactory, m_aURL );
++
++ aResourceAccess.UNLOCK( *m_pLock, DAVResourceAccess::createCommandEnvironment() );
++
++ delete m_pLock;
++ m_pLock = NULL;
++ }
+ }
+diff --git a/ucb/source/ucp/webdav/NeonInputStream.hxx b/ucb/source/ucp/webdav/NeonInputStream.hxx
+index 517e6d8..ba470e6 100644
+--- ucb/source/ucp/webdav/NeonInputStream.hxx
++++ ucb/source/ucp/webdav/NeonInputStream.hxx
+@@ -45,12 +45,27 @@
+ #include <cppuhelper/weak.hxx>
+ #endif
+
++#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
++#include <com/sun/star/io/XStream.hpp>
++#endif
+ #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+ #include <com/sun/star/io/XInputStream.hpp>
+ #endif
++#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
++#include <com/sun/star/io/XOutputStream.hpp>
++#endif
+ #ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
+ #include <com/sun/star/io/XSeekable.hpp>
+ #endif
++#ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_
++#include <com/sun/star/io/XTruncate.hpp>
++#endif
++
++#ifndef _COM_SUN_STAR_UCB_LOCK_HPP_
++#include <com/sun/star/ucb/Lock.hpp>
++#endif
++
++#include "DAVRequestEnvironment.hxx"
+
+
+ namespace webdav_ucp
+@@ -61,21 +76,33 @@ namespace webdav_ucp
+ // A simple XInputStream implementation provided specifically for use
+ // by the DAVSession::GET method.
+ // -------------------------------------------------------------------
+-class NeonInputStream : public ::com::sun::star::io::XInputStream,
++class NeonInputStream : public ::com::sun::star::io::XStream,
++ public ::com::sun::star::io::XInputStream,
++ public ::com::sun::star::io::XOutputStream,
+ public ::com::sun::star::io::XSeekable,
++ public ::com::sun::star::io::XTruncate,
+ public ::cppu::OWeakObject
+ {
+- private:
+- com::sun::star::uno::Sequence< sal_Int8 > mInputBuffer;
+- sal_Int64 mLen;
+- sal_Int64 mPos;
++private:
++ com::sun::star::uno::Sequence< sal_Int8 > m_aInputBuffer;
++ sal_Int64 m_nLen; // cannot be just m_aInputBuffer.getLength() - the buffer can be bigger
++ sal_Int64 m_nPos;
+
+- public:
+- NeonInputStream( void );
+- virtual ~NeonInputStream();
++ sal_Bool m_bDirty;
+
+- // Add some data to the end of the stream
+- void AddToStream( const char * inBuf, sal_Int32 inLen );
++ com::sun::star::ucb::Lock *m_pLock;
++ rtl::OUString m_aURL;
++
++public:
++ NeonInputStream( void );
++ virtual ~NeonInputStream();
++
++ // Add some data to the end of the stream
++ void AddToStream( const char * inBuf, sal_Int32 inLen );
++
++ // Associate a lock with this stream
++ void SetLock( const com::sun::star::ucb::Lock &rLock,
++ const rtl::OUString &rURL );
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+@@ -90,6 +117,12 @@ class NeonInputStream : public ::com::sun::star::io::XInputStream,
+ throw()
+ { OWeakObject::release(); }
+
++ // XStream
++ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( void )
++ throw( com::sun::star::uno::RuntimeException );
++
++ virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( void )
++ throw( com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes(
+@@ -137,6 +170,35 @@ class NeonInputStream : public ::com::sun::star::io::XInputStream,
+ virtual sal_Int64 SAL_CALL getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
++
++ // XOutputStream
++ virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
++ throw( com::sun::star::io::NotConnectedException,
++ com::sun::star::io::BufferSizeExceededException,
++ com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException);
++
++ virtual void SAL_CALL flush( void )
++ throw( com::sun::star::io::NotConnectedException,
++ com::sun::star::io::BufferSizeExceededException,
++ com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException);
++
++
++ virtual void SAL_CALL closeOutput( void )
++ throw( com::sun::star::io::NotConnectedException,
++ com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException );
++
++ // XTruncate
++ virtual void SAL_CALL truncate( void )
++ throw( com::sun::star::io::IOException,
++ com::sun::star::uno::RuntimeException );
++
++protected:
++
++ // Unlock the stream & destroy the lock
++ void Unlock( void );
+ };
+
+ } // namespace webdav_ucp
+diff --git a/ucb/source/ucp/webdav/NeonSession.cxx b/ucb/source/ucp/webdav/NeonSession.cxx
+index 0fef0bb..f1ddbf0 100644
+--- ucb/source/ucp/webdav/NeonSession.cxx
++++ ucb/source/ucp/webdav/NeonSession.cxx
+@@ -122,6 +122,9 @@
+ #ifndef _SIMPLECERTIFICATIONVALIDATIONREQUEST_HXX_
+ #include "ucbhelper/simplecertificatevalidationrequest.hxx"
+ #endif
++#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
++#include <ucbhelper/cancelcommandexecution.hxx>
++#endif
+
+ #include <cppuhelper/bootstrap.hxx>
+
+@@ -253,12 +256,13 @@ struct NeonRequestContext
+ // -------------------------------------------------------------------
+
+ #if NEON_VERSION >= 0250
+-extern "C" int NeonSession_ResponseBlockReader(void * inUserData,
++extern "C" int
+ #else
+-extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
++extern "C" void
+ #endif
+- const char * inBuf,
+- size_t inLen )
++NeonSession_ResponseBlockReader(void * inUserData,
++ const char * inBuf,
++ size_t inLen )
+ {
+ // neon calls this function with (inLen == 0)...
+ if ( inLen > 0 )
+@@ -283,12 +287,13 @@ extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
+ // -------------------------------------------------------------------
+
+ #if NEON_VERSION >= 0250
+-extern "C" int NeonSession_ResponseBlockWriter( void * inUserData,
++extern "C" int
+ #else
+-extern "C" void NeonSession_ResponseBlockWriter( void * inUserData,
++extern "C" void
+ #endif
+- const char * inBuf,
+- size_t inLen )
++NeonSession_ResponseBlockWriter( void * inUserData,
++ const char * inBuf,
++ size_t inLen )
+ {
+ // neon calls this function with (inLen == 0)...
+ if ( inLen > 0 )
+@@ -646,16 +651,14 @@ NeonSession::~NeonSession( )
+ {
+ if ( m_pHttpSession )
+ {
++ if ( m_NeonLockStore != NULL )
++ {
++ ne_lockstore_destroy( m_NeonLockStore );
++ m_NeonLockStore = NULL;
++ }
++
+ ne_session_destroy( m_pHttpSession );
+ m_pHttpSession = 0;
+- // Note: Uncomment the following if locking support is required
+- /*
+- if ( mNeonLockSession != NULL )
+- {
+- ne_lock_unregister( mNeonLockSession );
+- mNeonLockSession = NULL;
+- }
+- */
+ }
+
+ delete static_cast<RequestDataMap*>(m_pRequestData);
+@@ -797,14 +800,14 @@ void NeonSession::Init()
+ m_nProxyPort );
+ }
+
+- // Note: Uncomment the following if locking support is required
+- /*
+- mNeonLockSession = ne_lock_register( m_pHttpSession );
++ m_NeonLockStore = ne_lockstore_create();
+
+- if ( mNeonLockSession == NULL )
++ if ( m_NeonLockStore == NULL )
+ throw DAVException( DAVException::DAV_SESSION_CREATE,
+- theUri::makeConnectionEndPointString() );
+- */
++ NeonUri::makeConnectionEndPointString( m_aHostName, m_nPort ) );
++
++ // Register the lock store
++ ne_lockstore_register( m_NeonLockStore, m_pHttpSession );
+
+ // Register for redirects.
+ ne_redirect_register( m_pHttpSession );
+@@ -1136,7 +1139,7 @@ void NeonSession::GET( const rtl::OUString & inPath,
+ // -------------------------------------------------------------------
+ // GET
+ // -------------------------------------------------------------------
+-uno::Reference< io::XInputStream >
++uno::Reference< io::XStream >
+ NeonSession::GET( const rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+@@ -1152,8 +1155,8 @@ NeonSession::GET( const rtl::OUString & inPath,
+ ioResource.uri = inPath;
+ ioResource.properties.clear();
+
+- rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
+- NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource );
++ rtl::Reference< NeonInputStream > xStream( new NeonInputStream );
++ NeonRequestContext aCtx( xStream, inHeaderNames, ioResource );
+ int theRetVal = GET( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+@@ -1161,7 +1164,7 @@ NeonSession::GET( const rtl::OUString & inPath,
+ true,
+ &aCtx );
+ HandleError( theRetVal );
+- return uno::Reference< io::XInputStream >( xInputStream.get() );
++ return uno::Reference< io::XStream >( xStream.get() );
+ }
+
+ // -------------------------------------------------------------------
+@@ -1392,9 +1395,7 @@ void NeonSession::DESTROY( const rtl::OUString & inPath,
+ // -------------------------------------------------------------------
+ // LOCK
+ // -------------------------------------------------------------------
+-// Note: Uncomment the following if locking support is required
+-/*
+-void NeonSession::LOCK( const Lock & inLock,
++void NeonSession::LOCK( ucb::Lock & rLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+ {
+@@ -1404,16 +1405,20 @@ void NeonSession::LOCK( const Lock & inLock,
+
+ m_aEnv = rEnv;
+
+- Lockit( inLock, true );
++ if ( !Lockit( rLock, true ) )
++ {
++ ucbhelper::cancelCommandExecution( ucb::IOErrorCode_LOCKING_VIOLATION,
++ uno::Sequence< uno::Any >( 0 ), // FIXME more info about the file?
++ rEnv.m_xEnv,
++ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a locking error occured" ) ),
++ uno::Reference< ucb::XCommandProcessor >() );
++ }
+ }
+-*/
+
+ // -------------------------------------------------------------------
+ // UNLOCK
+ // -------------------------------------------------------------------
+-// Note: Uncomment the following if locking support is required
+-/*
+-void NeonSession::UNLOCK( const Lock & inLock,
++void NeonSession::UNLOCK( ucb::Lock & rLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+ {
+@@ -1423,9 +1428,15 @@ void NeonSession::UNLOCK( const Lock & inLock,
+
+ m_aEnv = rEnv;
+
+- Lockit( inLock, false );
++ if ( !Lockit( rLock, false ) )
++ {
++ ucbhelper::cancelCommandExecution( ucb::IOErrorCode_LOCKING_VIOLATION,
++ uno::Sequence< uno::Any >( 0 ), // FIXME more info about the file?
++ rEnv.m_xEnv,
++ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a locking error occured" ) ),
++ uno::Reference< ucb::XCommandProcessor >() );
++ }
+ }
+-*/
+
+ // -------------------------------------------------------------------
+ const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
+@@ -1521,77 +1532,97 @@ void NeonSession::HandleError( int nError )
+ }
+ }
+
+-// Note: Uncomment the following if locking support is required
+-/*
+-void NeonSession::Lockit( const Lock & inLock, bool inLockit )
++sal_Bool NeonSession::Lockit( ucb::Lock & rLock, bool bLockit )
+ throw ( DAVException )
+ {
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+- // Create the neon lock
+- NeonLock * theLock = new NeonLock;
+- int theRetVal;
++ if ( !m_NeonLockStore )
++ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+- // Set the lock uri
+- NeonUri theUri( inLock.uri );
+- theLock->uri = const_cast< char * >
+- ( rtl::OUStringToOString(
+- theUri.GetPath(), RTL_TEXTENCODING_UTF8 ).getStr() );
++ ne_uri aUri;
++ ne_uri_parse( rtl::OUStringToOString( m_aEnv.m_aRequestURI, RTL_TEXTENCODING_UTF8 ).getStr(),
++ &aUri );
+
+- if ( inLockit )
+- {
+- // Set the lock depth
+- switch( inLock.depth )
+- {
+- case DAVZERO:
+- case DAVINFINITY:
+- theLock->depth = int ( inLock.depth );
+- break;
+- default:
+- throw DAVException( DAVException::DAV_INVALID_ARG );
+- break;
+- }
++ // Create the neon lock
++ NeonLock * theLock = ne_lockstore_findbyuri( m_NeonLockStore, &aUri );
++ if ( !theLock )
++ {
++ theLock = ne_lock_create();
+
+- // Set the lock scope
+- switch ( inLock.scope )
+- {
+- case EXCLUSIVE:
+- theLock->scope = ne_lockscope_exclusive;
+- break;
+- case SHARED:
+- theLock->scope = ne_lockscope_shared;
+- break;
+- default:
+- throw DAVException( DAVException::DAV_INVALID_ARG );
+- break;
+- }
++ // Set the lock uri
++ theLock->uri = aUri;
++
++ // Set the lock depth
++ switch( rLock.Depth )
++ {
++ case ucb::LockDepth_ZERO: theLock->depth = NE_DEPTH_ZERO; break;
++ case ucb::LockDepth_ONE: theLock->depth = NE_DEPTH_ONE; break;
++ case ucb::LockDepth_INFINITY: theLock->depth = NE_DEPTH_INFINITE; break;
++ default:
++ throw DAVException( DAVException::DAV_INVALID_ARG );
++ }
++
++ // Set the lock scope
++ switch ( rLock.Scope )
++ {
++ case ucb::LockScope_EXCLUSIVE: theLock->scope = ne_lockscope_exclusive; break;
++ case ucb::LockScope_SHARED: theLock->scope = ne_lockscope_shared; break;
++ default:
++ throw DAVException( DAVException::DAV_INVALID_ARG );
++ break;
++ }
++
++ // Set the lock owner
++ rtl::OUString aValue;
++ rLock.Owner >>= aValue;
+
+- // Set the lock owner
+- const char * theOwner = rtl::OUStringToOString( inLock.owner,
+- RTL_TEXTENCODING_UTF8 );
+- theLock->owner = const_cast< char * > ( theOwner );
++ theLock->owner = strdup( rtl::OUStringToOString( aValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+- // Set the lock timeout
+- // Note: Neon ignores the timeout
+- //theLock->timeout = inLock.timeout;
++ // Set the lock timeout
++ // Note: Neon ignores the timeout
++ //theLock->timeout = rLock.timeout;
++ theLock->timeout = -1;
+
++ ne_lockstore_add( m_NeonLockStore, theLock );
++ }
++
++ int theRetVal;
++ if ( bLockit )
++ {
+ theRetVal = ne_lock( m_pHttpSession, theLock );
+- }
+- else
+- {
+
+- // Set the lock token
+- rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ];
+- theLock->token = const_cast< char * >
+- ( rtl::OUStringToOString(
+- theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
++ if ( theRetVal != NE_OK )
++ return sal_False;
++
++ uno::Sequence< rtl::OUString > aTokens( 1 );
++ aTokens[0] = rtl::OUString::createFromAscii( theLock->token );
++ rLock.LockTokens = aTokens;
++
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: locked the URL, the token is: %s\n", theLock->token );
++#endif
++ }
++ else
++ {
++ // Set the lock token
++ if ( rLock.LockTokens.getLength() > 0 )
++ {
++ rtl::OUString theToken = rLock.LockTokens.getConstArray()[ 0 ];
++ theLock->token = strdup( rtl::OUStringToOString( theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
++
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: going to unlock the URL, the token is: %s\n", theLock->token );
++#endif
++ }
+
+ theRetVal = ne_unlock( m_pHttpSession, theLock );
+- }
++ }
+
+- HandleError( theRetVal );
++ HandleError( theRetVal );
++
++ return sal_True;
+ }
+-*/
+
+ // -------------------------------------------------------------------
+ namespace {
+diff --git a/ucb/source/ucp/webdav/NeonSession.hxx b/ucb/source/ucp/webdav/NeonSession.hxx
+index 911939f..f35468a 100644
+--- ucb/source/ucp/webdav/NeonSession.hxx
++++ ucb/source/ucp/webdav/NeonSession.hxx
+@@ -84,8 +84,7 @@ class NeonSession : public DAVSession
+ // moment.
+ DAVRequestEnvironment m_aEnv;
+
+- // Note: Uncomment the following if locking support is required
+- // NeonLockSession * mNeonLockSession;
++ NeonLockStore *m_NeonLockStore;
+
+ static bool m_bGlobalsInited;
+
+@@ -156,7 +155,7 @@ class NeonSession : public DAVSession
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference<
+- com::sun::star::io::XInputStream >
++ com::sun::star::io::XStream >
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+@@ -223,16 +222,13 @@ class NeonSession : public DAVSession
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+- // Note: Uncomment the following if locking support is required
+- /*
+- virtual void LOCK (const Lock & inLock,
+- const DAVRequestEnvironment & rEnv )
++ virtual void LOCK ( com::sun::star::ucb::Lock & rLock,
++ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+- virtual void UNLOCK (const Lock & inLock,
+- const DAVRequestEnvironment & rEnv )
++ virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock,
++ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+- */
+
+ // helpers
+ const rtl::OUString & getHostName() const { return m_aHostName; }
+@@ -257,9 +253,8 @@ class NeonSession : public DAVSession
+
+ const ucbhelper::InternetProxyServer & getProxySettings() const;
+
+- // Note: Uncomment the following if locking support is required
+- // void Lockit( const Lock & inLock, bool inLockit )
+- // throw ( DAVException );
++ sal_Bool Lockit( com::sun::star::ucb::Lock & rLock, bool bLockit )
++ throw ( DAVException );
+
+ // low level GET implementation, used by public GET implementations
+ static int GET( ne_session * sess,
+diff --git a/ucb/source/ucp/webdav/NeonTypes.hxx b/ucb/source/ucp/webdav/NeonTypes.hxx
+index 63a8d68..5086f96 100644
+--- ucb/source/ucp/webdav/NeonTypes.hxx
++++ ucb/source/ucp/webdav/NeonTypes.hxx
+@@ -48,6 +48,9 @@
+ #ifndef NE_PROPS_H
+ #include <ne_props.h>
+ #endif
++#ifndef NE_LOCKS_H
++#include <ne_locks.h>
++#endif
+
+ typedef ne_session HttpSession;
+ typedef ne_status HttpStatus;
+@@ -56,4 +59,7 @@ typedef ne_server_capabilities HttpServerCapabilities;
+ typedef ne_propname NeonPropName;
+ typedef ne_prop_result_set NeonPropFindResultSet;
+
++typedef ne_lock_store NeonLockStore;
++typedef struct ne_lock NeonLock;
++
+ #endif // _NEONTYPES_HXX_
+diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx
+index 7b3d7c5..80f752e 100644
+--- ucb/source/ucp/webdav/webdavcontent.cxx
++++ ucb/source/ucp/webdav/webdavcontent.cxx
+@@ -76,6 +76,9 @@
+ #ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
+ #include <com/sun/star/io/XActiveDataSink.hpp>
+ #endif
++#ifndef _COM_SUN_STAR_IO_XACTIVEDATASTREAMER_HPP_
++#include <com/sun/star/io/XActiveDataStreamer.hpp>
++#endif
+ #ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
+ #include <com/sun/star/io/XOutputStream.hpp>
+ #endif
+@@ -190,6 +193,8 @@
+ #include "UCBDeadPropertyValue.hxx"
+ #endif
+
++#include "NeonInputStream.hxx"
++
+ using namespace com::sun::star;
+ using namespace webdav_ucp;
+
+@@ -453,7 +458,8 @@ Content::Content(
+ m_eResourceType( UNKNOWN ),
+ m_pProvider( pProvider ),
+ m_bTransient( sal_False ),
+- m_bCollection( sal_False )
++ m_bCollection( sal_False ),
++ m_bForceReadOnly( sal_False )
+ {
+ try
+ {
+@@ -722,6 +728,11 @@ uno::Any SAL_CALL Content::execute(
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: Execute command '%s'\n",
++ rtl::OUStringToOString( aCommand.Name, RTL_TEXTENCODING_UTF8 ).getStr() );
++#endif
++
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+@@ -1414,16 +1425,29 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ uno::Reference< ucb::XContentIdentifier > xIdentifier;
+ rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
+
+- // webdav does not support active streaming, we can immediately return
+- if ( ( rProperties.getLength() == 1 ) &&
+- rProperties[ 0 ].Name.equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( "SupportsActiveStreaming" ) ) )
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: getPropertyValues: answering the following properties: " );
++ for ( int i = 0; i < rProperties.getLength(); ++i )
++ fprintf( stderr, " %s,",
++ rtl::OUStringToOString( rProperties[i].Name, RTL_TEXTENCODING_UTF8 ).getStr() );
++ fprintf( stderr, "\n" );
++#endif
++
++ // WebDAV supports XActiveDataStreamer
++ // We have to return TRUE on
++ // - SupportsActiveStreaming - always
++ // - IsReadOnly - if we forced read only due to failed locking
++ if ( rProperties.getLength() == 1 )
+ {
+- rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+- = new ::ucbhelper::PropertyValueSet( m_xSMgr );
+- xRow->appendBoolean( rProperties[0], sal_False );
++ if ( rProperties[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SupportsActiveStreaming" ) ) ||
++ ( rProperties[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) && m_bForceReadOnly ) )
++ {
++ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
++ = new ::ucbhelper::PropertyValueSet( m_xSMgr );
++ xRow->appendBoolean( rProperties[0], sal_True );
+
+- return uno::Reference< sdbc::XRow >( xRow.get() );
++ return uno::Reference< sdbc::XRow >( xRow.get() );
++ }
+ }
+
+ {
+@@ -2114,61 +2138,108 @@ uno::Any Content::open(
+ }
+ }
+
+- if ( rArg.Sink.is() )
+- {
+- // Open document.
++ if ( !rArg.Sink.is() )
++ return aRet;
+
+- if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+- ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+- {
+- // Currently(?) unsupported.
+- ucbhelper::cancelCommandExecution(
++ // Open document.
++
++ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
++ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
++ {
++ // Currently(?) unsupported.
++ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedOpenModeException(
+- rtl::OUString(),
+- static_cast< cppu::OWeakObject * >( this ),
+- sal_Int16( rArg.Mode ) ) ),
++ rtl::OUString(),
++ static_cast< cppu::OWeakObject * >( this ),
++ sal_Int16( rArg.Mode ) ) ),
+ xEnv );
++ // Unreachable
++ }
++
++ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
++ uno::Reference< io::XOutputStream > xOut
++ = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
++ if ( xOut.is() )
++ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" );
++#endif
++ // PUSH: write data
++ try
++ {
++ std::auto_ptr< DAVResourceAccess > xResAccess;
++
++ {
++ osl::MutexGuard aGuard( m_aMutex );
++
++ // throw away previously cached headers.
++ m_xCachedProps.reset();
++
++ xResAccess.reset(
++ new DAVResourceAccess( *m_xResAccess.get() ) );
++ }
++
++ DAVResource aResource;
++ std::vector< rtl::OUString > aHeaders;
++ // // Obtain list containing all HTTP headers that can
++ // // be mapped to UCB properties.
++ // ContentProperties::getMappableHTTPHeaders( aHeaders );
++
++ xResAccess->GET( xOut, aHeaders, aResource, xEnv );
++
++ {
++ osl::MutexGuard aGuard( m_aMutex );
++
++ // cache headers.
++ m_xCachedProps.reset( new ContentProperties( aResource ) );
++
++ m_xResAccess.reset(
++ new DAVResourceAccess( *xResAccess.get() ) );
++ }
++ }
++ catch ( DAVException const & e )
++ {
++ cancelCommandExecution( e, xEnv );
+ // Unreachable
+ }
+-
+- rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+- uno::Reference< io::XOutputStream > xOut
+- = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
+- if ( xOut.is() )
++ }
++ else
++ {
++ uno::Reference< io::XActiveDataSink > xDataSink
++ = uno::Reference< io::XActiveDataSink >( rArg.Sink,
++ uno::UNO_QUERY );
++ if ( xDataSink.is() )
+ {
+- // PUSH: write data
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" );
++#endif
++ // PULL: wait for client read
+ try
+ {
+- std::auto_ptr< DAVResourceAccess > xResAccess;
+-
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // throw away previously cached headers.
+ m_xCachedProps.reset();
+-
+- xResAccess.reset(
+- new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+-
++ // fill inputsream sync; return if all data present
+ DAVResource aResource;
+ std::vector< rtl::OUString > aHeaders;
+-// // Obtain list containing all HTTP headers that can
+-// // be mapped to UCB properties.
+-// ContentProperties::getMappableHTTPHeaders( aHeaders );
+-
+- xResAccess->GET( xOut, aHeaders, aResource, xEnv );
++ // // Obtain list containing all HTTP headers that can
++ // // be mapped to UCB properties.
++ // ContentProperties::getMappableHTTPHeaders( aHeaders );
++ uno::Reference< io::XInputStream > xIn
++ = m_xResAccess->GET( aHeaders, aResource, xEnv )->getInputStream();
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+- // cache headers.
+- m_xCachedProps.reset( new ContentProperties( aResource ) );
+-
+- m_xResAccess.reset(
+- new DAVResourceAccess( *xResAccess.get() ) );
++ m_xCachedProps.reset(
++ new ContentProperties( aResource ) );
+ }
++
++ xDataSink->setInputStream( xIn );
+ }
+ catch ( DAVException const & e )
+ {
+@@ -2175,11 +2246,19 @@ uno::Any Content::open(
+ }
+ else
+ {
+- uno::Reference< io::XActiveDataSink > xDataSink
+- = uno::Reference< io::XActiveDataSink >( rArg.Sink,
+- uno::UNO_QUERY );
+- if ( xDataSink.is() )
++ uno::Reference< io::XActiveDataStreamer > xDataStreamer
++ = uno::Reference< io::XActiveDataStreamer >( rArg.Sink,
++ uno::UNO_QUERY );
++ if ( xDataStreamer.is() && !m_bForceReadOnly )
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer\n" );
++#endif
++ // prepare the lock
++ ucb::Lock aLock;
++ aLock.Depth = ucb::LockDepth_ZERO;
++ aLock.Scope = ucb::LockScope_EXCLUSIVE;
++
+ // PULL: wait for client read
+ try
+ {
+@@ -2192,39 +2271,58 @@ uno::Any Content::open(
+ // fill inputsream sync; return if all data present
+ DAVResource aResource;
+ std::vector< rtl::OUString > aHeaders;
+-// // Obtain list containing all HTTP headers that can
+-// // be mapped to UCB properties.
+-// ContentProperties::getMappableHTTPHeaders( aHeaders );
+- uno::Reference< io::XInputStream > xIn
++ // // Obtain list containing all HTTP headers that can
++ // // be mapped to UCB properties.
++ // ContentProperties::getMappableHTTPHeaders( aHeaders );
++
++ // if the locking or the creation of the stream below
++ // fails, we are read only at the next try
++ m_bForceReadOnly = sal_True;
++
++ m_xResAccess->LOCK( aLock, xEnv );
++
++ uno::Reference< io::XStream > xStream
+ = m_xResAccess->GET( aHeaders, aResource, xEnv );
++
++ // pass the lock to the stream
++ static_cast< NeonInputStream* >( xStream.get() )->SetLock( aLock, m_xResAccess->getURL() );
++
++ // everything went well wrt. locking
++ m_bForceReadOnly = sal_False;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ m_xCachedProps.reset(
+- new ContentProperties( aResource ) );
++ new ContentProperties( aResource ) );
+ }
+
+- xDataSink->setInputStream( xIn );
++ xDataStreamer->setStream( xStream );
+ }
+ catch ( DAVException const & e )
+ {
++ m_xResAccess->UNLOCK( aLock, xEnv );
++ m_bForceReadOnly = sal_False;
++
+ cancelCommandExecution( e, xEnv );
+ // Unreachable
+ }
+ }
+ else
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: unsupported rArg.Sink\n" );
++#endif
+ // Note: aOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+ ucbhelper::cancelCommandExecution(
+- uno::makeAny(
+- ucb::UnsupportedDataSinkException(
+- rtl::OUString(),
+- static_cast< cppu::OWeakObject * >( this ),
+- rArg.Sink ) ),
+- xEnv );
++ uno::makeAny(
++ ucb::UnsupportedDataSinkException(
++ rtl::OUString(),
++ static_cast< cppu::OWeakObject * >( this ),
++ rArg.Sink ) ),
++ xEnv );
+ // Unreachable
+ }
+ }
+@@ -2242,6 +2340,9 @@ void Content::post(
+ uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
+ if ( xSink.is() )
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" );
++#endif
+ try
+ {
+ uno::Reference< io::XInputStream > xResult
+@@ -2262,6 +2363,9 @@ void Content::post(
+ uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
+ if ( xResult.is() )
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" );
++#endif
+ try
+ {
+ m_xResAccess->POST( rArg.MediaType,
+@@ -2278,6 +2382,9 @@ void Content::post(
+ }
+ else
+ {
++#if OSL_DEBUG_LEVEL > 0
++ fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer (or something)\n" );
++#endif
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+diff --git a/ucb/source/ucp/webdav/webdavcontent.hxx b/ucb/source/ucp/webdav/webdavcontent.hxx
+index a4589a5..073c57f 100644
+--- ucb/source/ucp/webdav/webdavcontent.hxx
++++ ucb/source/ucp/webdav/webdavcontent.hxx
+@@ -111,6 +111,7 @@ class Content : public ::ucbhelper::ContentImplHelper,
+ ContentProvider* m_pProvider; // No need for a ref, base class holds object
+ sal_Bool m_bTransient;
+ sal_Bool m_bCollection;
++ sal_Bool m_bForceReadOnly;
+
+ private:
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+diff --git a/ucb/source/ucp/webdav/webdavcontentcaps.cxx b/ucb/source/ucp/webdav/webdavcontentcaps.cxx
+index c514903..abf958e 100644
+--- ucb/source/ucp/webdav/webdavcontentcaps.cxx
++++ ucb/source/ucp/webdav/webdavcontentcaps.cxx
+@@ -298,6 +298,24 @@ bool ContentProvider::getProperty(
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ) );
++
++ m_pProps->insert(
++ beans::Property(
++ rtl::OUString(
++ RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" ) ),
++ -1,
++ getCppuBooleanType(),
++ beans::PropertyAttribute::BOUND
++ | beans::PropertyAttribute::READONLY ) );
++
++ m_pProps->insert(
++ beans::Property(
++ rtl::OUString(
++ RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
++ -1,
++ getCppuBooleanType(),
++ beans::PropertyAttribute::BOUND
++ | beans::PropertyAttribute::READONLY ) );
+ }
+ }
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]