LCOV - code coverage report
Current view: top level - embeddedobj/source/commonembedding - persistence.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 784 0.0 %
Date: 2014-04-14 Functions: 0 34 0.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             : #include <commonembobj.hxx>
      21             : #include <com/sun/star/embed/Aspects.hpp>
      22             : #include <com/sun/star/document/XStorageBasedDocument.hpp>
      23             : #include <com/sun/star/embed/EmbedStates.hpp>
      24             : #include <com/sun/star/embed/EmbedVerbs.hpp>
      25             : #include <com/sun/star/embed/EntryInitModes.hpp>
      26             : #include <com/sun/star/embed/XStorage.hpp>
      27             : #include <com/sun/star/embed/XOptimizedStorage.hpp>
      28             : #include <com/sun/star/embed/ElementModes.hpp>
      29             : #include <com/sun/star/embed/EmbedUpdateModes.hpp>
      30             : #include <com/sun/star/embed/StorageFactory.hpp>
      31             : #include <com/sun/star/io/TempFile.hpp>
      32             : #include <com/sun/star/frame/XModel.hpp>
      33             : #include <com/sun/star/frame/XStorable.hpp>
      34             : #include <com/sun/star/frame/XLoadable.hpp>
      35             : #include <com/sun/star/frame/XComponentLoader.hpp>
      36             : #include <com/sun/star/frame/XModule.hpp>
      37             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      38             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      39             : #include <com/sun/star/lang/DisposedException.hpp>
      40             : #include <com/sun/star/util/XModifiable.hpp>
      41             : 
      42             : #include <com/sun/star/container/XNameAccess.hpp>
      43             : #include <com/sun/star/container/XChild.hpp>
      44             : #include <com/sun/star/util/XCloseable.hpp>
      45             : #include <com/sun/star/beans/XPropertySet.hpp>
      46             : #include <com/sun/star/beans/IllegalTypeException.hpp>
      47             : #include <com/sun/star/chart2/XChartDocument.hpp>
      48             : 
      49             : #include <comphelper/fileformat.h>
      50             : #include <comphelper/processfactory.hxx>
      51             : #include <comphelper/storagehelper.hxx>
      52             : #include <comphelper/mimeconfighelper.hxx>
      53             : #include <comphelper/namedvaluecollection.hxx>
      54             : 
      55             : #include <tools/diagnose_ex.h>
      56             : 
      57             : using namespace ::com::sun::star;
      58             : 
      59             : 
      60             : 
      61           0 : uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
      62             :                                                             sal_Bool bCanUseDocumentBaseURL )
      63             : {
      64           0 :     uno::Sequence< beans::PropertyValue > aResult;
      65           0 :     sal_Int32 nResLen = 0;
      66             : 
      67           0 :     for ( sal_Int32 nInd = 0; nInd < aMedDescr.getLength(); nInd++ )
      68             :     {
      69           0 :         if ( aMedDescr[nInd].Name == "ComponentData" || aMedDescr[nInd].Name == "DocumentTitle"
      70           0 :           || aMedDescr[nInd].Name == "InteractionHandler" || aMedDescr[nInd].Name == "JumpMark"
      71             :           // || aMedDescr[nInd].Name == "Password" // makes no sence for embedded objects
      72           0 :           || aMedDescr[nInd].Name == "Preview" || aMedDescr[nInd].Name == "ReadOnly"
      73           0 :           || aMedDescr[nInd].Name == "StartPresentation" || aMedDescr[nInd].Name == "RepairPackage"
      74           0 :           || aMedDescr[nInd].Name == "StatusIndicator" || aMedDescr[nInd].Name == "ViewData"
      75           0 :           || aMedDescr[nInd].Name == "ViewId" || aMedDescr[nInd].Name == "MacroExecutionMode"
      76           0 :           || aMedDescr[nInd].Name == "UpdateDocMode"
      77           0 :           || (aMedDescr[nInd].Name == "DocumentBaseURL" && bCanUseDocumentBaseURL) )
      78             :         {
      79           0 :             aResult.realloc( ++nResLen );
      80           0 :             aResult[nResLen-1] = aMedDescr[nInd];
      81             :         }
      82             :     }
      83             : 
      84           0 :     return aResult;
      85             : }
      86             : 
      87             : 
      88           0 : uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig )
      89             : {
      90           0 :     sal_Bool bAsTemplateSet = sal_False;
      91           0 :     sal_Int32 nLength = aOrig.getLength();
      92           0 :     uno::Sequence< beans::PropertyValue > aResult( nLength );
      93             : 
      94           0 :     for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
      95             :     {
      96           0 :         aResult[nInd].Name = aOrig[nInd].Name;
      97           0 :         if ( aResult[nInd].Name == "AsTemplate" )
      98             :         {
      99           0 :             aResult[nInd].Value <<= sal_True;
     100           0 :             bAsTemplateSet = sal_True;
     101             :         }
     102             :         else
     103           0 :             aResult[nInd].Value = aOrig[nInd].Value;
     104             :     }
     105             : 
     106           0 :     if ( !bAsTemplateSet )
     107             :     {
     108           0 :         aResult.realloc( nLength + 1 );
     109           0 :         aResult[nLength].Name = "AsTemplate";
     110           0 :         aResult[nLength].Value <<= sal_True;
     111             :     }
     112             : 
     113           0 :     return aResult;
     114             : }
     115             : 
     116             : 
     117           0 : uno::Reference< io::XInputStream > createTempInpStreamFromStor(
     118             :                                                             const uno::Reference< embed::XStorage >& xStorage,
     119             :                                                             const uno::Reference< uno::XComponentContext >& xContext )
     120             : {
     121             :     SAL_WARN_IF( !xStorage.is(), "embeddedobj.common", "The storage can not be empty!" );
     122             : 
     123           0 :     uno::Reference< io::XInputStream > xResult;
     124             : 
     125           0 :     uno::Reference < io::XStream > xTempStream( io::TempFile::create(xContext), uno::UNO_QUERY_THROW );
     126             : 
     127           0 :     uno::Reference < lang::XSingleServiceFactory > xStorageFactory( embed::StorageFactory::create(xContext) );
     128             : 
     129           0 :     uno::Sequence< uno::Any > aArgs( 2 );
     130           0 :     aArgs[0] <<= xTempStream;
     131           0 :     aArgs[1] <<= embed::ElementModes::READWRITE;
     132           0 :     uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
     133           0 :                                                     uno::UNO_QUERY );
     134           0 :     if ( !xTempStorage.is() )
     135           0 :         throw uno::RuntimeException(); // TODO:
     136             : 
     137             :     try
     138             :     {
     139           0 :         xStorage->copyToStorage( xTempStorage );
     140           0 :     } catch( const uno::Exception& e )
     141             :     {
     142             :         throw embed::StorageWrappedTargetException(
     143             :                     OUString( "Can't copy storage!" ),
     144             :                     uno::Reference< uno::XInterface >(),
     145           0 :                     uno::makeAny( e ) );
     146             :     }
     147             : 
     148             :     try {
     149           0 :         uno::Reference< lang::XComponent > xComponent( xTempStorage, uno::UNO_QUERY );
     150             :         SAL_WARN_IF( !xComponent.is(), "embeddedobj.common", "Wrong storage implementation!" );
     151           0 :         if ( xComponent.is() )
     152           0 :             xComponent->dispose();
     153             :     }
     154           0 :     catch ( const uno::Exception& )
     155             :     {
     156             :     }
     157             : 
     158             :     try {
     159           0 :         uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream();
     160           0 :         if ( xTempOut.is() )
     161           0 :             xTempOut->closeOutput();
     162             :     }
     163           0 :     catch ( const uno::Exception& )
     164             :     {
     165             :     }
     166             : 
     167           0 :     xResult = xTempStream->getInputStream();
     168             : 
     169           0 :     return xResult;
     170             : 
     171             : }
     172             : 
     173             : 
     174           0 : static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSource, const uno::Reference< embed::XStorage >& i_rTarget )
     175             : {
     176             :     try
     177             :     {
     178           0 :         const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW );
     179           0 :         const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW );
     180           0 :         const OUString sMediaTypePropName( "MediaType" );
     181           0 :         xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) );
     182             :     }
     183           0 :     catch( const uno::Exception& )
     184             :     {
     185             :         DBG_UNHANDLED_EXCEPTION();
     186             :     }
     187           0 : }
     188             : 
     189             : 
     190           0 : static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< uno::XComponentContext >& _rxContext,
     191             :     const OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport )
     192             : {
     193           0 :     ::comphelper::NamedValueCollection aArguments;
     194           0 :     aArguments.put( "EmbeddedObject", (sal_Bool)sal_True );
     195           0 :     aArguments.put( "EmbeddedScriptSupport", (sal_Bool)_bEmbeddedScriptSupport );
     196           0 :     aArguments.put( "DocumentRecoverySupport", (sal_Bool)i_bDocumentRecoverySupport );
     197             : 
     198           0 :     uno::Reference< uno::XInterface > xDocument;
     199             :     try
     200             :     {
     201           0 :         xDocument = _rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
     202           0 :                         _rDocumentServiceName, aArguments.getWrappedPropertyValues(), _rxContext );
     203             :     }
     204           0 :     catch( const uno::Exception& )
     205             :     {
     206             :         // if an embedded object implementation does not support XInitialization,
     207             :         // the default factory from cppuhelper will throw an
     208             :         // IllegalArgumentException when we try to create the instance with arguments.
     209             :         // Okay, so we fall back to creating the instance without any arguments.
     210             :         OSL_FAIL("Consider implementing interface XInitialization to avoid duplicate construction");
     211           0 :         xDocument = _rxContext->getServiceManager()->createInstanceWithContext( _rDocumentServiceName, _rxContext );
     212             :     }
     213             : 
     214             :     SAL_WARN_IF(!xDocument.is(), "embeddedobj.common", "Service " << _rDocumentServiceName << " is not available?");
     215           0 :     return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY );
     216             : }
     217             : 
     218             : 
     219           0 : static void SetDocToEmbedded( const uno::Reference< frame::XModel > xDocument, const OUString& aModuleName )
     220             : {
     221           0 :     if ( xDocument.is() )
     222             :     {
     223           0 :         uno::Sequence< beans::PropertyValue > aSeq( 1 );
     224           0 :         aSeq[0].Name = "SetEmbedded";
     225           0 :         aSeq[0].Value <<= sal_True;
     226           0 :         xDocument->attachResource( OUString(), aSeq );
     227             : 
     228           0 :         if ( !aModuleName.isEmpty() )
     229             :         {
     230             :             try
     231             :             {
     232           0 :                 uno::Reference< frame::XModule > xModule( xDocument, uno::UNO_QUERY_THROW );
     233           0 :                 xModule->setIdentifier( aModuleName );
     234             :             }
     235           0 :             catch( const uno::Exception& )
     236             :             {}
     237           0 :         }
     238             :     }
     239           0 : }
     240             : 
     241             : 
     242           0 : void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
     243             :                                                   const uno::Reference< embed::XStorage >& xNewObjectStorage,
     244             :                                                   const OUString& aNewName )
     245             : {
     246           0 :     if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
     247             :     {
     248             :         SAL_WARN_IF( xNewObjectStorage != m_xObjectStorage, "embeddedobj.common", "The storage must be the same!" );
     249           0 :         return;
     250             :     }
     251             : 
     252           0 :     uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
     253             :     OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
     254             : 
     255           0 :     m_xObjectStorage = xNewObjectStorage;
     256           0 :     m_xParentStorage = xNewParentStorage;
     257           0 :     m_aEntryName = aNewName;
     258             : 
     259             :     // the linked document should not be switched
     260           0 :     if ( !m_bIsLink )
     261             :     {
     262           0 :         uno::Reference< document::XStorageBasedDocument > xDoc( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
     263           0 :         if ( xDoc.is() )
     264           0 :             SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
     265             :     }
     266             : 
     267             :     try {
     268           0 :         if ( xComponent.is() )
     269           0 :             xComponent->dispose();
     270             :     }
     271           0 :     catch ( const uno::Exception& )
     272             :     {
     273           0 :     }
     274             : }
     275             : 
     276             : 
     277           0 : void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
     278             :                                                   const OUString& aNewName )
     279             : {
     280           0 :     if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
     281           0 :         return;
     282             : 
     283           0 :     sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
     284             : 
     285           0 :     uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode );
     286             :     SAL_WARN_IF( !xNewOwnStorage.is(), "embeddedobj.common", "The method can not return empty reference!" );
     287             : 
     288           0 :     SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName );
     289             : }
     290             : 
     291             : 
     292           0 : void OCommonEmbeddedObject::EmbedAndReparentDoc_Impl( const uno::Reference< util::XCloseable >& i_rxDocument ) const
     293             : {
     294           0 :     SetDocToEmbedded( uno::Reference< frame::XModel >( i_rxDocument, uno::UNO_QUERY ), m_aModuleName );
     295             : 
     296             :     try
     297             :     {
     298           0 :         uno::Reference < container::XChild > xChild( i_rxDocument, uno::UNO_QUERY );
     299           0 :         if ( xChild.is() )
     300           0 :             xChild->setParent( m_xParent );
     301             :     }
     302           0 :     catch( const lang::NoSupportException & )
     303             :     {
     304             :         SAL_WARN( "embeddedobj.common", "OCommonEmbeddedObject::EmbedAndReparentDoc: cannot set parent at document!" );
     305             :     }
     306           0 : }
     307             : 
     308             : 
     309           0 : uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
     310             : {
     311             :     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
     312           0 :                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
     313             : 
     314           0 :     uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY );
     315           0 :     uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY );
     316           0 :     if ( !xLoadable.is() )
     317           0 :         throw uno::RuntimeException();
     318             : 
     319             :     try
     320             :     {
     321             :         // set the document mode to embedded as the first action on document!!!
     322           0 :         EmbedAndReparentDoc_Impl( xDocument );
     323             : 
     324             :         // if we have a storage to recover the document from, do not use initNew, but instead load from that storage
     325           0 :         bool bInitNew = true;
     326           0 :         if ( m_xRecoveryStorage.is() )
     327             :         {
     328           0 :             uno::Reference< document::XStorageBasedDocument > xDoc( xLoadable, uno::UNO_QUERY );
     329             :             SAL_WARN_IF( !xDoc.is(), "embeddedobj.common", "OCommonEmbeddedObject::InitNewDocument_Impl: cannot recover from a storage when the document is not storage based!" );
     330           0 :             if ( xDoc.is() )
     331             :             {
     332           0 :                 ::comphelper::NamedValueCollection aLoadArgs;
     333           0 :                 FillDefaultLoadArgs_Impl( m_xRecoveryStorage, aLoadArgs );
     334             : 
     335           0 :                 xDoc->loadFromStorage( m_xRecoveryStorage, aLoadArgs.getPropertyValues() );
     336           0 :                 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
     337           0 :                 bInitNew = false;
     338           0 :             }
     339             :         }
     340             : 
     341           0 :         if ( bInitNew )
     342             :         {
     343             :             // init document as a new
     344           0 :             xLoadable->initNew();
     345             :         }
     346           0 :         xModel->attachResource( xModel->getURL(), m_aDocMediaDescriptor );
     347             :     }
     348           0 :     catch( const uno::Exception& )
     349             :     {
     350           0 :         uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
     351           0 :         if ( xCloseable.is() )
     352             :         {
     353             :             try
     354             :             {
     355           0 :                 xCloseable->close( sal_True );
     356             :             }
     357           0 :             catch( const uno::Exception& )
     358             :             {
     359             :             }
     360             :         }
     361             : 
     362           0 :         throw; // TODO
     363             :     }
     364             : 
     365           0 :     return xDocument;
     366             : }
     367             : 
     368             : 
     369           0 : uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
     370             : {
     371             :     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
     372           0 :                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
     373             : 
     374           0 :     uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
     375           0 :     if ( !xLoadable.is() )
     376           0 :         throw uno::RuntimeException();
     377             : 
     378           0 :     sal_Int32 nLen = 2;
     379           0 :     uno::Sequence< beans::PropertyValue > aArgs( nLen );
     380           0 :     aArgs[0].Name = "URL";
     381           0 :     aArgs[0].Value <<= m_aLinkURL;
     382           0 :     aArgs[1].Name = "FilterName";
     383           0 :     aArgs[1].Value <<= m_aLinkFilterName;
     384           0 :     if ( m_bLinkHasPassword )
     385             :     {
     386           0 :         aArgs.realloc( ++nLen );
     387           0 :         aArgs[nLen-1].Name = "Password";
     388           0 :         aArgs[nLen-1].Value <<= m_aLinkPassword;
     389             :     }
     390             : 
     391           0 :     aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
     392           0 :     for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
     393             :     {
     394           0 :         aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
     395           0 :         aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
     396             :     }
     397             : 
     398             :     try
     399             :     {
     400             :         // the document is not really an embedded one, it is a link
     401           0 :         EmbedAndReparentDoc_Impl( xDocument );
     402             : 
     403             :         // load the document
     404           0 :         xLoadable->load( aArgs );
     405             : 
     406           0 :         if ( !m_bLinkHasPassword )
     407             :         {
     408             :             // check if there is a password to cache
     409           0 :             uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW );
     410           0 :             uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs();
     411           0 :             for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
     412           0 :                 if ( aProps[nInd].Name == "Password" && ( aProps[nInd].Value >>= m_aLinkPassword ) )
     413             :                 {
     414           0 :                     m_bLinkHasPassword = sal_True;
     415           0 :                     break;
     416           0 :                 }
     417             :         }
     418             :     }
     419           0 :     catch( const uno::Exception& )
     420             :     {
     421           0 :         uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
     422           0 :         if ( xCloseable.is() )
     423             :         {
     424             :             try
     425             :             {
     426           0 :                 xCloseable->close( sal_True );
     427             :             }
     428           0 :             catch( const uno::Exception& )
     429             :             {
     430             :             }
     431             :         }
     432             : 
     433           0 :         throw; // TODO
     434             :     }
     435             : 
     436           0 :     return xDocument;
     437             : 
     438             : }
     439             : 
     440             : 
     441           0 : OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
     442             : {
     443           0 :     OUString aFilterName = GetPresetFilterName();
     444           0 :     if ( aFilterName.isEmpty() )
     445             :     {
     446             :         try {
     447           0 :             ::comphelper::MimeConfigurationHelper aHelper( m_xContext );
     448           0 :             aFilterName = aHelper.GetDefaultFilterFromServiceName( GetDocumentServiceName(), nVersion );
     449           0 :         } catch( const uno::Exception& )
     450             :         {}
     451             :     }
     452             : 
     453           0 :     return aFilterName;
     454             : }
     455             : 
     456             : 
     457           0 : void OCommonEmbeddedObject::FillDefaultLoadArgs_Impl( const uno::Reference< embed::XStorage >& i_rxStorage,
     458             :         ::comphelper::NamedValueCollection& o_rLoadArgs ) const
     459             : {
     460           0 :     o_rLoadArgs.put( "DocumentBaseURL", GetBaseURL_Impl() );
     461           0 :     o_rLoadArgs.put( "HierarchicalDocumentName", m_aEntryName );
     462           0 :     o_rLoadArgs.put( "ReadOnly", m_bReadOnly );
     463             : 
     464           0 :     OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( i_rxStorage ) );
     465             :     SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "OCommonEmbeddedObject::FillDefaultLoadArgs_Impl: Wrong document service name!" );
     466           0 :     if ( aFilterName.isEmpty() )
     467           0 :         throw io::IOException();    // TODO: error message/code
     468             : 
     469           0 :     o_rLoadArgs.put( "FilterName", aFilterName );
     470           0 : }
     471             : 
     472             : 
     473           0 : uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl()
     474             : {
     475           0 :     ENSURE_OR_THROW( m_xObjectStorage.is(), "no object storage" );
     476             : 
     477           0 :     const uno::Reference< embed::XStorage > xSourceStorage( m_xRecoveryStorage.is() ? m_xRecoveryStorage : m_xObjectStorage );
     478             : 
     479             :     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
     480           0 :                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
     481             : 
     482             :     //#i103460# ODF: take the size given from the parent frame as default
     483           0 :     uno::Reference< chart2::XChartDocument > xChart( xDocument, uno::UNO_QUERY );
     484           0 :     if( xChart.is() )
     485             :     {
     486           0 :         uno::Reference< embed::XVisualObject > xChartVisualObject( xChart, uno::UNO_QUERY );
     487           0 :         if( xChartVisualObject.is() )
     488           0 :             xChartVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, m_aDefaultSizeForChart_In_100TH_MM );
     489             :     }
     490             : 
     491           0 :     uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
     492           0 :     uno::Reference< document::XStorageBasedDocument > xDoc( xDocument, uno::UNO_QUERY );
     493           0 :     if ( !xDoc.is() && !xLoadable.is() ) ///BUG: This should be || instead of && ?
     494           0 :         throw uno::RuntimeException();
     495             : 
     496           0 :     ::comphelper::NamedValueCollection aLoadArgs;
     497           0 :     FillDefaultLoadArgs_Impl( xSourceStorage, aLoadArgs );
     498             : 
     499           0 :     uno::Reference< io::XInputStream > xTempInpStream;
     500           0 :     if ( !xDoc.is() )
     501             :     {
     502           0 :         xTempInpStream = createTempInpStreamFromStor( xSourceStorage, m_xContext );
     503           0 :         if ( !xTempInpStream.is() )
     504           0 :             throw uno::RuntimeException();
     505             : 
     506           0 :         OUString aTempFileURL;
     507             :         try
     508             :         {
     509             :             // no need to let the file stay after the stream is removed since the embedded document
     510             :             // can not be stored directly
     511           0 :             uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW );
     512           0 :             xTempStreamProps->getPropertyValue("Uri") >>= aTempFileURL;
     513             :         }
     514           0 :         catch( const uno::Exception& )
     515             :         {
     516             :         }
     517             : 
     518             :         SAL_WARN_IF( aTempFileURL.isEmpty(), "embeddedobj.common", "Coudn't retrieve temporary file URL!" );
     519             : 
     520           0 :         aLoadArgs.put( "URL", aTempFileURL );
     521           0 :         aLoadArgs.put( "InputStream", xTempInpStream );
     522             :     }
     523             : 
     524             : 
     525           0 :     aLoadArgs.merge( m_aDocMediaDescriptor, true );
     526             : 
     527             :     try
     528             :     {
     529             :         // set the document mode to embedded as the first step!!!
     530           0 :         EmbedAndReparentDoc_Impl( xDocument );
     531             : 
     532           0 :         if ( xDoc.is() )
     533             :         {
     534           0 :             xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() );
     535           0 :             if ( xSourceStorage != m_xObjectStorage )
     536           0 :                 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
     537             :         }
     538             :         else
     539           0 :             xLoadable->load( aLoadArgs.getPropertyValues() );
     540             :     }
     541           0 :     catch( const uno::Exception& )
     542             :     {
     543           0 :         uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
     544           0 :         if ( xCloseable.is() )
     545             :         {
     546             :             try
     547             :             {
     548           0 :                 xCloseable->close( sal_True );
     549             :             }
     550           0 :             catch( const uno::Exception& )
     551             :             {
     552             :                 DBG_UNHANDLED_EXCEPTION();
     553             :             }
     554             :         }
     555             : 
     556           0 :         throw; // TODO
     557             :     }
     558             : 
     559           0 :     return xDocument;
     560             : }
     561             : 
     562             : 
     563           0 : uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStream_Impl(
     564             :                                                                             sal_Int32 nStorageFormat,
     565             :                                                                             const OUString& aBaseURL,
     566             :                                                                             const OUString& aHierarchName )
     567             : {
     568             :     uno::Reference < io::XOutputStream > xTempOut(
     569             :                 io::TempFile::create(m_xContext),
     570           0 :                 uno::UNO_QUERY_THROW );
     571           0 :     uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY );
     572             : 
     573           0 :     if ( !aResult.is() )
     574           0 :         throw uno::RuntimeException(); // TODO:
     575             : 
     576           0 :     uno::Reference< frame::XStorable > xStorable;
     577             :     {
     578           0 :         osl::MutexGuard aGuard( m_aMutex );
     579           0 :         if ( m_pDocHolder )
     580           0 :             xStorable = uno::Reference< frame::XStorable > ( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
     581             :     }
     582             : 
     583           0 :     if( !xStorable.is() )
     584           0 :         throw uno::RuntimeException(); // TODO:
     585             : 
     586           0 :     OUString aFilterName = GetFilterName( nStorageFormat );
     587             : 
     588             :     SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "Wrong document service name!" );
     589           0 :     if ( aFilterName.isEmpty() )
     590           0 :         throw io::IOException(); // TODO:
     591             : 
     592           0 :     uno::Sequence< beans::PropertyValue > aArgs( 4 );
     593           0 :     aArgs[0].Name = "FilterName";
     594           0 :     aArgs[0].Value <<= aFilterName;
     595           0 :     aArgs[1].Name = "OutputStream";
     596           0 :     aArgs[1].Value <<= xTempOut;
     597           0 :     aArgs[2].Name = "DocumentBaseURL";
     598           0 :     aArgs[2].Value <<= aBaseURL;
     599           0 :     aArgs[3].Name = "HierarchicalDocumentName";
     600           0 :     aArgs[3].Value <<= aHierarchName;
     601             : 
     602           0 :     xStorable->storeToURL( OUString( "private:stream" ), aArgs );
     603             :     try
     604             :     {
     605           0 :         xTempOut->closeOutput();
     606             :     }
     607           0 :     catch( const uno::Exception& )
     608             :     {
     609             :         SAL_WARN( "embeddedobj.common", "Looks like stream was closed already" );
     610             :     }
     611             : 
     612           0 :     return aResult;
     613             : }
     614             : 
     615             : 
     616           0 : void OCommonEmbeddedObject::SaveObject_Impl()
     617             : {
     618           0 :     if ( m_xClientSite.is() )
     619             :     {
     620             :         try
     621             :         {
     622             :             // check whether the component is modified,
     623             :             // if not there is no need for storing
     624           0 :             uno::Reference< util::XModifiable > xModifiable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
     625           0 :             if ( xModifiable.is() && !xModifiable->isModified() )
     626           0 :                 return;
     627             :         }
     628           0 :         catch( const uno::Exception& )
     629             :         {}
     630             : 
     631             :         try {
     632           0 :             m_xClientSite->saveObject();
     633             :         }
     634           0 :         catch( const uno::Exception& )
     635             :         {
     636             :             SAL_WARN( "embeddedobj.common", "The object was not stored!" );
     637             :         }
     638             :     }
     639             : }
     640             : 
     641             : 
     642           0 : OUString OCommonEmbeddedObject::GetBaseURL_Impl() const
     643             : {
     644           0 :     OUString aBaseURL;
     645           0 :     sal_Int32 nInd = 0;
     646             : 
     647           0 :     if ( m_xClientSite.is() )
     648             :     {
     649             :         try
     650             :         {
     651           0 :             uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW );
     652           0 :             uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs();
     653           0 :             for ( nInd = 0; nInd < aModelProps.getLength(); nInd++ )
     654           0 :                 if ( aModelProps[nInd].Name.equals(
     655           0 :                                                 OUString( "DocumentBaseURL" ) ) )
     656             :                 {
     657           0 :                     aModelProps[nInd].Value >>= aBaseURL;
     658           0 :                     break;
     659           0 :                 }
     660             : 
     661             : 
     662             :         }
     663           0 :         catch( const uno::Exception& )
     664             :         {}
     665             :     }
     666             : 
     667           0 :     if ( aBaseURL.isEmpty() )
     668             :     {
     669           0 :         for ( nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
     670           0 :             if ( m_aDocMediaDescriptor[nInd].Name.equals(
     671           0 :                                                 OUString( "DocumentBaseURL" ) ) )
     672             :             {
     673           0 :                 m_aDocMediaDescriptor[nInd].Value >>= aBaseURL;
     674           0 :                 break;
     675             :             }
     676             :     }
     677             : 
     678           0 :     if ( aBaseURL.isEmpty() )
     679           0 :         aBaseURL = m_aDefaultParentBaseURL;
     680             : 
     681           0 :     return aBaseURL;
     682             : }
     683             : 
     684             : 
     685           0 : OUString OCommonEmbeddedObject::GetBaseURLFrom_Impl(
     686             :                     const uno::Sequence< beans::PropertyValue >& lArguments,
     687             :                     const uno::Sequence< beans::PropertyValue >& lObjArgs )
     688             : {
     689           0 :     OUString aBaseURL;
     690           0 :     sal_Int32 nInd = 0;
     691             : 
     692           0 :     for ( nInd = 0; nInd < lArguments.getLength(); nInd++ )
     693           0 :         if ( lArguments[nInd].Name == "DocumentBaseURL" )
     694             :         {
     695           0 :             lArguments[nInd].Value >>= aBaseURL;
     696           0 :             break;
     697             :         }
     698             : 
     699           0 :     if ( aBaseURL.isEmpty() )
     700             :     {
     701           0 :         for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
     702           0 :             if ( lObjArgs[nInd].Name == "DefaultParentBaseURL" )
     703             :             {
     704           0 :                 lObjArgs[nInd].Value >>= aBaseURL;
     705           0 :                 break;
     706             :             }
     707             :     }
     708             : 
     709           0 :     return aBaseURL;
     710             : }
     711             : 
     712             : 
     713             : 
     714           0 : void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< document::XStorageBasedDocument >& xDoc, const uno::Reference< embed::XStorage >& xStorage )
     715             : {
     716           0 :     xDoc->switchToStorage( xStorage );
     717             : 
     718           0 :     uno::Reference< util::XModifiable > xModif( xDoc, uno::UNO_QUERY );
     719           0 :     if ( xModif.is() )
     720           0 :         xModif->setModified( sal_False );
     721             : 
     722           0 :     if ( m_xRecoveryStorage.is() )
     723           0 :         m_xRecoveryStorage.clear();
     724           0 : }
     725             : 
     726             : 
     727           0 : void OCommonEmbeddedObject::StoreDocToStorage_Impl( const uno::Reference< embed::XStorage >& xStorage,
     728             :                                                     sal_Int32 nStorageFormat,
     729             :                                                     const OUString& aBaseURL,
     730             :                                                     const OUString& aHierarchName,
     731             :                                                     sal_Bool bAttachToTheStorage )
     732             : {
     733             :     SAL_WARN_IF( !xStorage.is(), "embeddedobj.common", "No storage is provided for storing!" );
     734             : 
     735           0 :     if ( !xStorage.is() )
     736           0 :         throw uno::RuntimeException(); // TODO:
     737             : 
     738           0 :     uno::Reference< document::XStorageBasedDocument > xDoc;
     739             :     {
     740           0 :         osl::MutexGuard aGuard( m_aMutex );
     741           0 :         if ( m_pDocHolder )
     742           0 :             xDoc = uno::Reference< document::XStorageBasedDocument >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
     743             :     }
     744             : 
     745           0 :     if ( xDoc.is() )
     746             :     {
     747           0 :         OUString aFilterName = GetFilterName( nStorageFormat );
     748             : 
     749             :         SAL_WARN_IF( aFilterName.isEmpty(), "embeddedobj.common", "Wrong document service name!" );
     750           0 :         if ( aFilterName.isEmpty() )
     751           0 :             throw io::IOException(); // TODO:
     752             : 
     753           0 :         uno::Sequence< beans::PropertyValue > aArgs( 3 );
     754           0 :         aArgs[0].Name = "FilterName";
     755           0 :         aArgs[0].Value <<= aFilterName;
     756           0 :         aArgs[2].Name = "DocumentBaseURL";
     757           0 :         aArgs[2].Value <<= aBaseURL;
     758           0 :         aArgs[1].Name = "HierarchicalDocumentName";
     759           0 :         aArgs[1].Value <<= aHierarchName;
     760             : 
     761           0 :         xDoc->storeToStorage( xStorage, aArgs );
     762           0 :         if ( bAttachToTheStorage )
     763           0 :             SwitchDocToStorage_Impl( xDoc, xStorage );
     764             :     }
     765             :     else
     766             :     {
     767             :         // store document to temporary stream based on temporary file
     768           0 :         uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName );
     769             : 
     770             :         SAL_WARN_IF( !xTempIn.is(), "embeddedobj.common", "The stream reference can not be empty!" );
     771             : 
     772             :         // open storage based on document temporary file for reading
     773           0 :         uno::Reference < lang::XSingleServiceFactory > xStorageFactory = embed::StorageFactory::create(m_xContext);
     774             : 
     775           0 :         uno::Sequence< uno::Any > aArgs(1);
     776           0 :         aArgs[0] <<= xTempIn;
     777           0 :         uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
     778           0 :                                                             uno::UNO_QUERY );
     779           0 :         if ( !xTempStorage.is() )
     780           0 :             throw uno::RuntimeException(); // TODO:
     781             : 
     782             :         // object storage must be commited automatically
     783           0 :         xTempStorage->copyToStorage( xStorage );
     784           0 :     }
     785           0 : }
     786             : 
     787             : 
     788           0 : uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateDocFromMediaDescr_Impl(
     789             :                                         const uno::Sequence< beans::PropertyValue >& aMedDescr )
     790             : {
     791             :     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
     792           0 :                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
     793             : 
     794           0 :     uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
     795           0 :     if ( !xLoadable.is() )
     796           0 :         throw uno::RuntimeException();
     797             : 
     798             :     try
     799             :     {
     800             :         // set the document mode to embedded as the first action on the document!!!
     801           0 :         EmbedAndReparentDoc_Impl( xDocument );
     802             : 
     803           0 :         xLoadable->load( addAsTemplate( aMedDescr ) );
     804             :     }
     805           0 :     catch( const uno::Exception& )
     806             :     {
     807           0 :         uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
     808           0 :         if ( xCloseable.is() )
     809             :         {
     810             :             try
     811             :             {
     812           0 :                 xCloseable->close( sal_True );
     813             :             }
     814           0 :             catch( const uno::Exception& )
     815             :             {
     816             :             }
     817             :         }
     818             : 
     819           0 :         throw; // TODO
     820             :     }
     821             : 
     822           0 :     return xDocument;
     823             : }
     824             : 
     825             : 
     826           0 : uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl()
     827             : {
     828           0 :     uno::Reference< util::XCloseable > xResult;
     829             : 
     830             :     SAL_WARN_IF( !m_bIsLink, "embeddedobj.common", "The object is not a linked one!" );
     831             : 
     832           0 :     uno::Sequence< beans::PropertyValue > aTempMediaDescr;
     833             : 
     834           0 :     sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
     835             :     try {
     836           0 :         nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
     837             :     }
     838           0 :     catch ( const beans::IllegalTypeException& )
     839             :     {
     840             :         // the container just has an unknown type, use current file format
     841             :     }
     842           0 :     catch ( const uno::Exception& )
     843             :     {
     844             :         SAL_WARN( "embeddedobj.common", "Can not retrieve storage media type!" );
     845             :     }
     846             : 
     847           0 :     if ( m_pDocHolder->GetComponent().is() )
     848             :     {
     849           0 :         aTempMediaDescr.realloc( 4 );
     850             : 
     851             :         // TODO/LATER: may be private:stream should be used as target URL
     852           0 :         OUString aTempFileURL;
     853             :         uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT,
     854             :                                                                                          OUString(),
     855           0 :                                                                                          OUString() );
     856             :         try
     857             :         {
     858             :             // no need to let the file stay after the stream is removed since the embedded document
     859             :             // can not be stored directly
     860           0 :             uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW );
     861           0 :             xTempStreamProps->getPropertyValue("Uri") >>= aTempFileURL;
     862             :         }
     863           0 :         catch( const uno::Exception& )
     864             :         {
     865             :         }
     866             : 
     867             :         SAL_WARN_IF( aTempFileURL.isEmpty(), "embeddedobj.common", "Couldn't retrieve temporary file URL!" );
     868             : 
     869           0 :         aTempMediaDescr[0].Name = "URL";
     870           0 :         aTempMediaDescr[0].Value <<= aTempFileURL;
     871           0 :         aTempMediaDescr[1].Name = "InputStream";
     872           0 :         aTempMediaDescr[1].Value <<= xTempStream;
     873           0 :         aTempMediaDescr[2].Name = "FilterName";
     874           0 :         aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat );
     875           0 :         aTempMediaDescr[3].Name = "AsTemplate";
     876           0 :         aTempMediaDescr[3].Value <<= sal_True;
     877             :     }
     878             :     else
     879             :     {
     880           0 :         aTempMediaDescr.realloc( 2 );
     881           0 :         aTempMediaDescr[0].Name = "URL";
     882           0 :         aTempMediaDescr[0].Value <<= m_aLinkURL;
     883           0 :         aTempMediaDescr[1].Name = "FilterName";
     884           0 :         aTempMediaDescr[1].Value <<= m_aLinkFilterName;
     885             :     }
     886             : 
     887           0 :     xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );
     888             : 
     889           0 :     return xResult;
     890             : }
     891             : 
     892             : 
     893           0 : void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
     894             :                     const uno::Reference< embed::XStorage >& xStorage,
     895             :                     const OUString& sEntName,
     896             :                     sal_Int32 nEntryConnectionMode,
     897             :                     const uno::Sequence< beans::PropertyValue >& lArguments,
     898             :                     const uno::Sequence< beans::PropertyValue >& lObjArgs )
     899             :         throw ( lang::IllegalArgumentException,
     900             :                 embed::WrongStateException,
     901             :                 io::IOException,
     902             :                 uno::Exception,
     903             :                 uno::RuntimeException, std::exception )
     904             : {
     905             :     SAL_INFO( "embeddedobj.common", "embeddedobj (mv76033) OCommonEmbeddedObject::setPersistentEntry" );
     906             : 
     907             :     // the type of the object must be already set
     908             :     // a kind of typedetection should be done in the factory
     909             : 
     910           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     911           0 :     if ( m_bDisposed )
     912           0 :         throw lang::DisposedException(); // TODO
     913             : 
     914           0 :     if ( !xStorage.is() )
     915             :         throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
     916             :                                             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
     917           0 :                                             1 );
     918             : 
     919           0 :     if ( sEntName.isEmpty() )
     920             :         throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
     921             :                                             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
     922           0 :                                             2 );
     923             : 
     924             :     // May be LOADED should be forbidden here ???
     925           0 :     if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
     926           0 :       && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
     927             :     {
     928             :         // if the object is not loaded
     929             :         // it can not get persistent representation without initialization
     930             : 
     931             :         // if the object is loaded
     932             :         // it can switch persistent representation only without initialization
     933             : 
     934             :         throw embed::WrongStateException(
     935             :                     OUString( "Can't change persistent representation of activated object!\n" ),
     936           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
     937             :     }
     938             : 
     939           0 :     if ( m_bWaitSaveCompleted )
     940             :     {
     941           0 :         if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
     942             :         {
     943             :             // saveCompleted is expected, handle it accordingly
     944           0 :             if ( m_xNewParentStorage == xStorage && m_aNewEntryName.equals( sEntName ) )
     945             :             {
     946           0 :                 saveCompleted( sal_True );
     947           0 :                 return;
     948             :             }
     949             : 
     950             :             // if a completely different entry is provided, switch first back to the old persistence in saveCompleted
     951             :             // and then switch to the target persistence
     952           0 :             sal_Bool bSwitchFurther = ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) );
     953           0 :             saveCompleted( sal_False );
     954           0 :             if ( !bSwitchFurther )
     955           0 :                 return;
     956             :         }
     957             :         else
     958             :             throw embed::WrongStateException(
     959             :                         OUString( "The object waits for saveCompleted() call!\n" ),
     960           0 :                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
     961             :     }
     962             : 
     963             :     // for now support of this interface is required to allow breaking of links and converting them to normal embedded
     964             :     // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
     965             :     // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
     966           0 :     if ( m_bIsLink )
     967             :     {
     968           0 :         m_aEntryName = sEntName;
     969           0 :         return;
     970             :     }
     971             : 
     972           0 :     uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
     973           0 :     if ( !xNameAccess.is() )
     974           0 :         throw uno::RuntimeException(); //TODO
     975             : 
     976             :     // detect entry existence
     977           0 :     sal_Bool bElExists = xNameAccess->hasByName( sEntName );
     978             : 
     979           0 :     m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments,
     980           0 :                                                   nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT );
     981             : 
     982           0 :     m_bReadOnly = sal_False;
     983           0 :     for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
     984           0 :         if ( lArguments[nInd].Name == "ReadOnly" )
     985           0 :             lArguments[nInd].Value >>= m_bReadOnly;
     986             : 
     987             :     // TODO: use lObjArgs for StoreVisualReplacement
     988           0 :     for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
     989           0 :         if ( lObjArgs[nObjInd].Name == "OutplaceDispatchInterceptor" )
     990             :         {
     991           0 :             uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
     992           0 :             if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
     993           0 :                 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
     994             :         }
     995           0 :         else if ( lObjArgs[nObjInd].Name == "DefaultParentBaseURL" )
     996             :         {
     997           0 :             lObjArgs[nObjInd].Value >>= m_aDefaultParentBaseURL;
     998             :         }
     999           0 :         else if ( lObjArgs[nObjInd].Name == "Parent" )
    1000             :         {
    1001           0 :             lObjArgs[nObjInd].Value >>= m_xParent;
    1002             :         }
    1003           0 :         else if ( lObjArgs[nObjInd].Name == "IndividualMiscStatus" )
    1004             :         {
    1005           0 :             sal_Int64 nMiscStatus=0;
    1006           0 :             lObjArgs[nObjInd].Value >>= nMiscStatus;
    1007           0 :             m_nMiscStatus |= nMiscStatus;
    1008             :         }
    1009           0 :         else if ( lObjArgs[nObjInd].Name == "CloneFrom" )
    1010             :         {
    1011           0 :             uno::Reference < embed::XEmbeddedObject > xObj;
    1012           0 :             lObjArgs[nObjInd].Value >>= xObj;
    1013           0 :             if ( xObj.is() )
    1014             :             {
    1015           0 :                 m_bHasClonedSize = sal_True;
    1016           0 :                 m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
    1017           0 :                 m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT );
    1018           0 :             }
    1019             :         }
    1020           0 :         else if ( lObjArgs[nObjInd].Name == "OutplaceFrameProperties" )
    1021             :         {
    1022           0 :             uno::Sequence< uno::Any > aOutFrameProps;
    1023           0 :             uno::Sequence< beans::NamedValue > aOutFramePropsTyped;
    1024           0 :             if ( lObjArgs[nObjInd].Value >>= aOutFrameProps )
    1025             :             {
    1026           0 :                 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
    1027             :             }
    1028           0 :             else if ( lObjArgs[nObjInd].Value >>= aOutFramePropsTyped )
    1029             :             {
    1030           0 :                 aOutFrameProps.realloc( aOutFramePropsTyped.getLength() );
    1031           0 :                 uno::Any* pProp = aOutFrameProps.getArray();
    1032           0 :                 for (   const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray();
    1033           0 :                         pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength();
    1034             :                         ++pTypedProp, ++pProp
    1035             :                     )
    1036             :                 {
    1037           0 :                     *pProp <<= *pTypedProp;
    1038             :                 }
    1039           0 :                 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
    1040             :             }
    1041             :             else
    1042           0 :                 SAL_WARN( "embeddedobj.common", "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" );
    1043             :         }
    1044           0 :         else if ( lObjArgs[nObjInd].Name == "ModuleName" )
    1045             :         {
    1046           0 :             lObjArgs[nObjInd].Value >>= m_aModuleName;
    1047             :         }
    1048           0 :         else if ( lObjArgs[nObjInd].Name == "EmbeddedScriptSupport" )
    1049             :         {
    1050           0 :             OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bEmbeddedScriptSupport );
    1051             :         }
    1052           0 :         else if ( lObjArgs[nObjInd].Name == "DocumentRecoverySupport" )
    1053             :         {
    1054           0 :             OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bDocumentRecoverySupport );
    1055             :         }
    1056           0 :         else if ( lObjArgs[nObjInd].Name == "RecoveryStorage" )
    1057             :         {
    1058           0 :             OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_xRecoveryStorage );
    1059             :         }
    1060             : 
    1061             : 
    1062           0 :     sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
    1063             : 
    1064           0 :     SwitchOwnPersistence( xStorage, sEntName );
    1065             : 
    1066           0 :     if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
    1067             :     {
    1068           0 :         if ( bElExists )
    1069             :         {
    1070             :             // the initialization from existing storage allows to leave object in loaded state
    1071           0 :             m_nObjectState = embed::EmbedStates::LOADED;
    1072             :         }
    1073             :         else
    1074             :         {
    1075           0 :             m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
    1076           0 :             if ( !m_pDocHolder->GetComponent().is() )
    1077           0 :                 throw io::IOException(); // TODO: can not create document
    1078             : 
    1079           0 :             m_nObjectState = embed::EmbedStates::RUNNING;
    1080             :         }
    1081             :     }
    1082             :     else
    1083             :     {
    1084           0 :         if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
    1085           0 :             throw io::IOException();
    1086             : 
    1087           0 :         if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
    1088             :         {
    1089             :             // the document just already changed its storage to store to
    1090             :             // the links to OOo documents for now ignore this call
    1091             :             // TODO: OOo links will have persistence so it will be switched here
    1092             :         }
    1093           0 :         else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
    1094             :         {
    1095           0 :             if ( m_xRecoveryStorage.is() )
    1096           0 :                 TransferMediaType( m_xRecoveryStorage, m_xObjectStorage );
    1097             : 
    1098             :             // TODO:
    1099           0 :             m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
    1100             : 
    1101           0 :             if ( !m_pDocHolder->GetComponent().is() )
    1102           0 :                 throw io::IOException(); // TODO: can not create document
    1103             : 
    1104           0 :             m_nObjectState = embed::EmbedStates::RUNNING;
    1105             :         }
    1106           0 :         else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
    1107             :         {
    1108           0 :             m_pDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly );
    1109           0 :             m_nObjectState = embed::EmbedStates::RUNNING;
    1110             :         }
    1111             :         //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
    1112             :         //{
    1113             :             //TODO:
    1114             :         //}
    1115             :         else
    1116             :             throw lang::IllegalArgumentException( OUString( "Wrong connection mode is provided!\n" ),
    1117             :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
    1118           0 :                                         3 );
    1119           0 :     }
    1120             : }
    1121             : 
    1122             : 
    1123           0 : void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
    1124             :                             const OUString& sEntName,
    1125             :                             const uno::Sequence< beans::PropertyValue >& lArguments,
    1126             :                             const uno::Sequence< beans::PropertyValue >& lObjArgs )
    1127             :         throw ( lang::IllegalArgumentException,
    1128             :                 embed::WrongStateException,
    1129             :                 io::IOException,
    1130             :                 uno::Exception,
    1131             :                 uno::RuntimeException, std::exception )
    1132             : {
    1133             :     SAL_INFO( "embeddedobj.common", "embeddedobj (mv76033) OCommonEmbeddedObject::storeToEntry" );
    1134             : 
    1135           0 :     ::osl::ResettableMutexGuard aGuard( m_aMutex );
    1136           0 :     if ( m_bDisposed )
    1137           0 :         throw lang::DisposedException(); // TODO
    1138             : 
    1139           0 :     if ( m_nObjectState == -1 )
    1140             :     {
    1141             :         // the object is still not loaded
    1142             :         throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
    1143           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1144             :     }
    1145             : 
    1146           0 :     if ( m_bWaitSaveCompleted )
    1147             :         throw embed::WrongStateException(
    1148             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1149           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1150             : 
    1151             :     // for now support of this interface is required to allow breaking of links and converting them to normal embedded
    1152             :     // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
    1153             :     // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
    1154           0 :     if ( m_bIsLink )
    1155           0 :         return;
    1156             : 
    1157             :     OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
    1158             : 
    1159           0 :     sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
    1160           0 :     sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
    1161             :     try {
    1162           0 :         nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
    1163             :     }
    1164           0 :     catch ( const beans::IllegalTypeException& )
    1165             :     {
    1166             :         // the container just has an unknown type, use current file format
    1167             :     }
    1168           0 :     catch ( const uno::Exception& )
    1169             :     {
    1170             :         SAL_WARN( "embeddedobj.common", "Can not retrieve target storage media type!" );
    1171             :     }
    1172             : 
    1173             :     try
    1174             :     {
    1175           0 :         nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
    1176             :     }
    1177           0 :     catch ( const beans::IllegalTypeException& )
    1178             :     {
    1179             :         // the container just has an unknown type, use current file format
    1180             :     }
    1181           0 :     catch ( const uno::Exception& )
    1182             :     {
    1183             :         SAL_WARN( "embeddedobj.common", "Can not retrieve own storage media type!" );
    1184             :     }
    1185             : 
    1186           0 :     sal_Bool bTryOptimization = sal_False;
    1187           0 :     for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
    1188             :     {
    1189             :         // StoreVisualReplacement and VisualReplacement args have no sence here
    1190           0 :         if ( lObjArgs[nInd].Name == "CanTryOptimization" )
    1191           0 :             lObjArgs[nInd].Value >>= bTryOptimization;
    1192             :     }
    1193             : 
    1194           0 :     sal_Bool bSwitchBackToLoaded = sal_False;
    1195             : 
    1196             :     // Storing to different format can be done only in running state.
    1197           0 :     if ( m_nObjectState == embed::EmbedStates::LOADED )
    1198             :     {
    1199             :         // TODO/LATER: copying is not legal for documents with relative links.
    1200           0 :         if ( nTargetStorageFormat == nOriginalStorageFormat )
    1201             :         {
    1202           0 :             sal_Bool bOptimizationWorks = sal_False;
    1203           0 :             if ( bTryOptimization )
    1204             :             {
    1205             :                 try
    1206             :                 {
    1207             :                     // try to use optimized copying
    1208           0 :                     uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
    1209           0 :                     uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
    1210           0 :                     xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
    1211           0 :                     bOptimizationWorks = sal_True;
    1212             :                 }
    1213           0 :                 catch( const uno::Exception& )
    1214             :                 {
    1215             :                 }
    1216             :             }
    1217             : 
    1218           0 :             if ( !bOptimizationWorks )
    1219           0 :                 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
    1220             :         }
    1221             :         else
    1222             :         {
    1223           0 :             changeState( embed::EmbedStates::RUNNING );
    1224           0 :             bSwitchBackToLoaded = sal_True;
    1225             :         }
    1226             :     }
    1227             : 
    1228           0 :     if ( m_nObjectState != embed::EmbedStates::LOADED )
    1229             :     {
    1230             :         uno::Reference< embed::XStorage > xSubStorage =
    1231           0 :                     xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
    1232             : 
    1233           0 :         if ( !xSubStorage.is() )
    1234           0 :             throw uno::RuntimeException(); //TODO
    1235             : 
    1236           0 :         aGuard.clear();
    1237             :         // TODO/LATER: support hierarchical name for embedded objects in embedded objects
    1238           0 :         StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
    1239           0 :         aGuard.reset();
    1240             : 
    1241           0 :         if ( bSwitchBackToLoaded )
    1242           0 :             changeState( embed::EmbedStates::LOADED );
    1243           0 :     }
    1244             : 
    1245             :     // TODO: should the listener notification be done?
    1246             : }
    1247             : 
    1248             : 
    1249           0 : void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
    1250             :                             const OUString& sEntName,
    1251             :                             const uno::Sequence< beans::PropertyValue >& lArguments,
    1252             :                             const uno::Sequence< beans::PropertyValue >& lObjArgs )
    1253             :         throw ( lang::IllegalArgumentException,
    1254             :                 embed::WrongStateException,
    1255             :                 io::IOException,
    1256             :                 uno::Exception,
    1257             :                 uno::RuntimeException, std::exception )
    1258             : {
    1259             :     SAL_INFO( "embeddedobj.common", "embeddedobj (mv76033) OCommonEmbeddedObject::storeAsEntry" );
    1260             : 
    1261             :     // TODO: use lObjArgs
    1262             : 
    1263           0 :     ::osl::ResettableMutexGuard aGuard( m_aMutex );
    1264           0 :     if ( m_bDisposed )
    1265           0 :         throw lang::DisposedException(); // TODO
    1266             : 
    1267           0 :     if ( m_nObjectState == -1 )
    1268             :     {
    1269             :         // the object is still not loaded
    1270             :         throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
    1271           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1272             :     }
    1273             : 
    1274           0 :     if ( m_bWaitSaveCompleted )
    1275             :         throw embed::WrongStateException(
    1276             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1277           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1278             : 
    1279             :     // for now support of this interface is required to allow breaking of links and converting them to normal embedded
    1280             :     // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
    1281             :     // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
    1282           0 :     if ( m_bIsLink )
    1283             :     {
    1284           0 :         m_aNewEntryName = sEntName;
    1285           0 :         return;
    1286             :     }
    1287             : 
    1288             :     OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
    1289             : 
    1290           0 :     sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
    1291           0 :     sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
    1292             :     try {
    1293           0 :         nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
    1294             :     }
    1295           0 :     catch ( const beans::IllegalTypeException& )
    1296             :     {
    1297             :         // the container just has an unknown type, use current file format
    1298             :     }
    1299           0 :     catch ( const uno::Exception& )
    1300             :     {
    1301             :         SAL_WARN( "embeddedobj.common", "Can not retrieve target storage media type!" );
    1302             :     }
    1303             : 
    1304             :     try
    1305             :     {
    1306           0 :         nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
    1307             :     }
    1308           0 :     catch ( const beans::IllegalTypeException& )
    1309             :     {
    1310             :         // the container just has an unknown type, use current file format
    1311             :     }
    1312           0 :     catch ( const uno::Exception& )
    1313             :     {
    1314             :         SAL_WARN( "embeddedobj.common", "Can not retrieve own storage media type!" );
    1315             :     }
    1316             : 
    1317           0 :     PostEvent_Impl( OUString( "OnSaveAs" ) );
    1318             : 
    1319           0 :     sal_Bool bTryOptimization = sal_False;
    1320           0 :     for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
    1321             :     {
    1322             :         // StoreVisualReplacement and VisualReplacement args have no sence here
    1323           0 :         if ( lObjArgs[nInd].Name == "CanTryOptimization" )
    1324           0 :             lObjArgs[nInd].Value >>= bTryOptimization;
    1325             :     }
    1326             : 
    1327           0 :     sal_Bool bSwitchBackToLoaded = sal_False;
    1328             : 
    1329             :     // Storing to different format can be done only in running state.
    1330           0 :     if ( m_nObjectState == embed::EmbedStates::LOADED )
    1331             :     {
    1332             :         // TODO/LATER: copying is not legal for documents with relative links.
    1333           0 :         if ( nTargetStorageFormat == nOriginalStorageFormat )
    1334             :         {
    1335           0 :             sal_Bool bOptimizationWorks = sal_False;
    1336           0 :             if ( bTryOptimization )
    1337             :             {
    1338             :                 try
    1339             :                 {
    1340             :                     // try to use optimized copying
    1341           0 :                     uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
    1342           0 :                     uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
    1343           0 :                     xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
    1344           0 :                     bOptimizationWorks = sal_True;
    1345             :                 }
    1346           0 :                 catch( const uno::Exception& )
    1347             :                 {
    1348             :                 }
    1349             :             }
    1350             : 
    1351           0 :             if ( !bOptimizationWorks )
    1352           0 :                 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
    1353             :         }
    1354             :         else
    1355             :         {
    1356           0 :             changeState( embed::EmbedStates::RUNNING );
    1357           0 :             bSwitchBackToLoaded = sal_True;
    1358             :         }
    1359             :     }
    1360             : 
    1361             :     uno::Reference< embed::XStorage > xSubStorage =
    1362           0 :                 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
    1363             : 
    1364           0 :     if ( !xSubStorage.is() )
    1365           0 :         throw uno::RuntimeException(); //TODO
    1366             : 
    1367           0 :     if ( m_nObjectState != embed::EmbedStates::LOADED )
    1368             :     {
    1369           0 :         aGuard.clear();
    1370             :         // TODO/LATER: support hierarchical name for embedded objects in embedded objects
    1371           0 :         StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
    1372           0 :         aGuard.reset();
    1373             : 
    1374           0 :         if ( bSwitchBackToLoaded )
    1375           0 :             changeState( embed::EmbedStates::LOADED );
    1376             :     }
    1377             : 
    1378           0 :     m_bWaitSaveCompleted = sal_True;
    1379           0 :     m_xNewObjectStorage = xSubStorage;
    1380           0 :     m_xNewParentStorage = xStorage;
    1381           0 :     m_aNewEntryName = sEntName;
    1382           0 :     m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
    1383             : 
    1384             :     // TODO: register listeners for storages above, in case thay are disposed
    1385             :     //       an exception will be thrown on saveCompleted( true )
    1386             : 
    1387             :     // TODO: should the listener notification be done here or in saveCompleted?
    1388             : }
    1389             : 
    1390             : 
    1391           0 : void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
    1392             :         throw ( embed::WrongStateException,
    1393             :                 uno::Exception,
    1394             :                 uno::RuntimeException, std::exception )
    1395             : {
    1396             :     SAL_INFO( "embeddedobj.common", "embeddedobj (mv76033) OCommonEmbeddedObject::saveCompleted" );
    1397             : 
    1398           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1399           0 :     if ( m_bDisposed )
    1400           0 :         throw lang::DisposedException(); // TODO
    1401             : 
    1402           0 :     if ( m_nObjectState == -1 )
    1403             :     {
    1404             :         // the object is still not loaded
    1405             :         throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
    1406           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1407             :     }
    1408             : 
    1409             :     // for now support of this interface is required to allow breaking of links and converting them to normal embedded
    1410             :     // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
    1411             :     // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
    1412           0 :     if ( m_bIsLink )
    1413             :     {
    1414           0 :         if ( bUseNew )
    1415           0 :             m_aEntryName = m_aNewEntryName;
    1416           0 :         m_aNewEntryName = OUString();
    1417           0 :         return;
    1418             :     }
    1419             : 
    1420             :     // it is allowed to call saveCompleted( false ) for nonstored objects
    1421           0 :     if ( !m_bWaitSaveCompleted && !bUseNew )
    1422           0 :         return;
    1423             : 
    1424             :     SAL_WARN_IF( !m_bWaitSaveCompleted, "embeddedobj.common", "Unexpected saveCompleted() call!" );
    1425           0 :     if ( !m_bWaitSaveCompleted )
    1426           0 :         throw io::IOException(); // TODO: illegal call
    1427             : 
    1428             :     OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
    1429           0 :     if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() )
    1430           0 :         throw uno::RuntimeException(); // TODO: broken internal information
    1431             : 
    1432           0 :     if ( bUseNew )
    1433             :     {
    1434           0 :         SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStorage, m_aNewEntryName );
    1435           0 :         m_aDocMediaDescriptor = m_aNewDocMediaDescriptor;
    1436             : 
    1437           0 :         uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
    1438           0 :         if ( xModif.is() )
    1439           0 :             xModif->setModified( sal_False );
    1440             : 
    1441           0 :         PostEvent_Impl( OUString( "OnSaveAsDone" ));
    1442             :     }
    1443             :     else
    1444             :     {
    1445             :         try {
    1446           0 :             uno::Reference< lang::XComponent > xComponent( m_xNewObjectStorage, uno::UNO_QUERY );
    1447             :             SAL_WARN_IF( !xComponent.is(), "embeddedobj.common", "Wrong storage implementation!" );
    1448           0 :             if ( xComponent.is() )
    1449           0 :                 xComponent->dispose();
    1450             :         }
    1451           0 :         catch ( const uno::Exception& )
    1452             :         {
    1453             :         }
    1454             :     }
    1455             : 
    1456           0 :     m_xNewObjectStorage = uno::Reference< embed::XStorage >();
    1457           0 :     m_xNewParentStorage = uno::Reference< embed::XStorage >();
    1458           0 :     m_aNewEntryName = OUString();
    1459           0 :     m_aNewDocMediaDescriptor.realloc( 0 );
    1460           0 :     m_bWaitSaveCompleted = sal_False;
    1461             : 
    1462           0 :     if ( bUseNew )
    1463             :     {
    1464             :         // TODO: notify listeners
    1465             : 
    1466           0 :         if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
    1467             :         {
    1468             :             // TODO: update visual representation
    1469             :         }
    1470           0 :     }
    1471             : }
    1472             : 
    1473             : 
    1474           0 : sal_Bool SAL_CALL OCommonEmbeddedObject::hasEntry()
    1475             :         throw ( embed::WrongStateException,
    1476             :                 uno::RuntimeException, std::exception )
    1477             : {
    1478           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1479           0 :     if ( m_bDisposed )
    1480           0 :         throw lang::DisposedException(); // TODO
    1481             : 
    1482           0 :     if ( m_bWaitSaveCompleted )
    1483             :         throw embed::WrongStateException(
    1484             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1485           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1486             : 
    1487           0 :     if ( m_xObjectStorage.is() )
    1488           0 :         return sal_True;
    1489             : 
    1490           0 :     return sal_False;
    1491             : }
    1492             : 
    1493             : 
    1494           0 : OUString SAL_CALL OCommonEmbeddedObject::getEntryName()
    1495             :         throw ( embed::WrongStateException,
    1496             :                 uno::RuntimeException, std::exception )
    1497             : {
    1498           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1499           0 :     if ( m_bDisposed )
    1500           0 :         throw lang::DisposedException(); // TODO
    1501             : 
    1502           0 :     if ( m_nObjectState == -1 )
    1503             :     {
    1504             :         // the object is still not loaded
    1505             :         throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
    1506           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1507             :     }
    1508             : 
    1509           0 :     if ( m_bWaitSaveCompleted )
    1510             :         throw embed::WrongStateException(
    1511             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1512           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1513             : 
    1514           0 :     return m_aEntryName;
    1515             : }
    1516             : 
    1517             : 
    1518           0 : void SAL_CALL OCommonEmbeddedObject::storeOwn()
    1519             :         throw ( embed::WrongStateException,
    1520             :                 io::IOException,
    1521             :                 uno::Exception,
    1522             :                 uno::RuntimeException, std::exception )
    1523             : {
    1524             :     SAL_INFO( "embeddedobj.common", "embeddedobj (mv76033) OCommonEmbeddedObject::storeOwn" );
    1525             : 
    1526             :     // during switching from Activated to Running and from Running to Loaded states the object will
    1527             :     // ask container to store the object, the container has to make decision
    1528             :     // to do so or not
    1529             : 
    1530           0 :     ::osl::ResettableMutexGuard aGuard( m_aMutex );
    1531           0 :     if ( m_bDisposed )
    1532           0 :         throw lang::DisposedException(); // TODO
    1533             : 
    1534           0 :     if ( m_nObjectState == -1 )
    1535             :     {
    1536             :         // the object is still not loaded
    1537             :         throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
    1538           0 :                                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1539             :     }
    1540             : 
    1541           0 :     if ( m_bWaitSaveCompleted )
    1542             :         throw embed::WrongStateException(
    1543             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1544           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1545             : 
    1546           0 :     if ( m_bReadOnly )
    1547           0 :         throw io::IOException(); // TODO: access denied
    1548             : 
    1549             :     // nothing to do, if the object is in loaded state
    1550           0 :     if ( m_nObjectState == embed::EmbedStates::LOADED )
    1551           0 :         return;
    1552             : 
    1553           0 :     PostEvent_Impl( OUString( "OnSave" ) );
    1554             : 
    1555             :     SAL_WARN_IF( !m_pDocHolder->GetComponent().is(), "embeddedobj.common", "If an object is activated or in running state it must have a document!" );
    1556           0 :     if ( !m_pDocHolder->GetComponent().is() )
    1557           0 :         throw uno::RuntimeException();
    1558             : 
    1559           0 :     if ( m_bIsLink )
    1560             :     {
    1561             :         // TODO: just store the document to it's location
    1562           0 :         uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
    1563           0 :         if ( !xStorable.is() )
    1564           0 :             throw uno::RuntimeException(); // TODO
    1565             : 
    1566             :         // free the main mutex for the storing time
    1567           0 :         aGuard.clear();
    1568             : 
    1569           0 :         xStorable->store();
    1570             : 
    1571           0 :         aGuard.reset();
    1572             :     }
    1573             :     else
    1574             :     {
    1575             :         OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
    1576             : 
    1577           0 :         if ( !m_xObjectStorage.is() )
    1578           0 :             throw io::IOException(); //TODO: access denied
    1579             : 
    1580           0 :         sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
    1581             :         try {
    1582           0 :             nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
    1583             :         }
    1584           0 :         catch ( const beans::IllegalTypeException& )
    1585             :         {
    1586             :             // the container just has an unknown type, use current file format
    1587             :         }
    1588           0 :         catch ( const uno::Exception& )
    1589             :         {
    1590             :             SAL_WARN( "embeddedobj.common", "Can not retrieve storage media type!" );
    1591             :         }
    1592             : 
    1593           0 :         aGuard.clear();
    1594           0 :         StoreDocToStorage_Impl( m_xObjectStorage, nStorageFormat, GetBaseURL_Impl(), m_aEntryName, sal_True );
    1595           0 :         aGuard.reset();
    1596             :     }
    1597             : 
    1598           0 :     uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
    1599           0 :     if ( xModif.is() )
    1600           0 :         xModif->setModified( sal_False );
    1601             : 
    1602           0 :     PostEvent_Impl( OUString( "OnSaveDone" ) );
    1603             : }
    1604             : 
    1605             : 
    1606           0 : sal_Bool SAL_CALL OCommonEmbeddedObject::isReadonly()
    1607             :         throw ( embed::WrongStateException,
    1608             :                 uno::RuntimeException, std::exception )
    1609             : {
    1610           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1611           0 :     if ( m_bDisposed )
    1612           0 :         throw lang::DisposedException(); // TODO
    1613             : 
    1614           0 :     if ( m_nObjectState == -1 )
    1615             :     {
    1616             :         // the object is still not loaded
    1617             :         throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
    1618           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1619             :     }
    1620             : 
    1621           0 :     if ( m_bWaitSaveCompleted )
    1622             :         throw embed::WrongStateException(
    1623             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1624           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1625             : 
    1626           0 :     return m_bReadOnly;
    1627             : }
    1628             : 
    1629             : 
    1630           0 : void SAL_CALL OCommonEmbeddedObject::reload(
    1631             :                 const uno::Sequence< beans::PropertyValue >& lArguments,
    1632             :                 const uno::Sequence< beans::PropertyValue >& lObjArgs )
    1633             :         throw ( lang::IllegalArgumentException,
    1634             :                 embed::WrongStateException,
    1635             :                 io::IOException,
    1636             :                 uno::Exception,
    1637             :                 uno::RuntimeException, std::exception )
    1638             : {
    1639             :     // TODO: use lObjArgs
    1640             :     // for now this method is used only to switch readonly state
    1641             : 
    1642           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1643           0 :     if ( m_bDisposed )
    1644           0 :         throw lang::DisposedException(); // TODO
    1645             : 
    1646           0 :     if ( m_nObjectState == -1 )
    1647             :     {
    1648             :         // the object is still not loaded
    1649             :         throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
    1650           0 :                                         uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1651             :     }
    1652             : 
    1653           0 :     if ( m_nObjectState != embed::EmbedStates::LOADED )
    1654             :     {
    1655             :         // the object is still not loaded
    1656             :         throw embed::WrongStateException(
    1657             :                                 OUString( "The object must be in loaded state to be reloaded!\n" ),
    1658           0 :                                 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1659             :     }
    1660             : 
    1661           0 :     if ( m_bWaitSaveCompleted )
    1662             :         throw embed::WrongStateException(
    1663             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1664           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1665             : 
    1666           0 :     if ( m_bIsLink )
    1667             :     {
    1668             :         // reload of the link
    1669           0 :         OUString aOldLinkFilter = m_aLinkFilterName;
    1670             : 
    1671           0 :         OUString aNewLinkFilter;
    1672           0 :         for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
    1673             :         {
    1674           0 :             if ( lArguments[nInd].Name == "URL" )
    1675             :             {
    1676             :                 // the new URL
    1677           0 :                 lArguments[nInd].Value >>= m_aLinkURL;
    1678           0 :                 m_aLinkFilterName = OUString();
    1679             :             }
    1680           0 :             else if ( lArguments[nInd].Name == "FilterName" )
    1681             :             {
    1682           0 :                 lArguments[nInd].Value >>= aNewLinkFilter;
    1683           0 :                 m_aLinkFilterName = OUString();
    1684             :             }
    1685             :         }
    1686             : 
    1687           0 :         ::comphelper::MimeConfigurationHelper aHelper( m_xContext );
    1688           0 :         if ( m_aLinkFilterName.isEmpty() )
    1689             :         {
    1690           0 :             if ( !aNewLinkFilter.isEmpty() )
    1691           0 :                 m_aLinkFilterName = aNewLinkFilter;
    1692             :             else
    1693             :             {
    1694           0 :                 uno::Sequence< beans::PropertyValue > aArgs( 1 );
    1695           0 :                 aArgs[0].Name = "URL";
    1696           0 :                 aArgs[0].Value <<= m_aLinkURL;
    1697           0 :                 m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, false );
    1698             :             }
    1699             :         }
    1700             : 
    1701           0 :         if ( !aOldLinkFilter.equals( m_aLinkFilterName ) )
    1702             :         {
    1703           0 :             uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName );
    1704             : 
    1705             :             // TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor
    1706           0 :             m_pDocHolder->release();
    1707           0 :             m_pDocHolder = NULL;
    1708             : 
    1709           0 :             LinkInit_Impl( aObject, lArguments, lObjArgs );
    1710           0 :         }
    1711             :     }
    1712             : 
    1713           0 :     m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
    1714             : 
    1715             :     // TODO: use lObjArgs for StoreVisualReplacement
    1716           0 :     for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
    1717           0 :         if ( lObjArgs[nObjInd].Name == "OutplaceDispatchInterceptor" )
    1718             :         {
    1719           0 :             uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
    1720           0 :             if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
    1721           0 :                 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
    1722             : 
    1723           0 :             break;
    1724             :         }
    1725             : 
    1726             :     // TODO:
    1727             :     // when document allows reloading through API the object can be reloaded not only in loaded state
    1728             : 
    1729           0 :     sal_Bool bOldReadOnlyValue = m_bReadOnly;
    1730             : 
    1731           0 :     m_bReadOnly = sal_False;
    1732           0 :     for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
    1733           0 :         if ( lArguments[nInd].Name == "ReadOnly" )
    1734           0 :             lArguments[nInd].Value >>= m_bReadOnly;
    1735             : 
    1736           0 :     if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink )
    1737             :     {
    1738             :         // close own storage
    1739             :         try {
    1740           0 :             uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
    1741             :             OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
    1742           0 :             if ( xComponent.is() )
    1743           0 :                 xComponent->dispose();
    1744             :         }
    1745           0 :         catch ( const uno::Exception& )
    1746             :         {
    1747             :         }
    1748             : 
    1749           0 :         sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
    1750           0 :         m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode );
    1751           0 :     }
    1752           0 : }
    1753             : 
    1754             : 
    1755           0 : void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
    1756             :                                                 const OUString& sEntName )
    1757             :         throw ( lang::IllegalArgumentException,
    1758             :                 embed::WrongStateException,
    1759             :                 io::IOException,
    1760             :                 uno::Exception,
    1761             :                 uno::RuntimeException, std::exception )
    1762             : {
    1763           0 :     ::osl::ResettableMutexGuard aGuard( m_aMutex );
    1764           0 :     if ( m_bDisposed )
    1765           0 :         throw lang::DisposedException(); // TODO
    1766             : 
    1767           0 :     if ( !m_bIsLink )
    1768             :     {
    1769             :         // it must be a linked initialized object
    1770             :         throw embed::WrongStateException(
    1771             :                     OUString( "The object is not a valid linked object!\n" ),
    1772           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1773             :     }
    1774             :     else
    1775             :     {
    1776             :         // the current implementation of OOo links does not implement this method since it does not implement
    1777             :         // all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ).
    1778             :     }
    1779             : 
    1780           0 :     if ( !xStorage.is() )
    1781             :         throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
    1782             :                                             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
    1783           0 :                                             1 );
    1784             : 
    1785           0 :     if ( sEntName.isEmpty() )
    1786             :         throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
    1787             :                                             uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
    1788           0 :                                             2 );
    1789             : 
    1790           0 :     if ( !m_bIsLink || m_nObjectState == -1 )
    1791             :     {
    1792             :         // it must be a linked initialized object
    1793             :         throw embed::WrongStateException(
    1794             :                     OUString( "The object is not a valid linked object!\n" ),
    1795           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1796             :     }
    1797             : 
    1798           0 :     if ( m_bWaitSaveCompleted )
    1799             :         throw embed::WrongStateException(
    1800             :                     OUString( "The object waits for saveCompleted() call!\n" ),
    1801           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1802             : 
    1803           0 :     uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
    1804           0 :     if ( !xNameAccess.is() )
    1805           0 :         throw uno::RuntimeException(); //TODO
    1806             : 
    1807             :     // detect entry existence
    1808           0 :     /*sal_Bool bElExists =*/ xNameAccess->hasByName( sEntName );
    1809             : 
    1810           0 :     m_bReadOnly = sal_False;
    1811             : 
    1812           0 :     if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
    1813           0 :         SwitchOwnPersistence( xStorage, sEntName );
    1814             : 
    1815             :     // for linked object it means that it becomes embedded object
    1816             :     // the document must switch it's persistence also
    1817             : 
    1818             :     // TODO/LATER: handle the case when temp doc can not be created
    1819             :     // the document is a new embedded object so it must be marked as modified
    1820           0 :     uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
    1821           0 :     uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
    1822           0 :     if ( !xModif.is() )
    1823           0 :         throw uno::RuntimeException();
    1824             :     try
    1825             :     {
    1826           0 :         xModif->setModified( sal_True );
    1827             :     }
    1828           0 :     catch( const uno::Exception& )
    1829             :     {}
    1830             : 
    1831           0 :     m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
    1832             :     SAL_WARN_IF( !m_pDocHolder->GetComponent().is(), "embeddedobj.common", "If document cant be created, an exception must be thrown!" );
    1833             : 
    1834           0 :     if ( m_nObjectState == embed::EmbedStates::LOADED )
    1835             :     {
    1836             :         // the state is changed and can not be switched to loaded state back without saving
    1837           0 :         m_nObjectState = embed::EmbedStates::RUNNING;
    1838           0 :         StateChangeNotification_Impl( sal_False, embed::EmbedStates::LOADED, m_nObjectState, aGuard );
    1839             :     }
    1840           0 :     else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
    1841           0 :         m_pDocHolder->Show();
    1842             : 
    1843           0 :     m_bIsLink = sal_False;
    1844           0 :     m_aLinkFilterName = OUString();
    1845           0 :     m_aLinkURL = OUString();
    1846           0 : }
    1847             : 
    1848             : 
    1849           0 : sal_Bool SAL_CALL  OCommonEmbeddedObject::isLink()
    1850             :         throw ( embed::WrongStateException,
    1851             :                 uno::RuntimeException, std::exception )
    1852             : {
    1853           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1854           0 :     if ( m_bDisposed )
    1855           0 :         throw lang::DisposedException(); // TODO
    1856             : 
    1857           0 :     return m_bIsLink;
    1858             : }
    1859             : 
    1860             : 
    1861           0 : OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
    1862             :         throw ( embed::WrongStateException,
    1863             :                 uno::Exception,
    1864             :                 uno::RuntimeException, std::exception )
    1865             : {
    1866           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1867           0 :     if ( m_bDisposed )
    1868           0 :         throw lang::DisposedException(); // TODO
    1869             : 
    1870           0 :     if ( !m_bIsLink )
    1871             :         throw embed::WrongStateException(
    1872             :                     OUString( "The object is not a link object!\n" ),
    1873           0 :                     uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    1874             : 
    1875           0 :     return m_aLinkURL;
    1876             : }
    1877             : 
    1878             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10