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 27 #ifndef DBA_COREDATAACESS_COMPONENTDEFINITION_HXX 28 #include "ComponentDefinition.hxx" 29 #endif 30 #ifndef _DBASHARED_APITOOLS_HXX_ 31 #include "apitools.hxx" 32 #endif 33 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC 34 #include "dbastrings.hrc" 35 #endif 36 #include "module_dba.hxx" 37 38 #ifndef _TOOLS_DEBUG_HXX 39 #include <tools/debug.hxx> 40 #endif 41 #ifndef _COMPHELPER_SEQUENCE_HXX_ 42 #include <comphelper/sequence.hxx> 43 #endif 44 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ 45 #include <com/sun/star/lang/DisposedException.hpp> 46 #endif 47 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ 48 #include <com/sun/star/beans/PropertyAttribute.hpp> 49 #endif 50 #ifndef _COMPHELPER_PROPERTY_HXX_ 51 #include <comphelper/property.hxx> 52 #endif 53 #ifndef _DBACORE_DEFINITIONCOLUMN_HXX_ 54 #include "definitioncolumn.hxx" 55 #endif 56 #include <cppuhelper/implbase1.hxx> 57 #include <comphelper/componentcontext.hxx> 58 59 using namespace ::com::sun::star::uno; 60 using namespace ::com::sun::star::sdbc; 61 using namespace ::com::sun::star::lang; 62 63 using namespace ::com::sun::star::beans; 64 using namespace ::com::sun::star::container; 65 using namespace ::osl; 66 using namespace ::comphelper; 67 using namespace ::cppu; 68 69 extern "C" void SAL_CALL createRegistryInfo_OComponentDefinition() 70 { 71 static ::dba::OAutoRegistration< ::dbaccess::OComponentDefinition > aAutoRegistration; 72 } 73 74 //........................................................................ 75 namespace dbaccess 76 { 77 //........................................................................ 78 /// helper class for column property change events which holds the OComponentDefinition weak 79 typedef ::cppu::WeakImplHelper1 < XPropertyChangeListener > TColumnPropertyListener_BASE; 80 class OColumnPropertyListener : public TColumnPropertyListener_BASE 81 { 82 OComponentDefinition* m_pComponent; 83 84 OColumnPropertyListener(const OColumnPropertyListener&); 85 void operator =(const OColumnPropertyListener&); 86 protected: 87 virtual ~OColumnPropertyListener(){} 88 public: 89 OColumnPropertyListener(OComponentDefinition* _pComponent) : m_pComponent(_pComponent){} 90 // XPropertyChangeListener 91 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw (RuntimeException) 92 { 93 if ( m_pComponent ) 94 m_pComponent->notifyDataSourceModified(); 95 } 96 // XEventListener 97 virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException) 98 { 99 } 100 void clear() { m_pComponent = NULL; } 101 }; 102 DBG_NAME(OComponentDefinition_Impl) 103 OComponentDefinition_Impl::OComponentDefinition_Impl() 104 { 105 DBG_CTOR(OComponentDefinition_Impl,NULL); 106 } 107 // ----------------------------------------------------------------------------- 108 OComponentDefinition_Impl::~OComponentDefinition_Impl() 109 { 110 DBG_DTOR(OComponentDefinition_Impl,NULL); 111 } 112 //========================================================================== 113 //= OComponentDefinition 114 //========================================================================== 115 //-------------------------------------------------------------------------- 116 DBG_NAME(OComponentDefinition) 117 //-------------------------------------------------------------------------- 118 void OComponentDefinition::registerProperties() 119 { 120 m_xColumnPropertyListener = ::comphelper::ImplementationReference<OColumnPropertyListener,XPropertyChangeListener>(new OColumnPropertyListener(this)); 121 OComponentDefinition_Impl& rDefinition( getDefinition() ); 122 ODataSettings::registerPropertiesFor( &rDefinition ); 123 124 registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND | PropertyAttribute::READONLY|PropertyAttribute::CONSTRAINED, 125 &rDefinition.m_aProps.aTitle, ::getCppuType(&rDefinition.m_aProps.aTitle)); 126 127 if ( m_bTable ) 128 { 129 registerProperty(PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME, PropertyAttribute::BOUND, 130 &rDefinition.m_sSchemaName, ::getCppuType(&rDefinition.m_sSchemaName)); 131 132 registerProperty(PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME, PropertyAttribute::BOUND, 133 &rDefinition.m_sCatalogName, ::getCppuType(&rDefinition.m_sCatalogName)); 134 } 135 } 136 137 //-------------------------------------------------------------------------- 138 OComponentDefinition::OComponentDefinition(const Reference< XMultiServiceFactory >& _xORB 139 ,const Reference< XInterface >& _xParentContainer 140 ,const TContentPtr& _pImpl 141 ,sal_Bool _bTable) 142 :OContentHelper(_xORB,_xParentContainer,_pImpl) 143 ,ODataSettings(OContentHelper::rBHelper,!_bTable) 144 ,m_bTable(_bTable) 145 { 146 DBG_CTOR(OComponentDefinition, NULL); 147 registerProperties(); 148 } 149 //-------------------------------------------------------------------------- 150 OComponentDefinition::~OComponentDefinition() 151 { 152 DBG_DTOR(OComponentDefinition, NULL); 153 } 154 155 //-------------------------------------------------------------------------- 156 OComponentDefinition::OComponentDefinition( const Reference< XInterface >& _rxContainer 157 ,const ::rtl::OUString& _rElementName 158 ,const Reference< XMultiServiceFactory >& _xORB 159 ,const TContentPtr& _pImpl 160 ,sal_Bool _bTable) 161 :OContentHelper(_xORB,_rxContainer,_pImpl) 162 ,ODataSettings(OContentHelper::rBHelper,!_bTable) 163 ,m_bTable(_bTable) 164 { 165 DBG_CTOR(OComponentDefinition, NULL); 166 registerProperties(); 167 168 m_pImpl->m_aProps.aTitle = _rElementName; 169 DBG_ASSERT(m_pImpl->m_aProps.aTitle.getLength() != 0, "OComponentDefinition::OComponentDefinition : invalid name !"); 170 } 171 172 //-------------------------------------------------------------------------- 173 IMPLEMENT_IMPLEMENTATION_ID(OComponentDefinition); 174 IMPLEMENT_GETTYPES3(OComponentDefinition,ODataSettings,OContentHelper,OComponentDefinition_BASE); 175 IMPLEMENT_FORWARD_XINTERFACE3( OComponentDefinition,OContentHelper,ODataSettings,OComponentDefinition_BASE) 176 //-------------------------------------------------------------------------- 177 ::rtl::OUString OComponentDefinition::getImplementationName_static( ) throw(RuntimeException) 178 { 179 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dba.OComponentDefinition")); 180 } 181 182 //-------------------------------------------------------------------------- 183 ::rtl::OUString SAL_CALL OComponentDefinition::getImplementationName( ) throw(RuntimeException) 184 { 185 return getImplementationName_static(); 186 } 187 188 //-------------------------------------------------------------------------- 189 Sequence< ::rtl::OUString > OComponentDefinition::getSupportedServiceNames_static( ) throw(RuntimeException) 190 { 191 Sequence< ::rtl::OUString > aServices(2); 192 aServices.getArray()[0] = SERVICE_SDB_TABLEDEFINITION; 193 aServices.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content")); 194 195 return aServices; 196 } 197 198 //-------------------------------------------------------------------------- 199 Sequence< ::rtl::OUString > SAL_CALL OComponentDefinition::getSupportedServiceNames( ) throw(RuntimeException) 200 { 201 return getSupportedServiceNames_static(); 202 } 203 //------------------------------------------------------------------------------ 204 Reference< XInterface > OComponentDefinition::Create( const Reference< XComponentContext >& _rxContext ) 205 { 206 ::comphelper::ComponentContext aContext( _rxContext ); 207 return *(new OComponentDefinition( aContext.getLegacyServiceFactory(), NULL, TContentPtr( new OComponentDefinition_Impl ) ) ); 208 } 209 // ----------------------------------------------------------------------------- 210 void SAL_CALL OComponentDefinition::disposing() 211 { 212 OContentHelper::disposing(); 213 if ( m_pColumns.get() ) 214 m_pColumns->disposing(); 215 m_xColumnPropertyListener->clear(); 216 m_xColumnPropertyListener.dispose(); 217 } 218 // ----------------------------------------------------------------------------- 219 IPropertyArrayHelper& OComponentDefinition::getInfoHelper() 220 { 221 return *getArrayHelper(); 222 } 223 //-------------------------------------------------------------------------- 224 IPropertyArrayHelper* OComponentDefinition::createArrayHelper( ) const 225 { 226 Sequence< Property > aProps; 227 describeProperties(aProps); 228 return new OPropertyArrayHelper(aProps); 229 } 230 //-------------------------------------------------------------------------- 231 Reference< XPropertySetInfo > SAL_CALL OComponentDefinition::getPropertySetInfo( ) throw(RuntimeException) 232 { 233 Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) ); 234 return xInfo; 235 } 236 237 // ----------------------------------------------------------------------------- 238 ::rtl::OUString OComponentDefinition::determineContentType() const 239 { 240 return m_bTable 241 ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseTable" ) ) 242 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseCommandDefinition" ) ); 243 } 244 245 // ----------------------------------------------------------------------------- 246 Reference< XNameAccess> OComponentDefinition::getColumns() throw (RuntimeException) 247 { 248 ::osl::MutexGuard aGuard(m_aMutex); 249 ::connectivity::checkDisposed(OContentHelper::rBHelper.bDisposed); 250 251 if ( !m_pColumns.get() ) 252 { 253 ::std::vector< ::rtl::OUString> aNames; 254 255 const OComponentDefinition_Impl& rDefinition( getDefinition() ); 256 aNames.reserve( rDefinition.size() ); 257 258 OComponentDefinition_Impl::const_iterator aIter = rDefinition.begin(); 259 OComponentDefinition_Impl::const_iterator aEnd = rDefinition.end(); 260 for ( ; aIter != aEnd; ++aIter ) 261 aNames.push_back( aIter->first ); 262 263 m_pColumns.reset( new OColumns( *this, m_aMutex, sal_True, aNames, this, NULL, sal_True, sal_False, sal_False ) ); 264 m_pColumns->setParent( *this ); 265 } 266 return m_pColumns.get(); 267 } 268 // ----------------------------------------------------------------------------- 269 OColumn* OComponentDefinition::createColumn(const ::rtl::OUString& _rName) const 270 { 271 const OComponentDefinition_Impl& rDefinition( getDefinition() ); 272 OComponentDefinition_Impl::const_iterator aFind = rDefinition.find( _rName ); 273 if ( aFind != rDefinition.end() ) 274 { 275 aFind->second->addPropertyChangeListener(::rtl::OUString(),m_xColumnPropertyListener.getRef()); 276 return new OTableColumnWrapper( aFind->second, aFind->second, true ); 277 } 278 OSL_ENSURE( false, "OComponentDefinition::createColumn: is this a valid case?" ); 279 // This here is the last place creating a OTableColumn, and somehow /me thinks it is not needed ... 280 return new OTableColumn( _rName ); 281 } 282 // ----------------------------------------------------------------------------- 283 Reference< XPropertySet > OComponentDefinition::createColumnDescriptor() 284 { 285 return new OTableColumnDescriptor( true ); 286 } 287 // ----------------------------------------------------------------------------- 288 void OComponentDefinition::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception) 289 { 290 ODataSettings::setFastPropertyValue_NoBroadcast(nHandle,rValue); 291 notifyDataSourceModified(); 292 } 293 // ----------------------------------------------------------------------------- 294 void OComponentDefinition::columnDropped(const ::rtl::OUString& _sName) 295 { 296 getDefinition().erase( _sName ); 297 notifyDataSourceModified(); 298 } 299 // ----------------------------------------------------------------------------- 300 void OComponentDefinition::columnAppended( const Reference< XPropertySet >& _rxSourceDescriptor ) 301 { 302 ::rtl::OUString sName; 303 _rxSourceDescriptor->getPropertyValue( PROPERTY_NAME ) >>= sName; 304 305 Reference<XPropertySet> xColDesc = new OTableColumnDescriptor( true ); 306 ::comphelper::copyProperties( _rxSourceDescriptor, xColDesc ); 307 getDefinition().insert( sName, xColDesc ); 308 309 // formerly, here was a setParent at the xColDesc. The parent used was an adapter (ChildHelper_Impl) 310 // which held another XChild weak, and forwarded all getParent requests to this other XChild. 311 // m_pColumns was used for this. This was nonsense, since m_pColumns dies when our instance dies, 312 // but xColDesc will live longer than this. So effectively, the setParent call was pretty useless. 313 // 314 // The intention for this parenting was that the column descriptor is able to find the data source, 315 // by traveling up the parent hierachy until there's an XDataSource. This didn't work (which 316 // for instance causes #i65023#). We need another way to properly ensure this. 317 318 notifyDataSourceModified(); 319 } 320 321 //........................................................................ 322 } // namespace dbaccess 323 //........................................................................ 324 325