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