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 throw ( uno::Exception, 94 uno::RuntimeException ) 95 { 96 // do nothing 97 } 98 99 void SAL_CALL UNOStorageHolder::commited( const lang::EventObject& /*aEvent*/ ) 100 throw ( uno::RuntimeException ) 101 { 102 ::utl::TempFile aTmpStorFile; 103 if ( !aTmpStorFile.GetURL().Len() ) 104 throw uno::RuntimeException(); 105 106 uno::Reference< lang::XSingleServiceFactory > xStorageFactory( 107 ::comphelper::getProcessServiceFactory()->createInstance( 108 ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 109 uno::UNO_QUERY ); 110 111 OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" ); 112 if ( !xStorageFactory.is() ) 113 throw uno::RuntimeException(); 114 115 uno::Sequence< uno::Any > aArg( 2 ); 116 aArg[0] <<= ::rtl::OUString( aTmpStorFile.GetURL() ); 117 aArg[1] <<= embed::ElementModes::READWRITE; 118 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArg ), uno::UNO_QUERY ); 119 120 OSL_ENSURE( xTempStorage.is(), "Can't open storage!\n" ); 121 if ( !xTempStorage.is() ) 122 throw uno::RuntimeException(); 123 124 m_xStorage->copyToStorage( xTempStorage ); 125 126 uno::Reference< lang::XComponent > xComp( xTempStorage, uno::UNO_QUERY ); 127 if ( !xComp.is() ) 128 throw uno::RuntimeException(); 129 130 xComp->dispose(); 131 132 SotStorageRef rTempStorage = new SotStorage( sal_True, aTmpStorFile.GetURL(), STREAM_WRITE, STORAGE_TRANSACTED ); 133 if ( !rTempStorage.Is() || rTempStorage->GetError() != ERRCODE_NONE ) 134 throw uno::RuntimeException(); 135 136 SvStorageInfoList aSubStorInfoList; 137 m_rSotStorage->FillInfoList( &aSubStorInfoList ); 138 for ( sal_uInt32 nInd = 0; nInd < aSubStorInfoList.Count(); nInd++ ) 139 { 140 m_rSotStorage->Remove( aSubStorInfoList[nInd].GetName() ); 141 if ( m_rSotStorage->GetError() ) 142 { 143 m_rSotStorage->ResetError(); 144 throw uno::RuntimeException(); 145 } 146 } 147 148 rTempStorage->CopyTo( m_rSotStorage ); 149 150 // CopyTo does not transport unknown media type 151 // just workaround it 152 uno::Any aMediaType; 153 if ( rTempStorage->GetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) ) 154 m_rSotStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ); 155 156 m_rSotStorage->Commit(); 157 } 158 159 void SAL_CALL UNOStorageHolder::preRevert( const lang::EventObject& /*aEvent*/ ) 160 throw ( uno::Exception, 161 uno::RuntimeException ) 162 { 163 // do nothing 164 } 165 166 void SAL_CALL UNOStorageHolder::reverted( const lang::EventObject& /*aEvent*/ ) 167 throw ( uno::RuntimeException ) 168 { 169 // do nothing, since reverting of the duplicate storage just means 170 // not to copy changes done for it to the original storage 171 } 172 173 void SAL_CALL UNOStorageHolder::disposing( const lang::EventObject& /*Source*/ ) 174 throw ( uno::RuntimeException ) 175 { 176 if ( m_pTempFile ) 177 { 178 delete m_pTempFile; 179 m_pTempFile = NULL; 180 } 181 182 if ( m_rSotStorage.Is() ) 183 m_rSotStorage = NULL; 184 185 if ( m_pParentStorage ) 186 { 187 SotStorage* pTmp = m_pParentStorage; 188 m_pParentStorage = NULL; 189 pTmp->RemoveUNOStorageHolder( this ); // this statement can lead to destruction of the holder 190 } 191 } 192 193 194