Bump for 3.6-28
[LibreOffice.git] / connectivity / source / commontools / conncleanup.cxx
blob1cd61cee15f2629c427b19c73a45a4f1f54bb815
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <connectivity/conncleanup.hxx>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/lang/XComponent.hpp>
32 #include <osl/diagnose.h>
34 //.........................................................................
35 namespace dbtools
37 //.........................................................................
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::sdbc;
42 using namespace ::com::sun::star::lang;
44 //=====================================================================
45 static const ::rtl::OUString& getActiveConnectionPropertyName()
47 static const ::rtl::OUString s_sActiveConnectionPropertyName( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ));
48 return s_sActiveConnectionPropertyName;
51 //=====================================================================
52 //= OAutoConnectionDisposer
53 //=====================================================================
54 //---------------------------------------------------------------------
55 OAutoConnectionDisposer::OAutoConnectionDisposer(const Reference< XRowSet >& _rxRowSet, const Reference< XConnection >& _rxConnection)
56 :m_xRowSet( _rxRowSet )
57 ,m_bRSListening( sal_False )
58 ,m_bPropertyListening( sal_False )
60 Reference< XPropertySet > xProps(_rxRowSet, UNO_QUERY);
61 OSL_ENSURE(xProps.is(), "OAutoConnectionDisposer::OAutoConnectionDisposer: invalid rowset (no XPropertySet)!");
63 if (!xProps.is())
64 return;
66 try
68 xProps->setPropertyValue( getActiveConnectionPropertyName(), makeAny( _rxConnection ) );
69 m_xOriginalConnection = _rxConnection;
70 startPropertyListening( xProps );
72 catch( const Exception& )
74 OSL_FAIL( "OAutoConnectionDisposer::OAutoConnectionDisposer: caught an exception!" );
78 //---------------------------------------------------------------------
79 void OAutoConnectionDisposer::startPropertyListening( const Reference< XPropertySet >& _rxRowSet )
81 try
83 _rxRowSet->addPropertyChangeListener( getActiveConnectionPropertyName(), this );
84 m_bPropertyListening = sal_True;
86 catch( const Exception& )
88 OSL_FAIL( "OAutoConnectionDisposer::startPropertyListening: caught an exception!" );
92 //---------------------------------------------------------------------
93 void OAutoConnectionDisposer::stopPropertyListening( const Reference< XPropertySet >& _rxEventSource )
95 // prevent deletion of ourself while we're herein
96 Reference< XInterface > xKeepAlive(static_cast< XWeak* >(this));
98 try
99 { // remove ourself as property change listener
100 OSL_ENSURE( _rxEventSource.is(), "OAutoConnectionDisposer::stopPropertyListening: invalid event source (no XPropertySet)!" );
101 if ( _rxEventSource.is() )
103 _rxEventSource->removePropertyChangeListener( getActiveConnectionPropertyName(), this );
104 m_bPropertyListening = sal_False;
107 catch( const Exception& )
109 OSL_FAIL( "OAutoConnectionDisposer::stopPropertyListening: caught an exception!" );
113 //---------------------------------------------------------------------
114 void OAutoConnectionDisposer::startRowSetListening()
116 OSL_ENSURE( !m_bRSListening, "OAutoConnectionDisposer::startRowSetListening: already listening!" );
119 if ( !m_bRSListening )
120 m_xRowSet->addRowSetListener( this );
122 catch( const Exception& )
124 OSL_FAIL( "OAutoConnectionDisposer::startRowSetListening: caught an exception!" );
126 m_bRSListening = sal_True;
129 //---------------------------------------------------------------------
130 void OAutoConnectionDisposer::stopRowSetListening()
132 OSL_ENSURE( m_bRSListening, "OAutoConnectionDisposer::stopRowSetListening: not listening!" );
135 m_xRowSet->removeRowSetListener( this );
137 catch( const Exception& )
139 OSL_FAIL( "OAutoConnectionDisposer::stopRowSetListening: caught an exception!" );
141 m_bRSListening = sal_False;
144 //---------------------------------------------------------------------
145 void SAL_CALL OAutoConnectionDisposer::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
147 if ( _rEvent.PropertyName.equals( getActiveConnectionPropertyName() ) )
148 { // somebody set a new ActiveConnection
150 Reference< XConnection > xNewConnection;
151 _rEvent.NewValue >>= xNewConnection;
153 if ( isRowSetListening() )
155 // we're listening at the row set, this means that the row set does not have our
156 // m_xOriginalConnection as active connection anymore
157 // So there are two possibilities
158 // a. somebody sets a new connection which is not our original one
159 // b. somebody sets a new connection, which is exactly the original one
160 // a. we're not interested in a, but in b: In this case, we simply need to move to the state
161 // we had originally: listen for property changes, do not listen for row set changes, and
162 // do not dispose the connection until the row set does not need it anymore
163 if ( xNewConnection.get() == m_xOriginalConnection.get() )
165 stopRowSetListening();
168 else
170 // start listening at the row set. We're allowed to dispose the old connection as soon
171 // as the RowSet changed
173 // Unfortunately, the our database form implementations sometimes fire the change of their
174 // ActiveConnection twice. This is a error in forms/source/component/DatabaseForm.cxx, but
175 // changing this would require incompatible changes we can't do for a while.
176 // So for the moment, we have to live with it here.
178 // The only scenario where this doubled notification causes problems is when the connection
179 // of the form is reset to the one we're responsible for (m_xOriginalConnection), so we
180 // check this here.
182 // Yes, this is a HACK :(
183 if ( xNewConnection.get() != m_xOriginalConnection.get() )
185 #if OSL_DEBUG_LEVEL > 0
186 Reference< XConnection > xOldConnection;
187 _rEvent.OldValue >>= xOldConnection;
188 OSL_ENSURE( xOldConnection.get() == m_xOriginalConnection.get(), "OAutoConnectionDisposer::propertyChange: unexpected (original) property value!" );
189 #endif
190 startRowSetListening();
196 //---------------------------------------------------------------------
197 void SAL_CALL OAutoConnectionDisposer::disposing( const EventObject& _rSource ) throw (RuntimeException)
199 // the rowset is beeing disposed, and nobody has set a new ActiveConnection in the meantime
200 if ( isRowSetListening() )
201 stopRowSetListening();
203 clearConnection();
205 if ( isPropertyListening() )
206 stopPropertyListening( Reference< XPropertySet >( _rSource.Source, UNO_QUERY ) );
208 //---------------------------------------------------------------------
209 void OAutoConnectionDisposer::clearConnection()
213 // dispose the old connection
214 Reference< XComponent > xComp(m_xOriginalConnection, UNO_QUERY);
215 if (xComp.is())
216 xComp->dispose();
217 m_xOriginalConnection.clear();
219 catch(Exception&)
221 OSL_FAIL("OAutoConnectionDisposer::clearConnection: caught an exception!");
224 //---------------------------------------------------------------------
225 void SAL_CALL OAutoConnectionDisposer::cursorMoved( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
228 //---------------------------------------------------------------------
229 void SAL_CALL OAutoConnectionDisposer::rowChanged( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
232 //---------------------------------------------------------------------
233 void SAL_CALL OAutoConnectionDisposer::rowSetChanged( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
235 stopRowSetListening();
236 clearConnection();
239 //---------------------------------------------------------------------
241 //.........................................................................
242 } // namespace dbtools
243 //.........................................................................
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */