1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sot.hxx" 26 #include <com/sun/star/uno/Reference.hxx> 27 #include <com/sun/star/embed/XTransactionBroadcaster.hpp> 28 #include <com/sun/star/embed/ElementModes.hpp> 29 #include <com/sun/star/lang/XComponent.hpp> 30 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 31 32 #include <comphelper/processfactory.hxx> 33 34 #include "unostorageholder.hxx" 35 #include <sot/storinfo.hxx> 36 37 38 using namespace ::com::sun::star; 39 40 UNOStorageHolder::UNOStorageHolder( SotStorage& aParentStorage, 41 SotStorage& aStorage, 42 uno::Reference< embed::XStorage > xStorage, 43 ::utl::TempFile* pTempFile ) 44 : m_pParentStorage( &aParentStorage ) 45 , m_rSotStorage( &aStorage ) 46 , m_xStorage( xStorage ) 47 , m_pTempFile( pTempFile ) 48 { 49 OSL_ENSURE( m_xStorage.is() && m_pTempFile, "Wrong initialization!\n" ); 50 if ( !m_xStorage.is() || !m_pTempFile ) 51 throw uno::RuntimeException(); 52 53 uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY ); 54 if ( !xTrBroadcast.is() ) 55 throw uno::RuntimeException(); 56 57 xTrBroadcast->addTransactionListener( (embed::XTransactionListener*)this ); 58 } 59 60 void UNOStorageHolder::InternalDispose() 61 { 62 uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY ); 63 if ( xTrBroadcast.is() ) 64 xTrBroadcast->removeTransactionListener( (embed::XTransactionListener*)this ); 65 66 uno::Reference< lang::XComponent > xComponent( m_xStorage, uno::UNO_QUERY ); 67 if ( xComponent.is() ) 68 xComponent->dispose(); 69 m_xStorage = uno::Reference< embed::XStorage >(); 70 71 if ( m_pParentStorage ) 72 m_pParentStorage = NULL; 73 74 if ( m_pTempFile ) 75 { 76 delete m_pTempFile; 77 m_pTempFile = NULL; 78 } 79 80 if ( m_rSotStorage.Is() ) 81 m_rSotStorage = NULL; 82 } 83 84 String UNOStorageHolder::GetStorageName() 85 { 86 if ( m_rSotStorage.Is() ) 87 return m_rSotStorage->GetName(); 88 89 return String(); 90 } 91 92 void SAL_CALL UNOStorageHolder::preCommit( const lang::EventObject& /*aEvent*/ ) 93 { 94 // do nothing 95 } 96 97 void SAL_CALL UNOStorageHolder::commited( const lang::EventObject& /*aEvent*/ ) 98 { 99 ::utl::TempFile aTmpStorFile; 100 if ( !aTmpStorFile.GetURL().Len() ) 101 throw uno::RuntimeException(); 102 103 uno::Reference< lang::XSingleServiceFactory > xStorageFactory( 104 ::comphelper::getProcessServiceFactory()->createInstance( 105 ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 106 uno::UNO_QUERY ); 107 108 OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" ); 109 if ( !xStorageFactory.is() ) 110 throw uno::RuntimeException(); 111 112 uno::Sequence< uno::Any > aArg( 2 ); 113 aArg[0] <<= ::rtl::OUString( aTmpStorFile.GetURL() ); 114 aArg[1] <<= embed::ElementModes::READWRITE; 115 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArg ), uno::UNO_QUERY ); 116 117 OSL_ENSURE( xTempStorage.is(), "Can't open storage!\n" ); 118 if ( !xTempStorage.is() ) 119 throw uno::RuntimeException(); 120 121 m_xStorage->copyToStorage( xTempStorage ); 122 123 uno::Reference< lang::XComponent > xComp( xTempStorage, uno::UNO_QUERY ); 124 if ( !xComp.is() ) 125 throw uno::RuntimeException(); 126 127 xComp->dispose(); 128 129 SotStorageRef rTempStorage = new SotStorage( sal_True, aTmpStorFile.GetURL(), STREAM_WRITE, STORAGE_TRANSACTED ); 130 if ( !rTempStorage.Is() || rTempStorage->GetError() != ERRCODE_NONE ) 131 throw uno::RuntimeException(); 132 133 SvStorageInfoList aSubStorInfoList; 134 m_rSotStorage->FillInfoList( &aSubStorInfoList ); 135 for ( sal_uInt32 nInd = 0; nInd < aSubStorInfoList.Count(); nInd++ ) 136 { 137 m_rSotStorage->Remove( aSubStorInfoList[nInd].GetName() ); 138 if ( m_rSotStorage->GetError() ) 139 { 140 m_rSotStorage->ResetError(); 141 throw uno::RuntimeException(); 142 } 143 } 144 145 rTempStorage->CopyTo( m_rSotStorage ); 146 147 // CopyTo does not transport unknown media type 148 // just workaround it 149 uno::Any aMediaType; 150 if ( rTempStorage->GetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) ) 151 m_rSotStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ); 152 153 m_rSotStorage->Commit(); 154 } 155 156 void SAL_CALL UNOStorageHolder::preRevert( const lang::EventObject& /*aEvent*/ ) 157 { 158 // do nothing 159 } 160 161 void SAL_CALL UNOStorageHolder::reverted( const lang::EventObject& /*aEvent*/ ) 162 { 163 // do nothing, since reverting of the duplicate storage just means 164 // not to copy changes done for it to the original storage 165 } 166 167 void SAL_CALL UNOStorageHolder::disposing( const lang::EventObject& /*Source*/ ) 168 { 169 if ( m_pTempFile ) 170 { 171 delete m_pTempFile; 172 m_pTempFile = NULL; 173 } 174 175 if ( m_rSotStorage.Is() ) 176 m_rSotStorage = NULL; 177 178 if ( m_pParentStorage ) 179 { 180 SotStorage* pTmp = m_pParentStorage; 181 m_pParentStorage = NULL; 182 pTmp->RemoveUNOStorageHolder( this ); // this statement can lead to destruction of the holder 183 } 184 } 185