LCOV - code coverage report
Current view: top level - svx/source/xml - xmleohlp.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 196 327 59.9 %
Date: 2015-06-13 12:38:46 Functions: 24 30 80.0 %
Legend: Lines: hit not hit

          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             : #include <com/sun/star/io/XStream.hpp>
      23             : #include <com/sun/star/beans/XPropertySet.hpp>
      24             : #include <com/sun/star/embed/XTransactedObject.hpp>
      25             : #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
      26             : #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
      27             : #include <com/sun/star/embed/ElementModes.hpp>
      28             : #include <com/sun/star/embed/XEmbeddedObject.hpp>
      29             : #include <com/sun/star/embed/XEmbedPersist.hpp>
      30             : #include <com/sun/star/embed/EntryInitModes.hpp>
      31             : #include <com/sun/star/embed/EmbedStates.hpp>
      32             : #include <com/sun/star/embed/Aspects.hpp>
      33             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      34             : #include <sot/storage.hxx>
      35             : #include <tools/debug.hxx>
      36             : #include <unotools/streamwrap.hxx>
      37             : #include <unotools/tempfile.hxx>
      38             : 
      39             : #include <svtools/embedhlp.hxx>
      40             : #include <unotools/ucbstreamhelper.hxx>
      41             : #include <comphelper/processfactory.hxx>
      42             : #include <comphelper/storagehelper.hxx>
      43             : #include <comphelper/embeddedobjectcontainer.hxx>
      44             : 
      45             : #include <comphelper/classids.hxx>
      46             : #include <map>
      47             : #include "svx/xmleohlp.hxx"
      48             : #include <boost/scoped_ptr.hpp>
      49             : 
      50             : using namespace ::osl;
      51             : using namespace ::cppu;
      52             : using namespace ::utl;
      53             : using namespace ::com::sun::star;
      54             : using namespace ::com::sun::star::document;
      55             : using namespace ::com::sun::star::uno;
      56             : using namespace ::com::sun::star::container;
      57             : using namespace ::com::sun::star::io;
      58             : using namespace ::com::sun::star::lang;
      59             : 
      60             : #define XML_CONTAINERSTORAGE_NAME_60        "Pictures"
      61             : #define XML_CONTAINERSTORAGE_NAME       "ObjectReplacements"
      62             : #define XML_EMBEDDEDOBJECT_URL_BASE     "vnd.sun.star.EmbeddedObject:"
      63             : #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE      "vnd.sun.star.GraphicObject:"
      64             : 
      65             : 
      66             : 
      67             : class OutputStorageWrapper_Impl : public ::cppu::WeakImplHelper1<XOutputStream>
      68             : {
      69             :     ::osl::Mutex    maMutex;
      70             :     Reference < XOutputStream > xOut;
      71             :     TempFile aTempFile;
      72             :     bool bStreamClosed : 1;
      73             :     SvStream* pStream;
      74             : 
      75             : public:
      76             :     OutputStorageWrapper_Impl();
      77             :     virtual ~OutputStorageWrapper_Impl();
      78             : 
      79             : // css::io::XOutputStream
      80             :     virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
      81             :     virtual void SAL_CALL flush() throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
      82             :     virtual void SAL_CALL closeOutput() throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
      83             : 
      84             :     SvStream*   GetStream();
      85             : };
      86             : 
      87          59 : OutputStorageWrapper_Impl::OutputStorageWrapper_Impl()
      88             :     : bStreamClosed( false )
      89          59 :     , pStream(0)
      90             : {
      91          59 :     aTempFile.EnableKillingFile();
      92          59 :     pStream = aTempFile.GetStream( STREAM_READWRITE );
      93          59 :     xOut = new OOutputStreamWrapper( *pStream );
      94          59 : }
      95             : 
      96         118 : OutputStorageWrapper_Impl::~OutputStorageWrapper_Impl()
      97             : {
      98         118 : }
      99             : 
     100          59 : SvStream *OutputStorageWrapper_Impl::GetStream()
     101             : {
     102          59 :     if( bStreamClosed )
     103          59 :         return pStream;
     104           0 :     return NULL;
     105             : }
     106             : 
     107         472 : void SAL_CALL OutputStorageWrapper_Impl::writeBytes(
     108             :         const Sequence< sal_Int8 >& aData)
     109             :     throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception)
     110             : {
     111         472 :     MutexGuard          aGuard( maMutex );
     112         472 :     xOut->writeBytes( aData );
     113         472 : }
     114             : 
     115           0 : void SAL_CALL OutputStorageWrapper_Impl::flush()
     116             :     throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception)
     117             : {
     118           0 :     MutexGuard          aGuard( maMutex );
     119           0 :     xOut->flush();
     120           0 : }
     121             : 
     122          59 : void SAL_CALL OutputStorageWrapper_Impl::closeOutput()
     123             :     throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception)
     124             : {
     125          59 :     MutexGuard          aGuard( maMutex );
     126          59 :     xOut->closeOutput();
     127          59 :     bStreamClosed = true;
     128          59 : }
     129             : 
     130             : struct OUStringLess
     131             : {
     132         118 :     bool operator() ( const OUString& r1, const OUString& r2 ) const
     133             :     {
     134         118 :         return r1 < r2;
     135             :     }
     136             : };
     137             : 
     138         754 : SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper() :
     139             :     WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
     140             :     maReplacementGraphicsContainerStorageName( XML_CONTAINERSTORAGE_NAME ),
     141             :     maReplacementGraphicsContainerStorageName60( XML_CONTAINERSTORAGE_NAME_60 ),
     142             :     mpDocPersist( 0 ),
     143             :     meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
     144         754 :     mpStreamMap( 0 )
     145             : {
     146         754 : }
     147             : 
     148         875 : SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper( ::comphelper::IEmbeddedHelper& rDocPersist, SvXMLEmbeddedObjectHelperMode eCreateMode ) :
     149             :     WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
     150             :     maReplacementGraphicsContainerStorageName( XML_CONTAINERSTORAGE_NAME ),
     151             :     maReplacementGraphicsContainerStorageName60( XML_CONTAINERSTORAGE_NAME_60 ),
     152             :     mpDocPersist( 0 ),
     153             :     meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
     154         875 :     mpStreamMap( 0 )
     155             : {
     156         875 :     Init( 0, rDocPersist, eCreateMode );
     157         875 : }
     158             : 
     159        4887 : SvXMLEmbeddedObjectHelper::~SvXMLEmbeddedObjectHelper()
     160             : {
     161        1629 :     if( mpStreamMap )
     162             :     {
     163          58 :         SvXMLEmbeddedObjectHelper_Impl::iterator aIter = mpStreamMap->begin();
     164          58 :         SvXMLEmbeddedObjectHelper_Impl::iterator aEnd = mpStreamMap->end();
     165          58 :         for( ; aIter != aEnd; ++aIter )
     166             :         {
     167           0 :             if( aIter->second )
     168             :             {
     169           0 :                 aIter->second->release();
     170           0 :                 aIter->second = 0;
     171             :             }
     172             :         }
     173          58 :         delete mpStreamMap;
     174             :     }
     175        3258 : }
     176             : 
     177        1629 : void SAL_CALL SvXMLEmbeddedObjectHelper::disposing()
     178             : {
     179        1629 :     Flush();
     180        1629 : }
     181             : 
     182         353 : void SvXMLEmbeddedObjectHelper::splitObjectURL(const OUString& _aURLNoPar,
     183             :     OUString& rContainerStorageName,
     184             :     OUString& rObjectStorageName)
     185             : {
     186             :     DBG_ASSERT(_aURLNoPar.isEmpty() || '#' != _aURLNoPar[0], "invalid object URL" );
     187         353 :     OUString aURLNoPar = _aURLNoPar;
     188             : 
     189         353 :     sal_Int32 _nPos = aURLNoPar.lastIndexOf( '/' );
     190         353 :     if( -1 == _nPos )
     191             :     {
     192          59 :         rContainerStorageName.clear();
     193          59 :         rObjectStorageName = aURLNoPar;
     194             :     }
     195             :     else
     196             :     {
     197             :         //eliminate 'superfluous' slashes at start and end
     198             :         //#i103076# load objects with all allowed xlink:href syntaxes
     199             :         {
     200             :             //eliminate './' at start
     201         294 :             sal_Int32 nStart = 0;
     202         294 :             sal_Int32 nCount = aURLNoPar.getLength();
     203         294 :             if( aURLNoPar.startsWith( "./" ) )
     204             :             {
     205          53 :                 nStart = 2;
     206          53 :                 nCount -= 2;
     207             :             }
     208             : 
     209             :             //eliminate '/' at end
     210         294 :             sal_Int32 nEnd = aURLNoPar.lastIndexOf( '/' );
     211         294 :             if( nEnd == aURLNoPar.getLength()-1 && nEnd != (nStart-1) )
     212           0 :                 nCount--;
     213             : 
     214         294 :             aURLNoPar = aURLNoPar.copy( nStart, nCount );
     215             :         }
     216             : 
     217         294 :         _nPos = aURLNoPar.lastIndexOf( '/' );
     218         294 :         if( _nPos >= 0 )
     219         241 :             rContainerStorageName = aURLNoPar.copy( 0, _nPos );
     220         294 :         rObjectStorageName = aURLNoPar.copy( _nPos+1 );
     221         353 :     }
     222         353 : }
     223             : 
     224         138 : bool SvXMLEmbeddedObjectHelper::ImplGetStorageNames(
     225             :         const OUString& rURLStr,
     226             :         OUString& rContainerStorageName,
     227             :         OUString& rObjectStorageName,
     228             :         bool bInternalToExternal,
     229             :         bool *pGraphicRepl,
     230             :         bool *pOasisFormat ) const
     231             : {
     232             :     // internal URL: vnd.sun.star.EmbeddedObject:<object-name>
     233             :     //           or: vnd.sun.star.EmbeddedObject:<path>/<object-name>
     234             :     // internal replacement images:
     235             :     //               vnd.sun.star.EmbeddedObjectGraphic:<object-name>
     236             :     //           or: vnd.sun.star.EmbeddedObjectGraphic:<path>/<object-name>
     237             :     // external URL: ./<path>/<object-name>
     238             :     //           or: <path>/<object-name>
     239             :     //           or: <object-name>
     240             :     // currently, path may only consist of a single directory name
     241             :     // it is also possible to have additional arguments at the end of URL: <main URL>[?<name>=<value>[,<name>=<value>]*]
     242             : 
     243         138 :     if( pGraphicRepl )
     244           0 :         *pGraphicRepl = false;
     245             : 
     246         138 :     if( pOasisFormat )
     247           0 :         *pOasisFormat = true; // the default value
     248             : 
     249         138 :     if( rURLStr.isEmpty() )
     250           0 :         return false;
     251             : 
     252             :     // get rid of arguments
     253         138 :     sal_Int32 nPos = rURLStr.indexOf( '?' );
     254         138 :     OUString aURLNoPar;
     255         138 :     if ( nPos == -1 )
     256         138 :         aURLNoPar = rURLStr;
     257             :     else
     258             :     {
     259           0 :         aURLNoPar = rURLStr.copy( 0, nPos );
     260             : 
     261             :         // check the arguments
     262           0 :         nPos++;
     263           0 :         while( nPos >= 0 && nPos < rURLStr.getLength() )
     264             :         {
     265           0 :             OUString aToken = rURLStr.getToken( 0, ',', nPos );
     266           0 :             if ( aToken.equalsIgnoreAsciiCase( "oasis=false" ) )
     267             :             {
     268           0 :                 if ( pOasisFormat )
     269           0 :                     *pOasisFormat = false;
     270           0 :                 break;
     271             :             }
     272             :             else
     273             :             {
     274             :                 DBG_ASSERT( false, "invalid arguments was found in URL!" );
     275             :             }
     276           0 :         }
     277             :     }
     278             : 
     279         138 :     if( bInternalToExternal )
     280             :     {
     281          26 :         nPos = aURLNoPar.indexOf( ':' );
     282          26 :         if( -1 == nPos )
     283           0 :             return false;
     284          26 :         bool bObjUrl = aURLNoPar.startsWith( XML_EMBEDDEDOBJECT_URL_BASE );
     285          39 :         bool bGrUrl = !bObjUrl &&
     286          39 :               aURLNoPar.startsWith( XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE );
     287          26 :         if( !(bObjUrl || bGrUrl) )
     288           0 :             return false;
     289             : 
     290          26 :         sal_Int32 nPathStart = nPos + 1;
     291          26 :         nPos = aURLNoPar.lastIndexOf( '/' );
     292          26 :         if( -1 == nPos )
     293             :         {
     294          26 :             rContainerStorageName.clear();
     295          26 :             rObjectStorageName = aURLNoPar.copy( nPathStart );
     296             :         }
     297           0 :         else if( nPos > nPathStart )
     298             :         {
     299           0 :             rContainerStorageName = aURLNoPar.copy( nPathStart, nPos-nPathStart);
     300           0 :             rObjectStorageName = aURLNoPar.copy( nPos+1 );
     301             :         }
     302             :         else
     303           0 :             return false;
     304             : 
     305          26 :         if( bGrUrl )
     306             :         {
     307          26 :             bool bOASIS = mxRootStorage.is() &&
     308          26 :                 ( SotStorage::GetVersion( mxRootStorage ) > SOFFICE_FILEFORMAT_60 );
     309          13 :             rContainerStorageName = bOASIS
     310             :                     ? maReplacementGraphicsContainerStorageName
     311          13 :                     : maReplacementGraphicsContainerStorageName60;
     312             : 
     313          13 :             if( pGraphicRepl )
     314           0 :                 *pGraphicRepl = true;
     315             :         }
     316             : 
     317             : 
     318             :     }
     319             :     else
     320             :     {
     321         112 :         splitObjectURL(aURLNoPar, rContainerStorageName, rObjectStorageName);
     322             :     }
     323             : 
     324         138 :     if( -1 != rContainerStorageName.indexOf( '/' ) )
     325             :     {
     326             :         OSL_FAIL( "SvXMLEmbeddedObjectHelper: invalid path name" );
     327           0 :         return false;
     328             :     }
     329             : 
     330         138 :     return true;
     331             : }
     332             : 
     333         112 : uno::Reference < embed::XStorage > SvXMLEmbeddedObjectHelper::ImplGetContainerStorage(
     334             :         const OUString& rStorageName )
     335             : {
     336             :     DBG_ASSERT( -1 == rStorageName.indexOf( '/' ) &&
     337             :                 -1 == rStorageName.indexOf( '\\' ),
     338             :                 "nested embedded storages aren't supported" );
     339         131 :     if( !mxContainerStorage.is() ||
     340          19 :         ( rStorageName != maCurContainerStorageName ) )
     341             :     {
     342         186 :         if( mxContainerStorage.is() &&
     343          93 :             !maCurContainerStorageName.isEmpty() &&
     344           0 :             EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode )
     345             :         {
     346           0 :             uno::Reference < embed::XTransactedObject > xTrans( mxContainerStorage, uno::UNO_QUERY );
     347           0 :             if ( xTrans.is() )
     348           0 :                 xTrans->commit();
     349             :         }
     350             : 
     351          93 :         if( !rStorageName.isEmpty() && mxRootStorage.is() )
     352             :         {
     353           0 :             sal_Int32 nMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode
     354             :                                     ? ::embed::ElementModes::READWRITE
     355           0 :                                     : ::embed::ElementModes::READ;
     356           0 :             mxContainerStorage = mxRootStorage->openStorageElement( rStorageName,
     357           0 :                                                              nMode );
     358             :         }
     359             :         else
     360             :         {
     361          93 :             mxContainerStorage = mxRootStorage;
     362             :         }
     363          93 :         maCurContainerStorageName = rStorageName;
     364             :     }
     365             : 
     366         112 :     return mxContainerStorage;
     367             : }
     368             : 
     369         112 : bool SvXMLEmbeddedObjectHelper::ImplReadObject(
     370             :         const OUString& rContainerStorageName,
     371             :         OUString& rObjName,
     372             :         const SvGlobalName *pClassId,
     373             :         SvStream* pTemp )
     374             : {
     375             :     (void)pClassId;
     376             : 
     377         112 :     uno::Reference < embed::XStorage > xDocStor( mpDocPersist->getStorage() );
     378         224 :     uno::Reference < embed::XStorage > xCntnrStor( ImplGetContainerStorage( rContainerStorageName ) );
     379             : 
     380         112 :     if( !xCntnrStor.is() && !pTemp )
     381           0 :         return false;
     382             : 
     383         224 :     OUString aSrcObjName( rObjName );
     384         112 :     comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
     385             : 
     386             :     // Is the object name unique?
     387             :     // if the object is already instantiated by GetEmbeddedObject
     388             :     // that means that the duplication is being loaded
     389         112 :     bool bDuplicate = rContainer.HasInstantiatedEmbeddedObject( rObjName );
     390             :     DBG_ASSERT( !bDuplicate, "An object in the document is referenced twice!" );
     391             : 
     392         112 :     if( xDocStor != xCntnrStor || pTemp || bDuplicate )
     393             :     {
     394             :         // TODO/LATER: make this altogether a method in the EmbeddedObjectContainer
     395             : 
     396             :         // create a unique name for the duplicate object
     397          63 :         if( bDuplicate )
     398           0 :             rObjName = rContainer.CreateUniqueObjectName();
     399             : 
     400          63 :         if( pTemp )
     401             :         {
     402             :             try
     403             :             {
     404          59 :                 pTemp->Seek( 0 );
     405          59 :                 uno::Reference < io::XStream > xStm = xDocStor->openStreamElement( rObjName,
     406          59 :                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
     407         118 :                 boost::scoped_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( xStm ));
     408          59 :                 pTemp->ReadStream( *pStream );
     409          59 :                 pStream.reset();
     410             : 
     411             :                 // TODO/LATER: what to do when other types of objects are based on substream persistence?
     412             :                 // This is an ole object
     413         118 :                 uno::Reference< beans::XPropertySet > xProps( xStm, uno::UNO_QUERY_THROW );
     414          59 :                 xProps->setPropertyValue(
     415             :                     OUString( "MediaType" ),
     416          59 :                     uno::makeAny( OUString( "application/vnd.sun.star.oleobject" ) ) );
     417             : 
     418         118 :                 xStm->getOutputStream()->closeOutput();
     419             :             }
     420           0 :             catch ( uno::Exception& )
     421             :             {
     422           0 :                 return false;
     423             :             }
     424             :         }
     425             :         else
     426             :         {
     427             :             try
     428             :             {
     429           4 :                 xCntnrStor->copyElementTo( aSrcObjName, xDocStor, rObjName );
     430             :             }
     431           2 :             catch ( uno::Exception& )
     432             :             {
     433           1 :                 return false;
     434             :             }
     435             :         }
     436             :     }
     437             : 
     438             :     // make object known to the container
     439             :     // TODO/LATER: could be done a little bit more efficient!
     440         222 :     OUString aName( rObjName );
     441             : 
     442             :     // TODO/LATER: The provided pClassId is ignored for now.
     443             :     //             The stream contains OLE storage internally and this storage already has a class id specifying the
     444             :     //             server that was used to create the object. pClassId could be used to specify the server that should
     445             :     //             be used for the next opening, but this information seems to be out of the file format responsibility
     446             :     //             area.
     447         111 :     rContainer.GetEmbeddedObject( aName );
     448             : 
     449         223 :     return true;
     450             : }
     451             : 
     452         138 : OUString SvXMLEmbeddedObjectHelper::ImplInsertEmbeddedObjectURL(
     453             :         const OUString& rURLStr )
     454             : {
     455         138 :     OUString sRetURL;
     456             : 
     457         276 :     OUString aContainerStorageName, aObjectStorageName;
     458         138 :     if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
     459             :                               aObjectStorageName,
     460         138 :                               EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) )
     461           0 :         return sRetURL;
     462             : 
     463         138 :     if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
     464             :     {
     465         112 :         OutputStorageWrapper_Impl *pOut = 0;
     466         112 :         SvXMLEmbeddedObjectHelper_Impl::iterator aIter;
     467             : 
     468         112 :         if( mpStreamMap )
     469             :         {
     470          59 :             aIter = mpStreamMap->find( rURLStr );
     471          59 :             if( aIter != mpStreamMap->end() && aIter->second )
     472          59 :                 pOut = aIter->second;
     473             :         }
     474             : 
     475         112 :         SvGlobalName aClassId, *pClassId = 0;
     476         112 :         sal_Int32 nPos = aObjectStorageName.lastIndexOf( '!' );
     477         112 :         if( -1 != nPos && aClassId.MakeId( aObjectStorageName.copy( nPos+1 ) ) )
     478             :         {
     479           0 :             aObjectStorageName = aObjectStorageName.copy( 0, nPos );
     480           0 :             pClassId = &aClassId;
     481             :         }
     482             : 
     483         112 :         ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId, pOut ? pOut->GetStream() : 0 );
     484         112 :         sRetURL = XML_EMBEDDEDOBJECT_URL_BASE;
     485         112 :         sRetURL += aObjectStorageName;
     486             : 
     487         112 :         if( pOut )
     488             :         {
     489          59 :             mpStreamMap->erase( aIter );
     490          59 :             pOut->release();
     491         112 :         }
     492             :     }
     493             :     else
     494             :     {
     495             :         // Objects are written using ::comphelper::IEmbeddedHelper::SaveAs
     496          26 :         sRetURL = "./";
     497          26 :         if( !aContainerStorageName.isEmpty() )
     498             :         {
     499          13 :             sRetURL += aContainerStorageName;
     500          13 :             sRetURL +=  "/";
     501             :         }
     502          26 :         sRetURL += aObjectStorageName;
     503             :     }
     504             : 
     505         138 :     return sRetURL;
     506             : }
     507             : 
     508           0 : uno::Reference< io::XInputStream > SvXMLEmbeddedObjectHelper::ImplGetReplacementImage(
     509             :                                             const uno::Reference< embed::XEmbeddedObject >& xObj )
     510             : {
     511           0 :     uno::Reference< io::XInputStream > xStream;
     512             : 
     513           0 :     if( xObj.is() )
     514             :     {
     515             :         try
     516             :         {
     517           0 :             bool bSwitchBackToLoaded = false;
     518           0 :             sal_Int32 nCurState = xObj->getCurrentState();
     519           0 :             if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
     520             :             {
     521             :                 // means that the object is not active
     522             :                 // copy replacement image from old to new container
     523           0 :                 OUString aMediaType;
     524           0 :                 xStream = mpDocPersist->getEmbeddedObjectContainer().GetGraphicStream( xObj, &aMediaType );
     525             :             }
     526             : 
     527           0 :             if ( !xStream.is() )
     528             :             {
     529             :                 // the image must be regenerated
     530             :                 // TODO/LATER: another aspect could be used
     531           0 :                 if ( nCurState == embed::EmbedStates::LOADED )
     532           0 :                     bSwitchBackToLoaded = true;
     533             : 
     534           0 :                 OUString aMediaType;
     535           0 :                 xStream = svt::EmbeddedObjectRef::GetGraphicReplacementStream(
     536             :                                                     embed::Aspects::MSOLE_CONTENT,
     537             :                                                     xObj,
     538           0 :                                                     &aMediaType );
     539             :             }
     540             : 
     541           0 :             if ( bSwitchBackToLoaded )
     542             :                 // switch back to loaded state; that way we have a minimum cache confusion
     543           0 :                 xObj->changeState( embed::EmbedStates::LOADED );
     544             :         }
     545           0 :         catch( uno::Exception& )
     546             :         {}
     547             :     }
     548             : 
     549           0 :     return xStream;
     550             : }
     551             : 
     552        1629 : void SvXMLEmbeddedObjectHelper::Init(
     553             :         const uno::Reference < embed::XStorage >& rRootStorage,
     554             :         ::comphelper::IEmbeddedHelper& rPersist,
     555             :         SvXMLEmbeddedObjectHelperMode eCreateMode )
     556             : {
     557        1629 :     mxRootStorage = rRootStorage;
     558        1629 :     mpDocPersist = &rPersist;
     559        1629 :     meCreateMode = eCreateMode;
     560        1629 : }
     561             : 
     562         616 : SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
     563             :         const uno::Reference < embed::XStorage >& rRootStorage,
     564             :         ::comphelper::IEmbeddedHelper& rDocPersist,
     565             :         SvXMLEmbeddedObjectHelperMode eCreateMode,
     566             :         bool bDirect )
     567             : {
     568             :     (void)bDirect;
     569             : 
     570         616 :     SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
     571             : 
     572         616 :     pThis->acquire();
     573         616 :     pThis->Init( rRootStorage, rDocPersist, eCreateMode );
     574             : 
     575         616 :     return pThis;
     576             : }
     577             : 
     578         138 : SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
     579             :         ::comphelper::IEmbeddedHelper& rDocPersist,
     580             :         SvXMLEmbeddedObjectHelperMode eCreateMode )
     581             : {
     582         138 :     SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
     583             : 
     584         138 :     pThis->acquire();
     585         138 :     pThis->Init( 0, rDocPersist, eCreateMode );
     586             : 
     587         138 :     return pThis;
     588             : }
     589             : 
     590         754 : void SvXMLEmbeddedObjectHelper::Destroy(
     591             :         SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper )
     592             : {
     593         754 :     if( pSvXMLEmbeddedObjectHelper )
     594             :     {
     595         754 :         pSvXMLEmbeddedObjectHelper->dispose();
     596         754 :         pSvXMLEmbeddedObjectHelper->release();
     597             :     }
     598         754 : }
     599             : 
     600        1629 : void SvXMLEmbeddedObjectHelper::Flush()
     601             : {
     602        1629 :     if( mxTempStorage.is() )
     603             :     {
     604           0 :         Reference < XComponent > xComp( mxTempStorage, UNO_QUERY );
     605           0 :         xComp->dispose();
     606             :     }
     607        1629 : }
     608             : 
     609             : // XGraphicObjectResolver: alien objects!
     610         138 : OUString SAL_CALL SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL(const OUString& rURL)
     611             :     throw(RuntimeException, std::exception)
     612             : {
     613         138 :     MutexGuard          aGuard( maMutex );
     614             : 
     615         138 :     OUString sRet;
     616             :     try
     617             :     {
     618         138 :         sRet = ImplInsertEmbeddedObjectURL(rURL);
     619             :     }
     620           0 :     catch (const RuntimeException&)
     621             :     {
     622           0 :         throw;
     623             :     }
     624           0 :     catch (const Exception& e)
     625             :     {
     626             :         throw WrappedTargetRuntimeException(
     627             :             "SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL non-RuntimeException",
     628           0 :             static_cast<uno::XWeak*>(this), uno::makeAny(e));
     629             :     }
     630         138 :     return sRet;
     631             : }
     632             : 
     633             : // XNameAccess: alien objects!
     634          59 : Any SAL_CALL SvXMLEmbeddedObjectHelper::getByName(
     635             :         const OUString& rURLStr )
     636             :     throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
     637             : {
     638          59 :     MutexGuard          aGuard( maMutex );
     639          59 :     Any aRet;
     640          59 :     if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
     641             :     {
     642          59 :         Reference < XOutputStream > xStrm;
     643          59 :         if( mpStreamMap )
     644             :         {
     645             :             SvXMLEmbeddedObjectHelper_Impl::iterator aIter =
     646           1 :                 mpStreamMap->find( rURLStr );
     647           1 :             if( aIter != mpStreamMap->end() && aIter->second )
     648           0 :                 xStrm = aIter->second;
     649             :         }
     650          59 :         if( !xStrm.is() )
     651             :         {
     652          59 :             OutputStorageWrapper_Impl *pOut = new OutputStorageWrapper_Impl;
     653          59 :             pOut->acquire();
     654          59 :             if( !mpStreamMap )
     655          58 :                 mpStreamMap = new SvXMLEmbeddedObjectHelper_Impl;
     656          59 :             (*mpStreamMap)[rURLStr] = pOut;
     657          59 :             xStrm = pOut;
     658             :         }
     659             : 
     660          59 :         aRet <<= xStrm;
     661             :     }
     662             :     else
     663             :     {
     664           0 :         bool bGraphicRepl = false;
     665           0 :         bool bOasisFormat = true;
     666           0 :         Reference < XInputStream > xStrm;
     667           0 :         OUString aContainerStorageName, aObjectStorageName;
     668           0 :         if( ImplGetStorageNames( rURLStr, aContainerStorageName,
     669             :                                  aObjectStorageName,
     670             :                                  true,
     671             :                                  &bGraphicRepl,
     672             :                                  &bOasisFormat ) )
     673             :         {
     674             :             try
     675             :             {
     676             :                 comphelper::EmbeddedObjectContainer& rContainer =
     677           0 :                         mpDocPersist->getEmbeddedObjectContainer();
     678             : 
     679           0 :                 Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( aObjectStorageName );
     680             :                 DBG_ASSERT( xObj.is(), "Didn't get object" );
     681             : 
     682           0 :                 if( xObj.is() )
     683             :                 {
     684           0 :                     if( bGraphicRepl )
     685             :                     {
     686           0 :                         xStrm = ImplGetReplacementImage( xObj );
     687             :                     }
     688             :                     else
     689             :                     {
     690           0 :                         Reference < embed::XEmbedPersist > xPersist( xObj, UNO_QUERY );
     691           0 :                         if( xPersist.is() )
     692             :                         {
     693           0 :                             if( !mxTempStorage.is() )
     694           0 :                                 mxTempStorage =
     695           0 :                                     comphelper::OStorageHelper::GetTemporaryStorage();
     696           0 :                             Sequence < beans::PropertyValue > aDummy( 0 ), aEmbDescr( 1 );
     697           0 :                             aEmbDescr[0].Name = "StoreVisualReplacement";
     698           0 :                             aEmbDescr[0].Value <<= !bOasisFormat;
     699           0 :                             if ( !bOasisFormat )
     700             :                             {
     701           0 :                                 uno::Reference< io::XInputStream > xGrInStream = ImplGetReplacementImage( xObj );
     702           0 :                                 if ( xGrInStream.is() )
     703             :                                 {
     704           0 :                                     aEmbDescr.realloc( 2 );
     705           0 :                                     aEmbDescr[1].Name = "VisualReplacement";
     706           0 :                                     aEmbDescr[1].Value <<= xGrInStream;
     707           0 :                                 }
     708             :                             }
     709             : 
     710           0 :                             xPersist->storeToEntry( mxTempStorage, aObjectStorageName,
     711           0 :                                                     aDummy, aEmbDescr );
     712             :                             Reference < io::XStream > xStream =
     713           0 :                                 mxTempStorage->openStreamElement(
     714             :                                                         aObjectStorageName,
     715           0 :                                                         embed::ElementModes::READ);
     716           0 :                             if( xStream.is() )
     717           0 :                                 xStrm = xStream->getInputStream();
     718           0 :                         }
     719             :                     }
     720           0 :                 }
     721             :             }
     722           0 :             catch ( uno::Exception& )
     723             :             {
     724             :             }
     725             :         }
     726             : 
     727           0 :         aRet <<= xStrm;
     728             :     }
     729             : 
     730          59 :     return aRet;
     731             : }
     732             : 
     733           0 : Sequence< OUString > SAL_CALL SvXMLEmbeddedObjectHelper::getElementNames()
     734             :     throw (RuntimeException, std::exception)
     735             : {
     736           0 :     MutexGuard          aGuard( maMutex );
     737           0 :     return Sequence< OUString >(0);
     738             : }
     739             : 
     740           0 : sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasByName( const OUString& rURLStr )
     741             :     throw (RuntimeException, std::exception)
     742             : {
     743           0 :     MutexGuard          aGuard( maMutex );
     744           0 :     if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
     745             :     {
     746           0 :         return sal_True;
     747             :     }
     748             :     else
     749             :     {
     750           0 :         OUString aContainerStorageName, aObjectStorageName;
     751           0 :         if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
     752             :                                   aObjectStorageName,
     753           0 :                                   true ) )
     754           0 :             return sal_False;
     755             : 
     756           0 :         comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
     757           0 :         return !aObjectStorageName.isEmpty() &&
     758           0 :                rContainer.HasEmbeddedObject( aObjectStorageName );
     759           0 :     }
     760             : }
     761             : 
     762             : // XNameAccess
     763           0 : Type SAL_CALL SvXMLEmbeddedObjectHelper::getElementType()
     764             :     throw (RuntimeException, std::exception)
     765             : {
     766           0 :     MutexGuard          aGuard( maMutex );
     767           0 :     if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
     768           0 :         return cppu::UnoType<XOutputStream>::get();
     769             :     else
     770           0 :         return cppu::UnoType<XInputStream>::get();
     771             : }
     772             : 
     773           0 : sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasElements()
     774             :     throw (RuntimeException, std::exception)
     775             : {
     776           0 :     MutexGuard          aGuard( maMutex );
     777           0 :     if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
     778             :     {
     779           0 :         return sal_True;
     780             :     }
     781             :     else
     782             :     {
     783           0 :         comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
     784           0 :         return rContainer.HasEmbeddedObjects();
     785           0 :     }
     786             : }
     787             : 
     788             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11