LCOV - code coverage report
Current view: top level - svl/source/misc - sharecontrolfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 164 0.0 %
Date: 2012-08-25 Functions: 0 10 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 474 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : #include <stdio.h>
      22                 :            : 
      23                 :            : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      24                 :            : #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
      25                 :            : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      26                 :            : #include <com/sun/star/ucb/XContent.hpp>
      27                 :            : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      28                 :            : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      29                 :            : #include <com/sun/star/io/WrongFormatException.hpp>
      30                 :            : 
      31                 :            : #include <osl/time.h>
      32                 :            : #include <osl/security.hxx>
      33                 :            : #include <osl/socket.hxx>
      34                 :            : 
      35                 :            : #include <rtl/string.hxx>
      36                 :            : #include <rtl/ustring.hxx>
      37                 :            : #include <rtl/strbuf.hxx>
      38                 :            : #include <rtl/ustrbuf.hxx>
      39                 :            : 
      40                 :            : #include <comphelper/processfactory.hxx>
      41                 :            : #include <ucbhelper/content.hxx>
      42                 :            : 
      43                 :            : #include <tools/stream.hxx>
      44                 :            : #include <unotools/bootstrap.hxx>
      45                 :            : #include <unotools/streamwrap.hxx>
      46                 :            : 
      47                 :            : #include <unotools/useroptions.hxx>
      48                 :            : 
      49                 :            : #include <svl/sharecontrolfile.hxx>
      50                 :            : 
      51                 :            : using namespace ::com::sun::star;
      52                 :            : 
      53                 :            : namespace svt {
      54                 :            : 
      55                 :            : // ----------------------------------------------------------------------
      56                 :          0 : ShareControlFile::ShareControlFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
      57 [ #  # ][ #  # ]:          0 : : LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( ".~sharing."  ) )
      58                 :            : {
      59         [ #  # ]:          0 :     OpenStream();
      60                 :            : 
      61         [ #  # ]:          0 :     if ( !IsValid() )
      62         [ #  # ]:          0 :         throw io::NotConnectedException();
      63                 :          0 : }
      64                 :            : 
      65                 :            : // ----------------------------------------------------------------------
      66         [ #  # ]:          0 : ShareControlFile::~ShareControlFile()
      67                 :            : {
      68                 :            :     try
      69                 :            :     {
      70         [ #  # ]:          0 :         Close();
      71                 :            :     }
      72         [ #  # ]:          0 :     catch( uno::Exception& )
      73                 :            :     {}
      74         [ #  # ]:          0 : }
      75                 :            : 
      76                 :            : // ----------------------------------------------------------------------
      77                 :          0 : void ShareControlFile::OpenStream()
      78                 :            : {
      79                 :            :     // if it is called outside of constructor the mutex must be locked already
      80                 :            : 
      81 [ #  # ][ #  # ]:          0 :     if ( !m_xStream.is() && !m_aURL.isEmpty() )
                 [ #  # ]
      82                 :            :     {
      83                 :          0 :         uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
      84         [ #  # ]:          0 :         ::ucbhelper::Content aContent = ::ucbhelper::Content( m_aURL, xDummyEnv );
      85                 :            : 
      86 [ #  # ][ #  # ]:          0 :         uno::Reference< ucb::XContentIdentifier > xContId( aContent.get().is() ? aContent.get()->getIdentifier() : 0 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      87 [ #  # ][ #  # ]:          0 :         if ( !xContId.is() || xContId->getContentProviderScheme() != "file" )
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
      88         [ #  # ]:          0 :             throw io::IOException(); // the implementation supports only local files for now
      89                 :            : 
      90                 :          0 :         uno::Reference< io::XStream > xStream;
      91                 :            : 
      92                 :            :         // Currently the locking of the original document is intended to be used.
      93                 :            :         // That means that the shared file should be accessed only when the original document is locked and only by user who has locked the document.
      94                 :            :         // TODO/LATER: should the own file locking be used?
      95                 :            : 
      96                 :            :         try
      97                 :            :         {
      98 [ #  # ][ #  # ]:          0 :             xStream = aContent.openWriteableStreamNoLock();
      99                 :            :         }
     100   [ #  #  #  # ]:          0 :         catch ( ucb::InteractiveIOException const & e )
     101                 :            :         {
     102         [ #  # ]:          0 :             if ( e.Code == ucb::IOErrorCode_NOT_EXISTING )
     103                 :            :             {
     104                 :            :                 // Create file...
     105         [ #  # ]:          0 :                 SvMemoryStream aStream(0,0);
     106   [ #  #  #  #  :          0 :                 uno::Reference< io::XInputStream > xInput( new ::utl::OInputStreamWrapper( aStream ) );
                   #  # ]
     107         [ #  # ]:          0 :                 ucb::InsertCommandArgument aInsertArg;
     108         [ #  # ]:          0 :                 aInsertArg.Data = xInput;
     109                 :          0 :                 aInsertArg.ReplaceExisting = sal_False;
     110   [ #  #  #  # ]:          0 :                 aContent.executeCommand( rtl::OUString("insert"), uno::makeAny( aInsertArg ) );
     111                 :            : 
     112                 :            :                 // try to let the file be hidden if possible
     113                 :            :                 try {
     114   [ #  #  #  #  :          0 :                     aContent.setPropertyValue( ::rtl::OUString( "IsHidden"  ), uno::makeAny( sal_True ) );
                   #  # ]
     115         [ #  # ]:          0 :                 } catch( uno::Exception& ) {}
     116                 :            : 
     117                 :            :                 // Try to open one more time
     118   [ #  #  #  #  :          0 :                 xStream = aContent.openWriteableStreamNoLock();
             #  #  #  # ]
     119                 :            :             }
     120                 :            :             else
     121                 :          0 :                 throw;
     122                 :            :         }
     123                 :            : 
     124         [ #  # ]:          0 :         m_xSeekable.set( xStream, uno::UNO_QUERY_THROW );
     125 [ #  # ][ #  # ]:          0 :         m_xInputStream.set( xStream->getInputStream(), uno::UNO_QUERY_THROW );
                 [ #  # ]
     126 [ #  # ][ #  # ]:          0 :         m_xOutputStream.set( xStream->getOutputStream(), uno::UNO_QUERY_THROW );
                 [ #  # ]
     127         [ #  # ]:          0 :         m_xTruncate.set( m_xOutputStream, uno::UNO_QUERY_THROW );
     128 [ #  # ][ #  # ]:          0 :         m_xStream = xStream;
     129                 :            :     }
     130                 :          0 : }
     131                 :            : 
     132                 :            : // ----------------------------------------------------------------------
     133                 :          0 : void ShareControlFile::Close()
     134                 :            : {
     135                 :            :     // if it is called outside of destructor the mutex must be locked
     136                 :            : 
     137         [ #  # ]:          0 :     if ( m_xStream.is() )
     138                 :            :     {
     139                 :            :         try
     140                 :            :         {
     141         [ #  # ]:          0 :             if ( m_xInputStream.is() )
     142 [ #  # ][ #  # ]:          0 :                 m_xInputStream->closeInput();
     143         [ #  # ]:          0 :             if ( m_xOutputStream.is() )
     144 [ #  # ][ #  # ]:          0 :                 m_xOutputStream->closeOutput();
     145                 :            :         }
     146                 :          0 :         catch( uno::Exception& )
     147                 :            :         {}
     148                 :            : 
     149         [ #  # ]:          0 :         m_xStream = uno::Reference< io::XStream >();
     150         [ #  # ]:          0 :         m_xInputStream = uno::Reference< io::XInputStream >();
     151         [ #  # ]:          0 :         m_xOutputStream = uno::Reference< io::XOutputStream >();
     152         [ #  # ]:          0 :         m_xSeekable = uno::Reference< io::XSeekable >();
     153         [ #  # ]:          0 :         m_xTruncate = uno::Reference< io::XTruncate >();
     154                 :          0 :         m_aUsersData.realloc( 0 );
     155                 :            :     }
     156         [ #  # ]:          0 : }
     157                 :            : 
     158                 :            : // ----------------------------------------------------------------------
     159                 :          0 : uno::Sequence< uno::Sequence< ::rtl::OUString > > ShareControlFile::GetUsersData()
     160                 :            : {
     161         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     162                 :            : 
     163         [ #  # ]:          0 :     if ( !IsValid() )
     164         [ #  # ]:          0 :         throw io::NotConnectedException();
     165                 :            : 
     166         [ #  # ]:          0 :     if ( !m_aUsersData.getLength() )
     167                 :            :     {
     168 [ #  # ][ #  # ]:          0 :         sal_Int64 nLength = m_xSeekable->getLength();
     169         [ #  # ]:          0 :         if ( nLength > SAL_MAX_INT32 )
     170         [ #  # ]:          0 :             throw uno::RuntimeException();
     171                 :            : 
     172         [ #  # ]:          0 :         uno::Sequence< sal_Int8 > aBuffer( (sal_Int32)nLength );
     173 [ #  # ][ #  # ]:          0 :         m_xSeekable->seek( 0 );
     174                 :            : 
     175 [ #  # ][ #  # ]:          0 :         sal_Int32 nRead = m_xInputStream->readBytes( aBuffer, (sal_Int32)nLength );
     176                 :          0 :         nLength -= nRead;
     177         [ #  # ]:          0 :         while ( nLength > 0 )
     178                 :            :         {
     179         [ #  # ]:          0 :             uno::Sequence< sal_Int8 > aTmpBuf( (sal_Int32)nLength );
     180 [ #  # ][ #  # ]:          0 :             nRead = m_xInputStream->readBytes( aTmpBuf, (sal_Int32)nLength );
     181         [ #  # ]:          0 :             if ( nRead > nLength )
     182         [ #  # ]:          0 :                 throw uno::RuntimeException();
     183                 :            : 
     184         [ #  # ]:          0 :             for ( sal_Int32 nInd = 0; nInd < nRead; nInd++ )
     185 [ #  # ][ #  # ]:          0 :                 aBuffer[aBuffer.getLength() - (sal_Int32)nLength + nInd] = aTmpBuf[nInd];
     186                 :          0 :             nLength -= nRead;
     187         [ #  # ]:          0 :         }
     188                 :            : 
     189 [ #  # ][ #  # ]:          0 :         m_aUsersData = ParseList( aBuffer );
         [ #  # ][ #  # ]
     190                 :            :     }
     191                 :            : 
     192 [ #  # ][ #  # ]:          0 :     return m_aUsersData;
     193                 :            : }
     194                 :            : 
     195                 :            : // ----------------------------------------------------------------------
     196                 :          0 : void ShareControlFile::SetUsersDataAndStore( const uno::Sequence< uno::Sequence< ::rtl::OUString > >& aUsersData )
     197                 :            : {
     198         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     199                 :            : 
     200         [ #  # ]:          0 :     if ( !IsValid() )
     201         [ #  # ]:          0 :         throw io::NotConnectedException();
     202                 :            : 
     203 [ #  # ][ #  # ]:          0 :     if ( !m_xTruncate.is() || !m_xOutputStream.is() || !m_xSeekable.is() )
         [ #  # ][ #  # ]
     204         [ #  # ]:          0 :         throw uno::RuntimeException();
     205                 :            : 
     206 [ #  # ][ #  # ]:          0 :     m_xTruncate->truncate();
     207 [ #  # ][ #  # ]:          0 :     m_xSeekable->seek( 0 );
     208                 :            : 
     209                 :          0 :     ::rtl::OUStringBuffer aBuffer;
     210         [ #  # ]:          0 :     for ( sal_Int32 nInd = 0; nInd < aUsersData.getLength(); nInd++ )
     211                 :            :     {
     212         [ #  # ]:          0 :         if ( aUsersData[nInd].getLength() != SHARED_ENTRYSIZE )
     213         [ #  # ]:          0 :             throw lang::IllegalArgumentException();
     214                 :            : 
     215         [ #  # ]:          0 :         for ( sal_Int32 nEntryInd = 0; nEntryInd < SHARED_ENTRYSIZE; nEntryInd++ )
     216                 :            :         {
     217 [ #  # ][ #  # ]:          0 :             aBuffer.append( EscapeCharacters( aUsersData[nInd][nEntryInd] ) );
     218         [ #  # ]:          0 :             if ( nEntryInd < SHARED_ENTRYSIZE - 1 )
     219         [ #  # ]:          0 :                 aBuffer.append( (sal_Unicode)',' );
     220                 :            :             else
     221         [ #  # ]:          0 :                 aBuffer.append( (sal_Unicode)';' );
     222                 :            :         }
     223                 :            :     }
     224                 :            : 
     225 [ #  # ][ #  # ]:          0 :     ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) );
     226         [ #  # ]:          0 :     uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() );
     227 [ #  # ][ #  # ]:          0 :     m_xOutputStream->writeBytes( aData );
     228 [ #  # ][ #  # ]:          0 :     m_aUsersData = aUsersData;
                 [ #  # ]
     229                 :          0 : }
     230                 :            : 
     231                 :            : // ----------------------------------------------------------------------
     232                 :          0 : uno::Sequence< ::rtl::OUString > ShareControlFile::InsertOwnEntry()
     233                 :            : {
     234         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     235                 :            : 
     236         [ #  # ]:          0 :     if ( !IsValid() )
     237         [ #  # ]:          0 :         throw io::NotConnectedException();
     238                 :            : 
     239 [ #  # ][ #  # ]:          0 :     GetUsersData();
     240         [ #  # ]:          0 :     uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 );
     241         [ #  # ]:          0 :     uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
     242                 :            : 
     243                 :          0 :     sal_Bool bExists = sal_False;
     244                 :          0 :     sal_Int32 nNewInd = 0;
     245         [ #  # ]:          0 :     for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ )
     246                 :            :     {
     247 [ #  # ][ #  # ]:          0 :         if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE )
     248                 :            :         {
     249 [ #  # ][ #  # ]:          0 :             if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aNewEntry[SHARED_LOCALHOST_ID]
         [ #  # ][ #  #  
             #  #  #  # ]
                 [ #  # ]
     250 [ #  # ][ #  # ]:          0 :               && m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aNewEntry[SHARED_SYSUSERNAME_ID]
                 [ #  # ]
     251 [ #  # ][ #  # ]:          0 :               && m_aUsersData[nInd][SHARED_USERURL_ID] == aNewEntry[SHARED_USERURL_ID] )
                 [ #  # ]
     252                 :            :             {
     253         [ #  # ]:          0 :                 if ( !bExists )
     254                 :            :                 {
     255 [ #  # ][ #  # ]:          0 :                     aNewData[nNewInd] = aNewEntry;
     256                 :          0 :                     bExists = sal_True;
     257                 :            :                 }
     258                 :            :             }
     259                 :            :             else
     260                 :            :             {
     261 [ #  # ][ #  # ]:          0 :                 aNewData[nNewInd] = m_aUsersData[nInd];
                 [ #  # ]
     262                 :            :             }
     263                 :            : 
     264                 :          0 :             nNewInd++;
     265                 :            :         }
     266                 :            :     }
     267                 :            : 
     268         [ #  # ]:          0 :     if ( !bExists )
     269 [ #  # ][ #  # ]:          0 :         aNewData[nNewInd++] = aNewEntry;
     270                 :            : 
     271         [ #  # ]:          0 :     aNewData.realloc( nNewInd );
     272         [ #  # ]:          0 :     SetUsersDataAndStore( aNewData );
     273                 :            : 
     274 [ #  # ][ #  # ]:          0 :     return aNewEntry;
     275                 :            : }
     276                 :            : 
     277                 :            : // ----------------------------------------------------------------------
     278                 :          0 : bool ShareControlFile::HasOwnEntry()
     279                 :            : {
     280         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     281                 :            : 
     282         [ #  # ]:          0 :     if ( !IsValid() )
     283                 :            :     {
     284         [ #  # ]:          0 :         throw io::NotConnectedException();
     285                 :            :     }
     286                 :            : 
     287 [ #  # ][ #  # ]:          0 :     GetUsersData();
     288         [ #  # ]:          0 :     uno::Sequence< ::rtl::OUString > aEntry = GenerateOwnEntry();
     289                 :            : 
     290         [ #  # ]:          0 :     for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); ++nInd )
     291                 :            :     {
     292 [ #  # ][ #  #  :          0 :         if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE &&
          #  #  #  #  #  
              # ][ #  # ]
     293 [ #  # ][ #  # ]:          0 :              m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aEntry[SHARED_LOCALHOST_ID] &&
                 [ #  # ]
     294 [ #  # ][ #  # ]:          0 :              m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aEntry[SHARED_SYSUSERNAME_ID] &&
                 [ #  # ]
     295 [ #  # ][ #  # ]:          0 :              m_aUsersData[nInd][SHARED_USERURL_ID] == aEntry[SHARED_USERURL_ID] )
                 [ #  # ]
     296                 :            :         {
     297                 :          0 :             return true;
     298                 :            :         }
     299                 :            :     }
     300                 :            : 
     301 [ #  # ][ #  # ]:          0 :     return false;
     302                 :            : }
     303                 :            : 
     304                 :            : // ----------------------------------------------------------------------
     305                 :          0 : void ShareControlFile::RemoveEntry( const uno::Sequence< ::rtl::OUString >& aArgEntry )
     306                 :            : {
     307         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     308                 :            : 
     309         [ #  # ]:          0 :     if ( !IsValid() )
     310         [ #  # ]:          0 :         throw io::NotConnectedException();
     311                 :            : 
     312 [ #  # ][ #  # ]:          0 :     GetUsersData();
     313                 :            : 
     314         [ #  # ]:          0 :     uno::Sequence< ::rtl::OUString > aEntry = aArgEntry;
     315         [ #  # ]:          0 :     if ( aEntry.getLength() != SHARED_ENTRYSIZE )
     316 [ #  # ][ #  # ]:          0 :         aEntry = GenerateOwnEntry();
                 [ #  # ]
     317                 :            : 
     318         [ #  # ]:          0 :     uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 );
     319                 :            : 
     320                 :          0 :     sal_Int32 nNewInd = 0;
     321         [ #  # ]:          0 :     for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ )
     322                 :            :     {
     323 [ #  # ][ #  # ]:          0 :         if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE )
     324                 :            :         {
     325 [ #  # ][ #  # ]:          0 :             if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] != aEntry[SHARED_LOCALHOST_ID]
         [ #  # ][ #  #  
             #  #  #  # ]
                 [ #  # ]
     326 [ #  # ][ #  # ]:          0 :               || m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] != aEntry[SHARED_SYSUSERNAME_ID]
                 [ #  # ]
     327 [ #  # ][ #  # ]:          0 :               || m_aUsersData[nInd][SHARED_USERURL_ID] != aEntry[SHARED_USERURL_ID] )
                 [ #  # ]
     328                 :            :             {
     329 [ #  # ][ #  # ]:          0 :                 aNewData[nNewInd] = m_aUsersData[nInd];
                 [ #  # ]
     330                 :          0 :                 nNewInd++;
     331                 :            :             }
     332                 :            :         }
     333                 :            :     }
     334                 :            : 
     335         [ #  # ]:          0 :     aNewData.realloc( nNewInd );
     336         [ #  # ]:          0 :     SetUsersDataAndStore( aNewData );
     337                 :            : 
     338         [ #  # ]:          0 :     if ( !nNewInd )
     339                 :            :     {
     340                 :            :         // try to remove the file if it is empty
     341         [ #  # ]:          0 :         RemoveFile();
     342 [ #  # ][ #  # ]:          0 :     }
                 [ #  # ]
     343                 :          0 : }
     344                 :            : 
     345                 :            : // ----------------------------------------------------------------------
     346                 :          0 : void ShareControlFile::RemoveFile()
     347                 :            : {
     348         [ #  # ]:          0 :     ::osl::MutexGuard aGuard( m_aMutex );
     349                 :            : 
     350         [ #  # ]:          0 :     if ( !IsValid() )
     351         [ #  # ]:          0 :         throw io::NotConnectedException();
     352                 :            : 
     353         [ #  # ]:          0 :     Close();
     354                 :            : 
     355 [ #  # ][ #  # ]:          0 :     uno::Reference<ucb::XSimpleFileAccess2> xSimpleFileAccess(ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()));
     356 [ #  # ][ #  # ]:          0 :     xSimpleFileAccess->kill( m_aURL );
                 [ #  # ]
     357                 :          0 : }
     358                 :            : 
     359                 :            : } // namespace svt
     360                 :            : 
     361                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10