1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 #ifndef DBA_CONTAINERMEDIATOR_HXX 31 #include "ContainerMediator.hxx" 32 #endif 33 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC 34 #include "dbastrings.hrc" 35 #endif 36 #ifndef DBA_PROPERTYSETFORWARD_HXX 37 #include "PropertyForward.hxx" 38 #endif 39 40 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ 41 #include <com/sun/star/beans/PropertyAttribute.hpp> 42 #endif 43 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ 44 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 45 #endif 46 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ 47 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 48 #endif 49 #include <com/sun/star/sdbcx/XRename.hpp> 50 #ifndef _CONNECTIVITY_DBTOOLS_HXX_ 51 #include <connectivity/dbtools.hxx> 52 #endif 53 #ifndef _COMPHELPER_PROPERTY_HXX_ 54 #include <comphelper/property.hxx> 55 #endif 56 #ifndef _TOOLS_DEBUG_HXX 57 #include <tools/debug.hxx> 58 #endif 59 #ifndef TOOLS_DIAGNOSE_EX_H 60 #include <tools/diagnose_ex.h> 61 #endif 62 63 64 //........................................................................ 65 namespace dbaccess 66 { 67 //........................................................................ 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::lang; 70 using namespace ::com::sun::star::sdbc; 71 using namespace ::com::sun::star::sdbcx; 72 using namespace ::com::sun::star::beans; 73 using namespace ::com::sun::star::container; 74 75 DBG_NAME(OContainerMediator) 76 OContainerMediator::OContainerMediator( const Reference< XContainer >& _xContainer, const Reference< XNameAccess >& _xSettings, 77 const Reference< XConnection >& _rxConnection, ContainerType _eType ) 78 : m_xSettings( _xSettings ) 79 , m_xContainer( _xContainer ) 80 , m_aConnection( _rxConnection ) 81 , m_eType( _eType ) 82 { 83 DBG_CTOR(OContainerMediator,NULL); 84 85 if ( _xSettings.is() && _xContainer.is() ) 86 { 87 osl_incrementInterlockedCount(&m_refCount); 88 try 89 { 90 m_xContainer->addContainerListener(this); 91 Reference< XContainer > xContainer(_xSettings, UNO_QUERY); 92 if ( xContainer.is() ) 93 xContainer->addContainerListener(this); 94 } 95 catch(Exception&) 96 { 97 OSL_ENSURE(sal_False, "OContainerMediator::OContainerMediator: caught an exception!"); 98 } 99 osl_decrementInterlockedCount( &m_refCount ); 100 } 101 else 102 { 103 m_xSettings.clear(); 104 m_xContainer.clear(); 105 } 106 } 107 // ----------------------------------------------------------------------------- 108 OContainerMediator::~OContainerMediator() 109 { 110 DBG_DTOR(OContainerMediator,NULL); 111 acquire(); 112 impl_cleanup_nothrow(); 113 } 114 115 // ----------------------------------------------------------------------------- 116 void OContainerMediator::impl_cleanup_nothrow() 117 { 118 try 119 { 120 Reference< XContainer > xContainer( m_xSettings, UNO_QUERY ); 121 if ( xContainer.is() ) 122 xContainer->removeContainerListener( this ); 123 m_xSettings.clear(); 124 125 xContainer = m_xContainer; 126 if ( xContainer.is() ) 127 xContainer->removeContainerListener( this ); 128 m_xContainer.clear(); 129 130 m_aForwardList.clear(); 131 } 132 catch( const Exception& ) 133 { 134 DBG_UNHANDLED_EXCEPTION(); 135 } 136 } 137 138 // ----------------------------------------------------------------------------- 139 void SAL_CALL OContainerMediator::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) 140 { 141 ::osl::MutexGuard aGuard(m_aMutex); 142 if ( _rEvent.Source == m_xSettings && m_xSettings.is() ) 143 { 144 ::rtl::OUString sElementName; 145 _rEvent.Accessor >>= sElementName; 146 PropertyForwardList::iterator aFind = m_aForwardList.find(sElementName); 147 if ( aFind != m_aForwardList.end() ) 148 { 149 Reference< XPropertySet> xDest(_rEvent.Element,UNO_QUERY); 150 aFind->second->setDefinition( xDest ); 151 } 152 } 153 } 154 // ----------------------------------------------------------------------------- 155 void SAL_CALL OContainerMediator::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) 156 { 157 ::osl::MutexGuard aGuard(m_aMutex); 158 Reference< XContainer > xContainer = m_xContainer; 159 if ( _rEvent.Source == xContainer && xContainer.is() ) 160 { 161 ::rtl::OUString sElementName; 162 _rEvent.Accessor >>= sElementName; 163 m_aForwardList.erase(sElementName); 164 try 165 { 166 Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY ); 167 if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) ) 168 xNameContainer->removeByName( sElementName ); 169 } 170 catch( const Exception& ) 171 { 172 DBG_UNHANDLED_EXCEPTION(); 173 } 174 } 175 } 176 // ----------------------------------------------------------------------------- 177 void SAL_CALL OContainerMediator::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) 178 { 179 Reference< XContainer > xContainer = m_xContainer; 180 if ( _rEvent.Source == xContainer && xContainer.is() ) 181 { 182 ::rtl::OUString sElementName; 183 _rEvent.ReplacedElement >>= sElementName; 184 185 PropertyForwardList::iterator aFind = m_aForwardList.find(sElementName); 186 if ( aFind != m_aForwardList.end() ) 187 { 188 ::rtl::OUString sNewName; 189 _rEvent.Accessor >>= sNewName; 190 try 191 { 192 Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY_THROW ); 193 if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) ) 194 { 195 Reference<XRename> xSource(m_xSettings->getByName(sElementName),UNO_QUERY_THROW); 196 xSource->rename(sNewName); 197 } 198 } 199 catch( const Exception& ) 200 { 201 DBG_UNHANDLED_EXCEPTION(); 202 } 203 204 aFind->second->setName(sNewName); 205 } 206 } 207 } 208 209 // ----------------------------------------------------------------------------- 210 void SAL_CALL OContainerMediator::disposing( const EventObject& /*Source*/ ) throw(RuntimeException) 211 { 212 ::osl::MutexGuard aGuard(m_aMutex); 213 214 impl_cleanup_nothrow(); 215 } 216 217 // ----------------------------------------------------------------------------- 218 void OContainerMediator::impl_initSettings_nothrow( const ::rtl::OUString& _rName, const Reference< XPropertySet >& _rxDestination ) 219 { 220 try 221 { 222 if ( m_xSettings.is() && m_xSettings->hasByName( _rName ) ) 223 { 224 Reference< XPropertySet > xSettings( m_xSettings->getByName( _rName ), UNO_QUERY_THROW ); 225 ::comphelper::copyProperties( xSettings, _rxDestination ); 226 } 227 } 228 catch( const Exception& ) 229 { 230 DBG_UNHANDLED_EXCEPTION(); 231 } 232 } 233 234 // ----------------------------------------------------------------------------- 235 void OContainerMediator::notifyElementCreated( const ::rtl::OUString& _sName, const Reference< XPropertySet >& _xDest ) 236 { 237 if ( !m_xSettings.is() ) 238 return; 239 240 PropertyForwardList::iterator aFind = m_aForwardList.find( _sName ); 241 if ( aFind != m_aForwardList.end() 242 && aFind->second->getDefinition().is() 243 ) 244 { 245 OSL_ENSURE( false, "OContainerMediator::notifyElementCreated: is this really a valid case?" ); 246 return; 247 } 248 249 ::std::vector< ::rtl::OUString > aPropertyList; 250 try 251 { 252 // initially copy from the settings object (if existent) to the newly created object 253 impl_initSettings_nothrow( _sName, _xDest ); 254 255 // collect the to-be-monitored properties 256 Reference< XPropertySetInfo > xPSI( _xDest->getPropertySetInfo(), UNO_QUERY_THROW ); 257 Sequence< Property > aProperties( xPSI->getProperties() ); 258 const Property* property = aProperties.getConstArray(); 259 const Property* propertyEnd = aProperties.getConstArray() + aProperties.getLength(); 260 for ( ; property != propertyEnd; ++property ) 261 { 262 if ( ( property->Attributes & PropertyAttribute::READONLY ) != 0 ) 263 continue; 264 if ( ( property->Attributes & PropertyAttribute::BOUND ) == 0 ) 265 continue; 266 267 aPropertyList.push_back( property->Name ); 268 } 269 } 270 catch( const Exception& ) 271 { 272 DBG_UNHANDLED_EXCEPTION(); 273 } 274 275 ::rtl::Reference< OPropertyForward > pForward( new OPropertyForward( _xDest, m_xSettings, _sName, aPropertyList ) ); 276 m_aForwardList[ _sName ] = pForward; 277 } 278 // ----------------------------------------------------------------------------- 279 //........................................................................ 280 } // namespace dbaccess 281 //........................................................................ 282