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

Generated by: LCOV version 1.10