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: 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"
36 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
37 #include "dbastrings.hrc"
39 #ifndef DBA_PROPERTYSETFORWARD_HXX
40 #include "PropertyForward.hxx"
43 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
46 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
47 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
49 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
50 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
52 #include <com/sun/star/sdbcx/XRename.hpp>
53 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
54 #include <connectivity/dbtools.hxx>
56 #ifndef _COMPHELPER_PROPERTY_HXX_
57 #include <comphelper/property.hxx>
59 #ifndef _TOOLS_DEBUG_HXX
60 #include <tools/debug.hxx>
62 #ifndef TOOLS_DIAGNOSE_EX_H
63 #include <tools/diagnose_ex.h>
67 //........................................................................
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
)
86 DBG_CTOR(OContainerMediator
,NULL
);
88 if ( _xSettings
.is() && _xContainer
.is() )
90 osl_incrementInterlockedCount(&m_refCount
);
93 m_xContainer
->addContainerListener(this);
94 Reference
< XContainer
> xContainer(_xSettings
, UNO_QUERY
);
95 if ( xContainer
.is() )
96 xContainer
->addContainerListener(this);
100 OSL_ENSURE(sal_False
, "OContainerMediator::OContainerMediator: caught an exception!");
102 osl_decrementInterlockedCount( &m_refCount
);
107 m_xContainer
.clear();
110 // -----------------------------------------------------------------------------
111 OContainerMediator::~OContainerMediator()
113 DBG_DTOR(OContainerMediator
,NULL
);
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 );
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() )
241 Reference
< XPropertySetInfo
> xPSI( _rxDestination
->getPropertySetInfo(), UNO_QUERY_THROW
);
242 if ( !xPSI
->hasPropertyByName( PROPERTY_TABLENAME
)
243 || !xPSI
->hasPropertyByName( PROPERTY_REALNAME
)
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
) )
270 Reference
< XColumnsSupplier
> xSuppCols( xTables
->getByName( sComposedTableName
), UNO_QUERY_THROW
);
271 Reference
< XNameAccess
> xColumns( xSuppCols
->getColumns(), UNO_QUERY_THROW
);
272 if ( !xColumns
->hasByName( sColumn
) )
275 xSettings
.set( xColumns
->getByName( sColumn
), UNO_QUERY
);
281 catch( const Exception
& )
283 DBG_UNHANDLED_EXCEPTION();
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
) );
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 )
312 if ( ( property
->Attributes
& PropertyAttribute::BOUND
) == 0 )
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 //........................................................................