1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sot.hxx" 30 #include <com/sun/star/uno/Reference.hxx> 31 #include <com/sun/star/embed/XTransactionBroadcaster.hpp> 32 #include <com/sun/star/embed/ElementModes.hpp> 33 #include <com/sun/star/lang/XComponent.hpp> 34 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 35 36 #include <comphelper/processfactory.hxx> 37 38 #include "unostorageholder.hxx" 39 #include <sot/storinfo.hxx> 40 41 42 using namespace ::com::sun::star; 43 44 UNOStorageHolder::UNOStorageHolder( SotStorage& aParentStorage, 45 SotStorage& aStorage, 46 uno::Reference< embed::XStorage > xStorage, 47 ::utl::TempFile* pTempFile ) 48 : m_pParentStorage( &aParentStorage ) 49 , m_rSotStorage( &aStorage ) 50 , m_xStorage( xStorage ) 51 , m_pTempFile( pTempFile ) 52 { 53 OSL_ENSURE( m_xStorage.is() && m_pTempFile, "Wrong initialization!\n" ); 54 if ( !m_xStorage.is() || !m_pTempFile ) 55 throw uno::RuntimeException(); 56 57 uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY ); 58 if ( !xTrBroadcast.is() ) 59 throw uno::RuntimeException(); 60 61 xTrBroadcast->addTransactionListener( (embed::XTransactionListener*)this ); 62 } 63 64 void UNOStorageHolder::InternalDispose() 65 { 66 uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY ); 67 if ( xTrBroadcast.is() ) 68 xTrBroadcast->removeTransactionListener( (embed::XTransactionListener*)this ); 69 70 uno::Reference< lang::XComponent > xComponent( m_xStorage, uno::UNO_QUERY ); 71 if ( xComponent.is() ) 72 xComponent->dispose(); 73 m_xStorage = uno::Reference< embed::XStorage >(); 74 75 if ( m_pParentStorage ) 76 m_pParentStorage = NULL; 77 78 if ( m_pTempFile ) 79 { 80 delete m_pTempFile; 81 m_pTempFile = NULL; 82 } 83 84 if ( m_rSotStorage.Is() ) 85 m_rSotStorage = NULL; 86 } 87 88 String UNOStorageHolder::GetStorageName() 89 { 90 if ( m_rSotStorage.Is() ) 91 return m_rSotStorage->GetName(); 92 93 return String(); 94 } 95 96 void SAL_CALL UNOStorageHolder::preCommit( const lang::EventObject& /*aEvent*/ ) 97 throw ( uno::Exception, 98 uno::RuntimeException ) 99 { 100 // do nothing 101 } 102 103 void SAL_CALL UNOStorageHolder::commited( const lang::EventObject& /*aEvent*/ ) 104 throw ( uno::RuntimeException ) 105 { 106 ::utl::TempFile aTmpStorFile; 107 if ( !aTmpStorFile.GetURL().Len() ) 108 throw uno::RuntimeException(); 109 110 uno::Reference< lang::XSingleServiceFactory > xStorageFactory( 111 ::comphelper::getProcessServiceFactory()->createInstance( 112 ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 113 uno::UNO_QUERY ); 114 115 OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" ); 116 if ( !xStorageFactory.is() ) 117 throw uno::RuntimeException(); 118 119 uno::Sequence< uno::Any > aArg( 2 ); 120 aArg[0] <<= ::rtl::OUString( aTmpStorFile.GetURL() ); 121 aArg[1] <<= embed::ElementModes::READWRITE; 122 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArg ), uno::UNO_QUERY ); 123 124 OSL_ENSURE( xTempStorage.is(), "Can't open storage!\n" ); 125 if ( !xTempStorage.is() ) 126 throw uno::RuntimeException(); 127 128 m_xStorage->copyToStorage( xTempStorage ); 129 130 uno::Reference< lang::XComponent > xComp( xTempStorage, uno::UNO_QUERY ); 131 if ( !xComp.is() ) 132 throw uno::RuntimeException(); 133 134 xComp->dispose(); 135 136 SotStorageRef rTempStorage = new SotStorage( sal_True, aTmpStorFile.GetURL(), STREAM_WRITE, STORAGE_TRANSACTED ); 137 if ( !rTempStorage.Is() || rTempStorage->GetError() != ERRCODE_NONE ) 138 throw uno::RuntimeException(); 139 140 SvStorageInfoList aSubStorInfoList; 141 m_rSotStorage->FillInfoList( &aSubStorInfoList ); 142 for ( sal_uInt32 nInd = 0; nInd < aSubStorInfoList.Count(); nInd++ ) 143 { 144 m_rSotStorage->Remove( aSubStorInfoList[nInd].GetName() ); 145 if ( m_rSotStorage->GetError() ) 146 { 147 m_rSotStorage->ResetError(); 148 throw uno::RuntimeException(); 149 } 150 } 151 152 rTempStorage->CopyTo( m_rSotStorage ); 153 154 // CopyTo does not transport unknown media type 155 // just workaround it 156 uno::Any aMediaType; 157 if ( rTempStorage->GetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) ) 158 m_rSotStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ); 159 160 m_rSotStorage->Commit(); 161 } 162 163 void SAL_CALL UNOStorageHolder::preRevert( const lang::EventObject& /*aEvent*/ ) 164 throw ( uno::Exception, 165 uno::RuntimeException ) 166 { 167 // do nothing 168 } 169 170 void SAL_CALL UNOStorageHolder::reverted( const lang::EventObject& /*aEvent*/ ) 171 throw ( uno::RuntimeException ) 172 { 173 // do nothing, since reverting of the duplicate storage just means 174 // not to copy changes done for it to the original storage 175 } 176 177 void SAL_CALL UNOStorageHolder::disposing( const lang::EventObject& /*Source*/ ) 178 throw ( uno::RuntimeException ) 179 { 180 if ( m_pTempFile ) 181 { 182 delete m_pTempFile; 183 m_pTempFile = NULL; 184 } 185 186 if ( m_rSotStorage.Is() ) 187 m_rSotStorage = NULL; 188 189 if ( m_pParentStorage ) 190 { 191 SotStorage* pTmp = m_pParentStorage; 192 m_pParentStorage = NULL; 193 pTmp->RemoveUNOStorageHolder( this ); // this statement can lead to destruction of the holder 194 } 195 } 196 197 198