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