1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: conncleanup.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include <connectivity/conncleanup.hxx>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/lang/XComponent.hpp>
36 #include <osl/diagnose.h>
38 //.........................................................................
41 //.........................................................................
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::beans
;
45 using namespace ::com::sun::star::sdbc
;
46 using namespace ::com::sun::star::lang
;
48 //=====================================================================
49 static const ::rtl::OUString
& getActiveConnectionPropertyName()
51 static const ::rtl::OUString s_sActiveConnectionPropertyName
= ::rtl::OUString::createFromAscii("ActiveConnection");
52 return s_sActiveConnectionPropertyName
;
55 //=====================================================================
56 //= OAutoConnectionDisposer
57 //=====================================================================
58 //---------------------------------------------------------------------
59 OAutoConnectionDisposer::OAutoConnectionDisposer(const Reference
< XRowSet
>& _rxRowSet
, const Reference
< XConnection
>& _rxConnection
)
60 :m_xRowSet( _rxRowSet
)
61 ,m_bRSListening( sal_False
)
62 ,m_bPropertyListening( sal_False
)
64 Reference
< XPropertySet
> xProps(_rxRowSet
, UNO_QUERY
);
65 OSL_ENSURE(xProps
.is(), "OAutoConnectionDisposer::OAutoConnectionDisposer: invalid rowset (no XPropertySet)!");
72 xProps
->setPropertyValue( getActiveConnectionPropertyName(), makeAny( _rxConnection
) );
73 m_xOriginalConnection
= _rxConnection
;
74 startPropertyListening( xProps
);
76 catch( const Exception
& )
78 OSL_ENSURE( sal_False
, "OAutoConnectionDisposer::OAutoConnectionDisposer: caught an exception!" );
82 //---------------------------------------------------------------------
83 void OAutoConnectionDisposer::startPropertyListening( const Reference
< XPropertySet
>& _rxRowSet
)
87 _rxRowSet
->addPropertyChangeListener( getActiveConnectionPropertyName(), this );
88 m_bPropertyListening
= sal_True
;
90 catch( const Exception
& )
92 OSL_ENSURE( sal_False
, "OAutoConnectionDisposer::startPropertyListening: caught an exception!" );
96 //---------------------------------------------------------------------
97 void OAutoConnectionDisposer::stopPropertyListening( const Reference
< XPropertySet
>& _rxEventSource
)
99 // prevent deletion of ourself while we're herein
100 Reference
< XInterface
> xKeepAlive(static_cast< XWeak
* >(this));
103 { // remove ourself as property change listener
104 OSL_ENSURE( _rxEventSource
.is(), "OAutoConnectionDisposer::stopPropertyListening: invalid event source (no XPropertySet)!" );
105 if ( _rxEventSource
.is() )
107 _rxEventSource
->removePropertyChangeListener( getActiveConnectionPropertyName(), this );
108 m_bPropertyListening
= sal_False
;
111 catch( const Exception
& )
113 OSL_ENSURE( sal_False
, "OAutoConnectionDisposer::stopPropertyListening: caught an exception!" );
117 //---------------------------------------------------------------------
118 void OAutoConnectionDisposer::startRowSetListening()
120 OSL_ENSURE( !m_bRSListening
, "OAutoConnectionDisposer::startRowSetListening: already listening!" );
123 if ( !m_bRSListening
)
124 m_xRowSet
->addRowSetListener( this );
126 catch( const Exception
& )
128 OSL_ENSURE( sal_False
, "OAutoConnectionDisposer::startRowSetListening: caught an exception!" );
130 m_bRSListening
= sal_True
;
133 //---------------------------------------------------------------------
134 void OAutoConnectionDisposer::stopRowSetListening()
136 OSL_ENSURE( m_bRSListening
, "OAutoConnectionDisposer::stopRowSetListening: not listening!" );
139 m_xRowSet
->removeRowSetListener( this );
141 catch( const Exception
& )
143 OSL_ENSURE( sal_False
, "OAutoConnectionDisposer::stopRowSetListening: caught an exception!" );
145 m_bRSListening
= sal_False
;
148 //---------------------------------------------------------------------
149 void SAL_CALL
OAutoConnectionDisposer::propertyChange( const PropertyChangeEvent
& _rEvent
) throw (RuntimeException
)
151 if ( _rEvent
.PropertyName
.equals( getActiveConnectionPropertyName() ) )
152 { // somebody set a new ActiveConnection
154 Reference
< XConnection
> xNewConnection
;
155 _rEvent
.NewValue
>>= xNewConnection
;
157 if ( isRowSetListening() )
159 // we're listening at the row set, this means that the row set does not have our
160 // m_xOriginalConnection as active connection anymore
161 // So there are two possibilities
162 // a. somebody sets a new connection which is not our original one
163 // b. somebody sets a new connection, which is exactly the original one
164 // a. we're not interested in a, but in b: In this case, we simply need to move to the state
165 // we had originally: listen for property changes, do not listen for row set changes, and
166 // do not dispose the connection until the row set does not need it anymore
167 if ( xNewConnection
.get() == m_xOriginalConnection
.get() )
169 stopRowSetListening();
174 // start listening at the row set. We're allowed to dispose the old connection as soon
175 // as the RowSet changed
177 // Unfortunately, the our database form implementations sometimes fire the change of their
178 // ActiveConnection twice. This is a error in forms/source/component/DatabaseForm.cxx, but
179 // changing this would require incompatible changes we can't do for a while.
180 // So for the moment, we have to live with it here.
182 // The only scenario where this doubled notification causes problems is when the connection
183 // of the form is reset to the one we're responsible for (m_xOriginalConnection), so we
186 // Yes, this is a HACK :(
188 // 94407 - 08.11.2001 - fs@openoffice.org
189 if ( xNewConnection
.get() != m_xOriginalConnection
.get() )
191 #if OSL_DEBUG_LEVEL > 0
192 Reference
< XConnection
> xOldConnection
;
193 _rEvent
.OldValue
>>= xOldConnection
;
194 OSL_ENSURE( xOldConnection
.get() == m_xOriginalConnection
.get(), "OAutoConnectionDisposer::propertyChange: unexpected (original) property value!" );
196 startRowSetListening();
202 //---------------------------------------------------------------------
203 void SAL_CALL
OAutoConnectionDisposer::disposing( const EventObject
& _rSource
) throw (RuntimeException
)
205 // the rowset is beeing disposed, and nobody has set a new ActiveConnection in the meantime
206 if ( isRowSetListening() )
207 stopRowSetListening();
211 if ( isPropertyListening() )
212 stopPropertyListening( Reference
< XPropertySet
>( _rSource
.Source
, UNO_QUERY
) );
214 //---------------------------------------------------------------------
215 void OAutoConnectionDisposer::clearConnection()
219 // dispose the old connection
220 Reference
< XComponent
> xComp(m_xOriginalConnection
, UNO_QUERY
);
223 m_xOriginalConnection
.clear();
227 OSL_ENSURE(sal_False
, "OAutoConnectionDisposer::clearConnection: caught an exception!");
230 //---------------------------------------------------------------------
231 void SAL_CALL
OAutoConnectionDisposer::cursorMoved( const ::com::sun::star::lang::EventObject
& /*event*/ ) throw (::com::sun::star::uno::RuntimeException
)
234 //---------------------------------------------------------------------
235 void SAL_CALL
OAutoConnectionDisposer::rowChanged( const ::com::sun::star::lang::EventObject
& /*event*/ ) throw (::com::sun::star::uno::RuntimeException
)
238 //---------------------------------------------------------------------
239 void SAL_CALL
OAutoConnectionDisposer::rowSetChanged( const ::com::sun::star::lang::EventObject
& /*event*/ ) throw (::com::sun::star::uno::RuntimeException
)
241 stopRowSetListening();
245 //---------------------------------------------------------------------
247 //.........................................................................
248 } // namespace dbtools
249 //.........................................................................