Commits

Anonymous committed c4c7352

mav58: #i114699# use system file locking for webdav protocall

Comments (0)

Files changed (2)

sfx2/inc/sfx2/docfile.hxx

     sal_Bool            IsStorage();
 
     sal_Int8            ShowLockedDocumentDialog( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock );
+    sal_Int8            LockIterationImpl( sal_Bool bHandleSysLocked, sal_Bool bUseSystemLock, sal_Bool bLoading, sal_Bool bNoUI );
     sal_Bool            LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI );
     void                UnlockFile( sal_Bool bReleaseLockStream );
 

sfx2/source/doc/docfile.cxx

 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
 #include <com/sun/star/ucb/CommandFailedException.hpp>
 #include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/InteractiveLockingLockedException.hpp>
 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
 #include <com/sun/star/ucb/XContentProvider.hpp>
     sal_Bool bStorageBasedOnInStream: 1;
     sal_Bool m_bSalvageMode: 1;
     sal_Bool m_bVersionsAlreadyLoaded: 1;
-    sal_Bool m_bLocked: 1;
+    sal_Bool m_bOwnLockSet: 1;
+    sal_Bool m_bUCBLockSet: 1;
     sal_Bool m_bGotDateTime: 1;
 
     uno::Reference < embed::XStorage > xStorage;
     bStorageBasedOnInStream( sal_False ),
     m_bSalvageMode( sal_False ),
     m_bVersionsAlreadyLoaded( sal_False ),
-    m_bLocked( sal_False ),
+    m_bOwnLockSet( sal_False ),
+    m_bUCBLockSet( sal_False ),
     m_bGotDateTime( sal_False ),
     pAntiImpl( pAntiImplP ),
     nFileVersion( 0 ),
 }
 
 //------------------------------------------------------------------
+sal_Int8 SfxMedium::LockIterationImpl( sal_Bool bHandleSysLocked, sal_Bool bUseSystemLock, sal_Bool bLoading, sal_Bool bNoUI )
+{
+    sal_Int8 nResult = LOCK_UI_NOLOCK;
+    try
+    {
+        ::svt::DocumentLockFile aLockFile( aLogicName );
+        if ( !bHandleSysLocked )
+        {
+            try
+            {
+                if ( aLockFile.CreateOwnLockFile() )
+                    nResult = LOCK_UI_SUCCEEDED;
+            }
+            catch ( ucb::InteractiveIOException& e )
+            {
+                // exception means that the lock file can not be successfuly accessed
+                // in this case it should be ignored if system file locking is anyway active
+                if ( bUseSystemLock || !IsOOoLockFileUsed() )
+                {
+                    nResult = LOCK_UI_SUCCEEDED;
+                    // take the ownership over the lock file
+                    aLockFile.OverwriteOwnLockFile();
+                }
+                else if ( e.Code == IOErrorCode_INVALID_PARAMETER )
+                {
+                    // system file locking is not active, ask user whether he wants to open the document without any locking
+                    uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
+
+                    if ( xHandler.is() )
+                    {
+                        ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl
+                            = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
+
+                        uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 );
+                        aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() );
+                        aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() );
+                        xIgnoreRequestImpl->setContinuations( aContinuations );
+
+                        xHandler->handle( xIgnoreRequestImpl.get() );
+
+                        ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection();
+                        if (  uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is() )
+                            nResult = LOCK_UI_SUCCEEDED;
+                    }
+                }
+            }
+            catch ( uno::Exception& )
+            {
+                // exception means that the lock file can not be successfuly accessed
+                // in this case it should be ignored if system file locking is anyway active
+                if ( bUseSystemLock || !IsOOoLockFileUsed() )
+                {
+                    nResult = LOCK_UI_SUCCEEDED;
+                    // take the ownership over the lock file
+                    aLockFile.OverwriteOwnLockFile();
+                }
+            }
+
+            // in case OOo locking is turned off the lock file is still written if possible
+            // but it is ignored while deciding whether the document should be opened for editing or not
+            if ( nResult != LOCK_UI_SUCCEEDED && !IsOOoLockFileUsed() )
+            {
+                nResult = LOCK_UI_SUCCEEDED;
+                // take the ownership over the lock file
+                aLockFile.OverwriteOwnLockFile();
+            }
+        }
+
+
+        if ( nResult != LOCK_UI_SUCCEEDED )
+        {
+            uno::Sequence< ::rtl::OUString > aData;
+            try
+            {
+                // impossibility to get data is no real problem
+                aData = aLockFile.GetLockData();
+            }
+            catch( uno::Exception ) {}
+
+            sal_Bool bOwnLock = sal_False;
+
+            if ( !bHandleSysLocked )
+            {
+                uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry();
+                bOwnLock = ( aData.getLength() > LOCKFILE_USERURL_ID
+                          && aOwnData.getLength() > LOCKFILE_USERURL_ID
+                          && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) );
+
+                if ( bOwnLock
+                  && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] )
+                  && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) )
+                {
+                    // this is own lock from the same installation, it could remain because of crash
+                    nResult = LOCK_UI_SUCCEEDED;
+                }
+            }
+
+            if ( nResult != LOCK_UI_SUCCEEDED && !bNoUI )
+            {
+                sal_Int8 nUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock );
+                if ( nUIStatus == LOCK_UI_SUCCEEDED )
+                {
+                    // take the ownership over the lock file
+                    if ( aLockFile.OverwriteOwnLockFile() )
+                        nResult = nUIStatus;
+                }
+                else
+                    nResult = nUIStatus;
+            }
+        }
+    }
+    catch( uno::Exception& )
+    {
+    }
+
+    return nResult;
+}
+
+//------------------------------------------------------------------
 sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI )
 {
     // returns true if the document can be opened for editing ( even if it should be a copy )
     // otherwise the document should be opened readonly
     // if user cancel the loading the ERROR_ABORT is set
 
-    if ( pImp->m_bLocked && bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+    if ( pImp->m_bOwnLockSet && bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
     {
         // if the document is already locked the system locking might be temporarely off after storing
         // check whether the system file locking should be taken again
         GetLockingStream_Impl();
     }
 
-    sal_Bool bResult = pImp->m_bLocked;
+    sal_Bool bResult = pImp->m_bOwnLockSet || pImp->m_bUCBLockSet;
 
     if ( !bResult )
     {
     if ( !bResult && !IsReadOnly() )
     {
         sal_Bool bContentReadonly = sal_False;
+        Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+        ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
+
         if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
         {
             // let the original document be opened to check the possibility to open it for editing
             try
             {
                 // MediaDescriptor does this check also, the duplication should be avoided in future
-                Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
-                ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
                 aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly;
             }
             catch( uno::Exception )
                     GetMedium_Impl();
                 }
 
-                sal_Int8 bUIStatus = LOCK_UI_NOLOCK;
+                sal_Int8 nUIStatus = LOCK_UI_NOLOCK;
 
                 // check whether system file locking has been used, the default value is false
                 sal_Bool bUseSystemLock = IsSystemFileLockingUsed();
 
                 do
                 {
-                    try
-                    {
-                        ::svt::DocumentLockFile aLockFile( aLogicName );
-                        if ( !bHandleSysLocked )
-                        {
-                            try
-                            {
-                                bResult = aLockFile.CreateOwnLockFile();
-                            }
-                            catch ( ucb::InteractiveIOException& e )
-                            {
-                                // exception means that the lock file can not be successfuly accessed
-                                // in this case it should be ignored if system file locking is anyway active
-                                if ( bUseSystemLock || !IsOOoLockFileUsed() )
-                                {
-                                    bResult = sal_True;
-                                    // take the ownership over the lock file
-                                    aLockFile.OverwriteOwnLockFile();
-                                }
-                                else if ( e.Code == IOErrorCode_INVALID_PARAMETER )
-                                {
-                                    // system file locking is not active, ask user whether he wants to open the document without any locking
-                                    uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
-
-                                    if ( xHandler.is() )
-                                    {
-                                        ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl
-                                            = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
-
-                                        uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 );
-                                        aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() );
-                                        aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() );
-                                        xIgnoreRequestImpl->setContinuations( aContinuations );
-
-                                        xHandler->handle( xIgnoreRequestImpl.get() );
-
-                                        ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection();
-                                        bResult = (  uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is() );
-                                    }
-                                }
-                            }
-                            catch ( uno::Exception& )
-                            {
-                                // exception means that the lock file can not be successfuly accessed
-                                // in this case it should be ignored if system file locking is anyway active
-                                if ( bUseSystemLock || !IsOOoLockFileUsed() )
-                                {
-                                    bResult = sal_True;
-                                    // take the ownership over the lock file
-                                    aLockFile.OverwriteOwnLockFile();
-                                }
-                            }
-
-                            // in case OOo locking is turned off the lock file is still written if possible
-                            // but it is ignored while deciding whether the document should be opened for editing or not
-                            if ( !bResult && !IsOOoLockFileUsed() )
-                            {
-                                bResult = sal_True;
-                                // take the ownership over the lock file
-                                aLockFile.OverwriteOwnLockFile();
-                            }
-                        }
-
-
-                        if ( !bResult )
-                        {
-                            uno::Sequence< ::rtl::OUString > aData;
-                            try
-                            {
-                                // impossibility to get data is no real problem
-                                aData = aLockFile.GetLockData();
-                            }
-                            catch( uno::Exception ) {}
-
-                            sal_Bool bOwnLock = sal_False;
-
-                            if ( !bHandleSysLocked )
-                            {
-                                uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry();
-                                bOwnLock = ( aData.getLength() > LOCKFILE_USERURL_ID
-                                          && aOwnData.getLength() > LOCKFILE_USERURL_ID
-                                          && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) );
-
-                                if ( bOwnLock
-                                  && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] )
-                                  && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) )
-                                {
-                                    // this is own lock from the same installation, it could remain because of crash
-                                    bResult = sal_True;
-                                }
-                            }
-
-                            if ( !bResult && !bNoUI )
-                            {
-                                bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock );
-                                if ( bUIStatus == LOCK_UI_SUCCEEDED )
-                                {
-                                    // take the ownership over the lock file
-                                    bResult = aLockFile.OverwriteOwnLockFile();
-                                }
-                            }
-
-                            bHandleSysLocked = sal_False;
-                        }
-                    }
-                    catch( uno::Exception& )
-                    {
-                    }
-                } while( !bResult && bUIStatus == LOCK_UI_TRY );
-
-                pImp->m_bLocked = bResult;
+                    nUIStatus = LockIterationImpl( bHandleSysLocked, bUseSystemLock, bLoading, bNoUI );
+                    bHandleSysLocked = sal_False;
+                } while( !bResult && nUIStatus == LOCK_UI_TRY );
+                
+                if ( nUIStatus == LOCK_UI_SUCCEEDED )
+                    bResult = sal_True;
+
+                pImp->m_bOwnLockSet = bResult;
             }
             else
             {
                 // this is no file URL, check whether the file is readonly
                 bResult = !bContentReadonly;
+                if ( bResult )
+                {
+                    try
+                    {
+                        aContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lock" ) ), uno::Any() );
+                        pImp->m_bUCBLockSet = sal_True;
+                    }
+                    catch( ucb::InteractiveLockingLockedException& )
+                    {
+                        bResult = sal_False;
+                        uno::Sequence< ::rtl::OUString > aData;
+
+                        if ( !bNoUI )
+                        {
+                            sal_Int8 nUIStatus = ShowLockedDocumentDialog( aData, bLoading, sal_False );
+                            bResult = ( nUIStatus == LOCK_UI_SUCCEEDED );
+                        }
+                    }
+                    catch( uno::Exception& )
+                    {}
+                }
             }
         }
     }
         pImp->m_xLockingStream = uno::Reference< io::XStream >();
     }
 
-    if ( pImp->m_bLocked )
+    if ( pImp->m_bOwnLockSet )
     {
         try
         {
-            pImp->m_bLocked = sal_False;
+            pImp->m_bOwnLockSet = sal_False;
             ::svt::DocumentLockFile aLockFile( aLogicName );
             // TODO/LATER: A warning could be shown in case the file is not the own one
             aLockFile.RemoveFile();
         catch( uno::Exception& )
         {}
     }
+
+    if ( pImp->m_bUCBLockSet )
+    {
+        pImp->m_bUCBLockSet = sal_False;
+
+        try
+        {
+            Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+            ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
+            aContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unlock" ) ), uno::Any() );
+        }
+        catch( uno::Exception& )
+        {}
+    }
 }
 
 void SfxMedium::CloseAndReleaseStreams_Impl()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.