update dev300-m58
[ooovba.git] / dbaccess / source / core / misc / ContainerMediator.cxx
blobd0841ab67da4210e8472463da04af697c3091c2d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ContainerMediator.cxx,v $
10 * $Revision: 1.11.42.1 $
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_dbaccess.hxx"
33 #ifndef DBA_CONTAINERMEDIATOR_HXX
34 #include "ContainerMediator.hxx"
35 #endif
36 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
37 #include "dbastrings.hrc"
38 #endif
39 #ifndef DBA_PROPERTYSETFORWARD_HXX
40 #include "PropertyForward.hxx"
41 #endif
43 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #endif
46 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
47 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
50 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
51 #endif
52 #include <com/sun/star/sdbcx/XRename.hpp>
53 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
54 #include <connectivity/dbtools.hxx>
55 #endif
56 #ifndef _COMPHELPER_PROPERTY_HXX_
57 #include <comphelper/property.hxx>
58 #endif
59 #ifndef _TOOLS_DEBUG_HXX
60 #include <tools/debug.hxx>
61 #endif
62 #ifndef TOOLS_DIAGNOSE_EX_H
63 #include <tools/diagnose_ex.h>
64 #endif
67 //........................................................................
68 namespace dbaccess
70 //........................................................................
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::sdbc;
74 using namespace ::com::sun::star::sdbcx;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::container;
78 DBG_NAME(OContainerMediator)
79 OContainerMediator::OContainerMediator( const Reference< XContainer >& _xContainer, const Reference< XNameAccess >& _xSettings,
80 const Reference< XConnection >& _rxConnection, ContainerType _eType )
81 : m_xSettings( _xSettings )
82 , m_xContainer( _xContainer )
83 , m_aConnection( _rxConnection )
84 , m_eType( _eType )
86 DBG_CTOR(OContainerMediator,NULL);
88 if ( _xSettings.is() && _xContainer.is() )
90 osl_incrementInterlockedCount(&m_refCount);
91 try
93 m_xContainer->addContainerListener(this);
94 Reference< XContainer > xContainer(_xSettings, UNO_QUERY);
95 if ( xContainer.is() )
96 xContainer->addContainerListener(this);
98 catch(Exception&)
100 OSL_ENSURE(sal_False, "OContainerMediator::OContainerMediator: caught an exception!");
102 osl_decrementInterlockedCount( &m_refCount );
104 else
106 m_xSettings.clear();
107 m_xContainer.clear();
110 // -----------------------------------------------------------------------------
111 OContainerMediator::~OContainerMediator()
113 DBG_DTOR(OContainerMediator,NULL);
114 acquire();
115 impl_cleanup_nothrow();
118 // -----------------------------------------------------------------------------
119 void OContainerMediator::impl_cleanup_nothrow()
123 Reference< XContainer > xContainer( m_xSettings, UNO_QUERY );
124 if ( xContainer.is() )
125 xContainer->removeContainerListener( this );
126 m_xSettings.clear();
128 xContainer = m_xContainer;
129 if ( xContainer.is() )
130 xContainer->removeContainerListener( this );
131 m_xContainer.clear();//WeakReference< XContainer >();
133 m_aForwardList.clear();
135 catch( const Exception& )
137 DBG_UNHANDLED_EXCEPTION();
141 // -----------------------------------------------------------------------------
142 void SAL_CALL OContainerMediator::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException)
144 ::osl::MutexGuard aGuard(m_aMutex);
145 if ( _rEvent.Source == m_xSettings && m_xSettings.is() )
147 ::rtl::OUString sElementName;
148 _rEvent.Accessor >>= sElementName;
149 PropertyForwardList::iterator aFind = m_aForwardList.find(sElementName);
150 if ( aFind != m_aForwardList.end() )
152 Reference< XPropertySet> xDest(_rEvent.Element,UNO_QUERY);
153 aFind->second->setDefinition( xDest );
157 // -----------------------------------------------------------------------------
158 void SAL_CALL OContainerMediator::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException)
160 ::osl::MutexGuard aGuard(m_aMutex);
161 Reference< XContainer > xContainer = m_xContainer;
162 if ( _rEvent.Source == xContainer && xContainer.is() )
164 ::rtl::OUString sElementName;
165 _rEvent.Accessor >>= sElementName;
166 m_aForwardList.erase(sElementName);
169 Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY );
170 if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) )
171 xNameContainer->removeByName( sElementName );
173 catch( const Exception& )
175 DBG_UNHANDLED_EXCEPTION();
179 // -----------------------------------------------------------------------------
180 void SAL_CALL OContainerMediator::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException)
182 Reference< XContainer > xContainer = m_xContainer;
183 if ( _rEvent.Source == xContainer && xContainer.is() )
185 ::rtl::OUString sElementName;
186 _rEvent.ReplacedElement >>= sElementName;
188 PropertyForwardList::iterator aFind = m_aForwardList.find(sElementName);
189 if ( aFind != m_aForwardList.end() )
191 ::rtl::OUString sNewName;
192 _rEvent.Accessor >>= sNewName;
195 Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY_THROW );
196 if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) )
198 Reference<XRename> xSource(m_xSettings->getByName(sElementName),UNO_QUERY_THROW);
199 xSource->rename(sNewName);
202 catch( const Exception& )
204 DBG_UNHANDLED_EXCEPTION();
207 aFind->second->setName(sNewName);
212 // -----------------------------------------------------------------------------
213 void SAL_CALL OContainerMediator::disposing( const EventObject& /*Source*/ ) throw(RuntimeException)
215 ::osl::MutexGuard aGuard(m_aMutex);
217 // Reference< XContainer > xContainer = m_xContainer;
218 // if ( Source.Source == xContainer || Source.Source == m_xSettings )
219 // this can only be one of them :-) So no check needed here
220 impl_cleanup_nothrow();
223 // -----------------------------------------------------------------------------
224 Reference< XPropertySet > OContainerMediator::impl_getSettingsForInitialization_nothrow( const ::rtl::OUString& _rName,
225 const Reference< XPropertySet >& _rxDestination ) const
227 Reference< XPropertySet > xSettings;
230 if ( m_xSettings.is() && m_xSettings->hasByName( _rName ) )
231 OSL_VERIFY( m_xSettings->getByName( _rName ) >>= xSettings );
232 else if ( m_eType == eColumns )
234 do // artifial loop for easier flow control
237 Reference< XConnection > xConnection( m_aConnection );
238 if ( !xConnection.is() )
239 break;
241 Reference< XPropertySetInfo > xPSI( _rxDestination->getPropertySetInfo(), UNO_QUERY_THROW );
242 if ( !xPSI->hasPropertyByName( PROPERTY_TABLENAME )
243 || !xPSI->hasPropertyByName( PROPERTY_REALNAME )
245 break;
247 // determine the composed table name, plus the column name, as indicated by the
248 // respective properties at the destination object
249 ::rtl::OUString sCatalog, sSchema, sTable, sColumn;
250 if ( xPSI->hasPropertyByName( PROPERTY_CATALOGNAME ) )
252 OSL_VERIFY( _rxDestination->getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog );
254 if ( xPSI->hasPropertyByName( PROPERTY_SCHEMANAME ) )
256 OSL_VERIFY( _rxDestination->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema );
258 OSL_VERIFY( _rxDestination->getPropertyValue( PROPERTY_TABLENAME ) >>= sTable );
259 OSL_VERIFY( _rxDestination->getPropertyValue( PROPERTY_REALNAME ) >>= sColumn );
261 ::rtl::OUString sComposedTableName = ::dbtools::composeTableName(
262 xConnection->getMetaData(), sCatalog, sSchema, sTable, sal_False, ::dbtools::eComplete );
264 // retrieve the table in question
265 Reference< XTablesSupplier > xSuppTables( xConnection, UNO_QUERY_THROW );
266 Reference< XNameAccess > xTables( xSuppTables->getTables(), UNO_QUERY_THROW );
267 if ( !xTables->hasByName( sComposedTableName ) )
268 break;
270 Reference< XColumnsSupplier > xSuppCols( xTables->getByName( sComposedTableName ), UNO_QUERY_THROW );
271 Reference< XNameAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW );
272 if ( !xColumns->hasByName( sColumn ) )
273 break;
275 xSettings.set( xColumns->getByName( sColumn ), UNO_QUERY );
278 while ( false );
281 catch( const Exception& )
283 DBG_UNHANDLED_EXCEPTION();
285 return xSettings;
288 // -----------------------------------------------------------------------------
289 void OContainerMediator::notifyElementCreated(const ::rtl::OUString& _sName,const Reference<XPropertySet>& _xDest)
291 PropertyForwardList::iterator aFind = m_aForwardList.find(_sName);
292 if ( (aFind == m_aForwardList.end() || !aFind->second->getDefinition().is() )&& m_xSettings.is() )
294 ::std::vector< ::rtl::OUString> aPropertyList;
298 // initially copy from the settings object (if existent) to the newly created object
299 Reference< XPropertySet > xSetting( impl_getSettingsForInitialization_nothrow( _sName, _xDest ) );
300 if ( xSetting.is() )
301 ::comphelper::copyProperties( xSetting, _xDest );
303 // collect the to-be-monitored properties
304 Reference< XPropertySetInfo > xPSI( _xDest->getPropertySetInfo(), UNO_QUERY_THROW );
305 Sequence< Property > aProperties( xPSI->getProperties() );
306 const Property* property = aProperties.getConstArray();
307 const Property* propertyEnd = aProperties.getConstArray() + aProperties.getLength();
308 for ( ; property != propertyEnd; ++property )
310 if ( ( property->Attributes & PropertyAttribute::READONLY ) != 0 )
311 continue;
312 if ( ( property->Attributes & PropertyAttribute::BOUND ) == 0 )
313 continue;
315 aPropertyList.push_back( property->Name );
318 catch( const Exception& )
320 DBG_UNHANDLED_EXCEPTION();
323 ::rtl::Reference< OPropertyForward > pForward( new OPropertyForward( _xDest, m_xSettings, _sName, aPropertyList ) );
324 m_aForwardList[_sName] = pForward;
325 } // if ( aFind == m_aForwardList.end() && m_xSettings.is() )
327 // -----------------------------------------------------------------------------
328 //........................................................................
329 } // namespace dbaccess
330 //........................................................................