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

Generated by: LCOV version 1.10