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 31 #include "apitools.hxx" 32 #include "dbastrings.hrc" 33 #include "definitioncolumn.hxx" 34 #include "sdbcoretools.hxx" 35 36 /** === begin UNO includes === **/ 37 #include <com/sun/star/beans/PropertyAttribute.hpp> 38 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 39 /** === end UNO includes === **/ 40 41 #include <comphelper/property.hxx> 42 #include <comphelper/types.hxx> 43 #include <connectivity/dbtools.hxx> 44 #include <cppuhelper/typeprovider.hxx> 45 #include <tools/debug.hxx> 46 #include <tools/diagnose_ex.h> 47 48 using namespace ::com::sun::star::sdbc; 49 using namespace ::com::sun::star::sdbcx; 50 using namespace ::com::sun::star::beans; 51 using namespace ::com::sun::star::uno; 52 using namespace ::com::sun::star::lang; 53 using namespace ::com::sun::star::container; 54 using namespace ::cppu; 55 using namespace ::comphelper; 56 using namespace ::osl; 57 using namespace dbaccess; 58 59 #define HAS_DESCRIPTION 0x00000001 60 #define HAS_DEFAULTVALUE 0x00000002 61 #define HAS_ROWVERSION 0x00000004 62 #define HAS_AUTOINCREMENT_CREATION 0x00000008 63 64 //============================================================ 65 //= OTableColumnDescriptor 66 //============================================================ 67 IMPLEMENT_FORWARD_XINTERFACE2(OTableColumnDescriptor,OColumn,TXChild) 68 69 //------------------------------------------------------------------------------ 70 void OTableColumnDescriptor::impl_registerProperties() 71 { 72 sal_Int32 nDefaultAttr = m_bActAsDescriptor ? 0 : PropertyAttribute::READONLY; 73 74 registerProperty( PROPERTY_TYPENAME, PROPERTY_ID_TYPENAME, nDefaultAttr, &m_aTypeName, ::getCppuType( &m_aTypeName ) ); 75 registerProperty( PROPERTY_DESCRIPTION, PROPERTY_ID_DESCRIPTION, nDefaultAttr, &m_aDescription, ::getCppuType( &m_aDescription ) ); 76 registerProperty( PROPERTY_DEFAULTVALUE, PROPERTY_ID_DEFAULTVALUE, nDefaultAttr, &m_aDefaultValue, ::getCppuType( &m_aDefaultValue ) ); 77 78 if ( m_bActAsDescriptor ) 79 registerProperty( PROPERTY_AUTOINCREMENTCREATION, PROPERTY_ID_AUTOINCREMENTCREATION, nDefaultAttr, &m_aAutoIncrementValue, ::getCppuType( &m_aAutoIncrementValue ) ); 80 81 registerProperty( PROPERTY_TYPE, PROPERTY_ID_TYPE, nDefaultAttr, &m_nType, ::getCppuType( &m_nType ) ); 82 registerProperty( PROPERTY_PRECISION, PROPERTY_ID_PRECISION, nDefaultAttr, &m_nPrecision, ::getCppuType( &m_nPrecision ) ); 83 registerProperty( PROPERTY_SCALE, PROPERTY_ID_SCALE, nDefaultAttr, &m_nScale, ::getCppuType( &m_nScale ) ); 84 registerProperty( PROPERTY_ISNULLABLE, PROPERTY_ID_ISNULLABLE, nDefaultAttr, &m_nIsNullable, ::getCppuType( &m_nIsNullable ) ); 85 registerProperty( PROPERTY_ISAUTOINCREMENT, PROPERTY_ID_ISAUTOINCREMENT, nDefaultAttr, &m_bAutoIncrement, ::getCppuType( &m_bAutoIncrement ) ); 86 registerProperty( PROPERTY_ISROWVERSION, PROPERTY_ID_ISROWVERSION, nDefaultAttr, &m_bRowVersion, ::getCppuType( &m_bRowVersion ) ); 87 registerProperty( PROPERTY_ISCURRENCY, PROPERTY_ID_ISCURRENCY, nDefaultAttr, &m_bCurrency, ::getCppuType( &m_bCurrency ) ); 88 89 OColumnSettings::registerProperties( *this ); 90 } 91 92 //-------------------------------------------------------------------------- 93 IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnDescriptor ) 94 95 // ::com::sun::star::lang::XServiceInfo 96 //------------------------------------------------------------------------------ 97 rtl::OUString OTableColumnDescriptor::getImplementationName( ) throw (RuntimeException) 98 { 99 return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumnDescriptor"); 100 } 101 102 //------------------------------------------------------------------------------ 103 Sequence< ::rtl::OUString > OTableColumnDescriptor::getSupportedServiceNames( ) throw (RuntimeException) 104 { 105 Sequence< ::rtl::OUString > aSNS( 2 ); 106 aSNS[0] = m_bActAsDescriptor ? SERVICE_SDBCX_COLUMNDESCRIPTOR : SERVICE_SDBCX_COLUMN; 107 aSNS[1] = SERVICE_SDB_COLUMNSETTINGS; 108 return aSNS; 109 } 110 111 // comphelper::OPropertyArrayUsageHelper 112 //------------------------------------------------------------------------------ 113 ::cppu::IPropertyArrayHelper* OTableColumnDescriptor::createArrayHelper( ) const 114 { 115 Sequence< Property > aProps; 116 describeProperties( aProps ); 117 return new ::cppu::OPropertyArrayHelper( aProps ); 118 } 119 120 // cppu::OPropertySetHelper 121 //------------------------------------------------------------------------------ 122 ::cppu::IPropertyArrayHelper& OTableColumnDescriptor::getInfoHelper() 123 { 124 return *static_cast< ::comphelper::OPropertyArrayUsageHelper< OTableColumnDescriptor >* >(this)->getArrayHelper(); 125 } 126 127 //------------------------------------------------------------------------------ 128 void OTableColumnDescriptor::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) 129 { 130 OColumn::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 131 ::dbaccess::notifyDataSourceModified( m_xParent, sal_True ); 132 } 133 134 // ----------------------------------------------------------------------------- 135 Reference< XInterface > SAL_CALL OTableColumnDescriptor::getParent( ) throw (RuntimeException) 136 { 137 ::osl::MutexGuard aGuard(m_aMutex); 138 return m_xParent; 139 } 140 // ----------------------------------------------------------------------------- 141 void SAL_CALL OTableColumnDescriptor::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException) 142 { 143 ::osl::MutexGuard aGuard(m_aMutex); 144 m_xParent = _xParent; 145 } 146 //============================================================ 147 //= OTableColumn 148 //============================================================ 149 DBG_NAME(OTableColumn); 150 151 // ------------------------------------------------------------------------- 152 OTableColumn::OTableColumn( const ::rtl::OUString& _rName ) 153 :OTableColumnDescriptor( false /* do not act as descriptor */ ) 154 { 155 DBG_CTOR(OTableColumn,NULL); 156 m_sName = _rName; 157 } 158 159 // ----------------------------------------------------------------------------- 160 OTableColumn::~OTableColumn() 161 { 162 DBG_DTOR(OTableColumn,NULL); 163 } 164 165 //-------------------------------------------------------------------------- 166 IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumn ) 167 168 //------------------------------------------------------------------------------ 169 rtl::OUString OTableColumn::getImplementationName( ) throw (RuntimeException) 170 { 171 return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumn"); 172 } 173 174 //------------------------------------------------------------------------------ 175 ::cppu::IPropertyArrayHelper& SAL_CALL OTableColumn::getInfoHelper() 176 { 177 return *OTableColumn_PBase::getArrayHelper(); 178 } 179 180 //------------------------------------------------------------------------------ 181 ::cppu::IPropertyArrayHelper* OTableColumn::createArrayHelper( ) const 182 { 183 return OTableColumnDescriptor::createArrayHelper(); 184 } 185 186 // ========================================================================= 187 //= OQueryColumn 188 // ========================================================================= 189 DBG_NAME( OQueryColumn ); 190 191 // ------------------------------------------------------------------------- 192 OQueryColumn::OQueryColumn( const Reference< XPropertySet >& _rxParserColumn, const Reference< XConnection >& _rxConnection,const ::rtl::OUString i_sLabel ) 193 :OTableColumnDescriptor( false /* do not act as descriptor */ ) 194 ,m_sLabel(i_sLabel) 195 { 196 const sal_Int32 nPropAttr = PropertyAttribute::READONLY; 197 registerProperty( PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME, nPropAttr, &m_sCatalogName, ::getCppuType( &m_sCatalogName ) ); 198 registerProperty( PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME, nPropAttr, &m_sSchemaName, ::getCppuType( &m_sSchemaName ) ); 199 registerProperty( PROPERTY_TABLENAME, PROPERTY_ID_TABLENAME, nPropAttr, &m_sTableName, ::getCppuType( &m_sTableName ) ); 200 registerProperty( PROPERTY_REALNAME, PROPERTY_ID_REALNAME, nPropAttr, &m_sRealName, ::getCppuType( &m_sRealName ) ); 201 registerProperty( PROPERTY_LABEL, PROPERTY_ID_LABEL, nPropAttr, &m_sLabel, ::getCppuType( &m_sLabel ) ); 202 203 DBG_CTOR( OQueryColumn, NULL ); 204 205 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_TYPENAME ) >>= m_aTypeName ); 206 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= m_nIsNullable ); 207 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_PRECISION ) >>= m_nPrecision ); 208 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_SCALE ) >>= m_nScale ); 209 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_TYPE ) >>= m_nType ); 210 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= m_bAutoIncrement ); 211 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISCURRENCY ) >>= m_bCurrency ); 212 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_NAME ) >>= m_sName ); 213 214 m_bRowVersion = sal_False; 215 216 Reference< XPropertySetInfo > xPSI( _rxParserColumn->getPropertySetInfo(), UNO_SET_THROW ); 217 if ( xPSI->hasPropertyByName( PROPERTY_DEFAULTVALUE ) ) 218 OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_DEFAULTVALUE ) >>= m_aDefaultValue ); 219 220 // copy some optional properties from the parser column 221 struct PropertyDescriptor 222 { 223 ::rtl::OUString sName; 224 sal_Int32 nHandle; 225 }; 226 PropertyDescriptor aProps[] = 227 { 228 { PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME }, 229 { PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME }, 230 { PROPERTY_TABLENAME, PROPERTY_ID_TABLENAME }, 231 { PROPERTY_REALNAME, PROPERTY_ID_REALNAME } 232 }; 233 for ( size_t i=0; i < sizeof( aProps ) / sizeof( aProps[0] ); ++i ) 234 { 235 if ( xPSI->hasPropertyByName( aProps[i].sName ) ) 236 setFastPropertyValue_NoBroadcast( aProps[i].nHandle, _rxParserColumn->getPropertyValue( aProps[i].sName ) ); 237 } 238 239 // determine the table column we're based on 240 osl_incrementInterlockedCount( &m_refCount ); 241 { 242 m_xOriginalTableColumn = impl_determineOriginalTableColumn( _rxConnection ); 243 } 244 osl_decrementInterlockedCount( &m_refCount ); 245 } 246 247 //-------------------------------------------------------------------------- 248 OQueryColumn::~OQueryColumn() 249 { 250 DBG_DTOR( OQueryColumn, NULL ); 251 } 252 253 //-------------------------------------------------------------------------- 254 Reference< XPropertySet > OQueryColumn::impl_determineOriginalTableColumn( const Reference< XConnection >& _rxConnection ) 255 { 256 OSL_PRECOND( _rxConnection.is(), "OQueryColumn::impl_determineOriginalTableColumn: illegal connection!" ); 257 if ( !_rxConnection.is() ) 258 return NULL; 259 260 Reference< XPropertySet > xOriginalTableColumn; 261 try 262 { 263 // determine the composed table name, plus the column name, as indicated by the 264 // respective properties 265 ::rtl::OUString sCatalog, sSchema, sTable; 266 OSL_VERIFY( getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog ); 267 OSL_VERIFY( getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema ); 268 OSL_VERIFY( getPropertyValue( PROPERTY_TABLENAME ) >>= sTable ); 269 if ( !sCatalog.getLength() && !sSchema.getLength() && !sTable.getLength() ) 270 return NULL; 271 272 ::rtl::OUString sComposedTableName = ::dbtools::composeTableName( 273 _rxConnection->getMetaData(), sCatalog, sSchema, sTable, sal_False, ::dbtools::eComplete ); 274 275 // retrieve the table in question 276 Reference< XTablesSupplier > xSuppTables( _rxConnection, UNO_QUERY_THROW ); 277 Reference< XNameAccess > xTables( xSuppTables->getTables(), UNO_QUERY_THROW ); 278 if ( !xTables->hasByName( sComposedTableName ) ) 279 return NULL; 280 281 Reference< XColumnsSupplier > xSuppCols( xTables->getByName( sComposedTableName ), UNO_QUERY_THROW ); 282 Reference< XNameAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW ); 283 284 ::rtl::OUString sColumn; 285 OSL_VERIFY( getPropertyValue( PROPERTY_REALNAME ) >>= sColumn ); 286 if ( !xColumns->hasByName( sColumn ) ) 287 return NULL; 288 289 xOriginalTableColumn.set( xColumns->getByName( sColumn ), UNO_QUERY ); 290 } 291 catch( const Exception& ) 292 { 293 DBG_UNHANDLED_EXCEPTION(); 294 } 295 return xOriginalTableColumn; 296 } 297 298 //-------------------------------------------------------------------------- 299 IMPLEMENT_GET_IMPLEMENTATION_ID( OQueryColumn ) 300 301 //-------------------------------------------------------------------------- 302 ::rtl::OUString SAL_CALL OQueryColumn::getImplementationName( ) throw(RuntimeException) 303 { 304 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbaccess.OQueryColumn" ) ); 305 } 306 307 //------------------------------------------------------------------------------ 308 ::cppu::IPropertyArrayHelper& SAL_CALL OQueryColumn::getInfoHelper() 309 { 310 return *OQueryColumn_PBase::getArrayHelper(); 311 } 312 313 //-------------------------------------------------------------------------- 314 ::cppu::IPropertyArrayHelper* OQueryColumn::createArrayHelper() const 315 { 316 return OTableColumnDescriptor::createArrayHelper(); 317 } 318 319 //-------------------------------------------------------------------------- 320 void SAL_CALL OQueryColumn::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const 321 { 322 OTableColumnDescriptor::getFastPropertyValue( _rValue, _nHandle ); 323 324 // special treatment for column settings: 325 if ( !OColumnSettings::isColumnSettingProperty( _nHandle ) ) 326 return; 327 328 // If the setting has its default value, then try to obtain the value from the table column which 329 // this query column is based on 330 if ( !OColumnSettings::isDefaulted( _nHandle, _rValue ) ) 331 return; 332 333 if ( !m_xOriginalTableColumn.is() ) 334 return; 335 336 try 337 { 338 // determine original property name 339 ::rtl::OUString sPropName; 340 sal_Int16 nAttributes( 0 ); 341 const_cast< OQueryColumn* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle ); 342 OSL_ENSURE( sPropName.getLength(), "OColumnWrapper::impl_getPropertyNameFromHandle: property not found!" ); 343 344 _rValue = m_xOriginalTableColumn->getPropertyValue( sPropName ); 345 } 346 catch( const Exception& ) 347 { 348 DBG_UNHANDLED_EXCEPTION(); 349 } 350 } 351 352 //========================================================================== 353 //= OColumnWrapper 354 //========================================================================== 355 DBG_NAME(OColumnWrapper); 356 //-------------------------------------------------------------------------- 357 OColumnWrapper::OColumnWrapper( const Reference< XPropertySet > & rCol, const bool _bNameIsReadOnly ) 358 :OColumn( _bNameIsReadOnly ) 359 ,m_xAggregate(rCol) 360 ,m_nColTypeID(-1) 361 { 362 DBG_CTOR(OColumnWrapper,NULL); 363 // which type of aggregate property do we have? 364 // we distingish the properties by the containment of optional properties 365 m_nColTypeID = 0; 366 if ( m_xAggregate.is() ) 367 { 368 Reference <XPropertySetInfo > xInfo(m_xAggregate->getPropertySetInfo()); 369 m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_DESCRIPTION) ? HAS_DESCRIPTION : 0; 370 m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_DEFAULTVALUE) ? HAS_DEFAULTVALUE : 0; 371 m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_ISROWVERSION) ? HAS_ROWVERSION : 0; 372 m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) ? HAS_AUTOINCREMENT_CREATION : 0; 373 374 m_xAggregate->getPropertyValue(PROPERTY_NAME) >>= m_sName; 375 } 376 } 377 // ----------------------------------------------------------------------------- 378 OColumnWrapper::~OColumnWrapper() 379 { 380 DBG_DTOR(OColumnWrapper,NULL); 381 } 382 383 //------------------------------------------------------------------------------ 384 ::rtl::OUString OColumnWrapper::impl_getPropertyNameFromHandle( const sal_Int32 _nHandle ) const 385 { 386 ::rtl::OUString sPropName; 387 sal_Int16 nAttributes( 0 ); 388 const_cast< OColumnWrapper* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle ); 389 OSL_ENSURE( sPropName.getLength(), "OColumnWrapper::impl_getPropertyNameFromHandle: property not found!" ); 390 return sPropName; 391 } 392 393 //------------------------------------------------------------------------------ 394 void OColumnWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const 395 { 396 // derived classes are free to either use the OPropertyContainer(Helper) mechanisms for properties, 397 // or to declare additional properties which are to be forwarded to the wrapped object. So we need 398 // to distinguish those cases. 399 if ( OColumn::isRegisteredProperty( nHandle ) ) 400 { 401 OColumn::getFastPropertyValue( rValue, nHandle ); 402 } 403 else 404 { 405 rValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) ); 406 } 407 } 408 409 //------------------------------------------------------------------------------ 410 sal_Bool OColumnWrapper::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, 411 const Any& rValue ) throw (IllegalArgumentException) 412 { 413 sal_Bool bModified( sal_False ); 414 if ( OColumn::isRegisteredProperty( nHandle ) ) 415 { 416 bModified = OColumn::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue ); 417 } 418 else 419 { 420 getFastPropertyValue( rOldValue, nHandle ); 421 if ( rOldValue != rValue ) 422 { 423 rConvertedValue = rValue; 424 bModified = sal_True; 425 } 426 } 427 return bModified; 428 } 429 430 //------------------------------------------------------------------------------ 431 void OColumnWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) 432 { 433 if ( OColumn::isRegisteredProperty( nHandle ) ) 434 { 435 OColumn::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 436 } 437 else 438 { 439 m_xAggregate->setPropertyValue( impl_getPropertyNameFromHandle( nHandle ), rValue ); 440 } 441 } 442 443 // ----------------------------------------------------------------------------- 444 sal_Int64 SAL_CALL OColumnWrapper::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw(RuntimeException) 445 { 446 Reference< XUnoTunnel > xTunnel( m_xAggregate, UNO_QUERY); 447 if ( xTunnel.is() ) 448 return xTunnel->getSomething( aIdentifier ); 449 return 0; 450 } 451 452 //============================================================ 453 //= OTableColumnDescriptorWrapper 454 //============================================================ 455 //-------------------------------------------------------------------------- 456 OTableColumnDescriptorWrapper::OTableColumnDescriptorWrapper( const Reference< XPropertySet >& _rCol, const bool _bPureWrap, const bool _bIsDescriptor ) 457 :OColumnWrapper( _rCol, !_bIsDescriptor ) 458 ,m_bPureWrap( _bPureWrap ) 459 ,m_bIsDescriptor( _bIsDescriptor ) 460 { 461 // let the ColumnSettings register its properties 462 OColumnSettings::registerProperties( *this ); 463 } 464 465 // com::sun::star::lang::XTypeProvider 466 //-------------------------------------------------------------------------- 467 IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnDescriptorWrapper ) 468 469 // ::com::sun::star::lang::XServiceInfo 470 //------------------------------------------------------------------------------ 471 rtl::OUString OTableColumnDescriptorWrapper::getImplementationName( ) throw (RuntimeException) 472 { 473 return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumnDescriptorWrapper"); 474 } 475 476 //------------------------------------------------------------------------------ 477 Sequence< ::rtl::OUString > OTableColumnDescriptorWrapper::getSupportedServiceNames( ) throw (RuntimeException) 478 { 479 Sequence< ::rtl::OUString > aSNS( 2 ); 480 aSNS[0] = SERVICE_SDBCX_COLUMNDESCRIPTOR; 481 aSNS[1] = SERVICE_SDB_COLUMNSETTINGS; 482 return aSNS; 483 } 484 485 // comphelper::OPropertyArrayUsageHelper 486 //------------------------------------------------------------------------------ 487 ::cppu::IPropertyArrayHelper* OTableColumnDescriptorWrapper::createArrayHelper( sal_Int32 nId ) const 488 { 489 const sal_Int32 nHaveAlways = 7; 490 491 // Which optional properties are contained? 492 sal_Int32 nHaveOptionally = 0; 493 if (nId & HAS_DESCRIPTION) 494 ++nHaveOptionally; 495 if (nId & HAS_DEFAULTVALUE) 496 ++nHaveOptionally; 497 if (nId & HAS_ROWVERSION) 498 ++nHaveOptionally; 499 if ( nId & HAS_AUTOINCREMENT_CREATION ) 500 ++nHaveOptionally; 501 502 const sal_Int32 nPropertyCount( nHaveAlways + nHaveOptionally ); 503 Sequence< Property > aTableDescProperties( nPropertyCount ); 504 Property* pDesc = aTableDescProperties.getArray(); 505 sal_Int32 nPos = 0; 506 507 DECL_PROP0_BOOL( ISAUTOINCREMENT ); 508 DECL_PROP0_BOOL( ISCURRENCY ); 509 DECL_PROP0( ISNULLABLE, sal_Int32 ); 510 DECL_PROP0( PRECISION, sal_Int32 ); 511 DECL_PROP0( SCALE, sal_Int32 ); 512 DECL_PROP0( TYPE, sal_Int32 ); 513 DECL_PROP0( TYPENAME, ::rtl::OUString ); 514 515 if ( nId & HAS_AUTOINCREMENT_CREATION ) 516 { 517 DECL_PROP1( AUTOINCREMENTCREATION, ::rtl::OUString, MAYBEVOID ); 518 } 519 if ( nId & HAS_DEFAULTVALUE ) 520 { 521 DECL_PROP0( DEFAULTVALUE, ::rtl::OUString ); 522 } 523 if ( nId & HAS_DESCRIPTION ) 524 { 525 DECL_PROP0( DESCRIPTION, ::rtl::OUString ); 526 } 527 if ( nId & HAS_ROWVERSION ) 528 { 529 DECL_PROP0_BOOL( ISROWVERSION ); 530 } 531 532 OSL_ENSURE( nPos == nPropertyCount, "OTableColumnDescriptorWrapper::createArrayHelper: something went wrong!" ); 533 534 if ( !m_bIsDescriptor ) 535 { 536 for ( Property* prop = aTableDescProperties.getArray(); 537 prop != aTableDescProperties.getArray() + aTableDescProperties.getLength(); 538 ++prop 539 ) 540 { 541 prop->Attributes |= PropertyAttribute::READONLY; 542 } 543 } 544 545 // finally also describe the properties which are maintained by our base class, in particular the OPropertyContainerHelper 546 Sequence< Property > aBaseProperties; 547 describeProperties( aBaseProperties ); 548 549 Sequence< Property > aAllProperties( ::comphelper::concatSequences( aTableDescProperties, aBaseProperties ) ); 550 return new ::cppu::OPropertyArrayHelper( aAllProperties, sal_False ); 551 } 552 553 // cppu::OPropertySetHelper 554 //------------------------------------------------------------------------------ 555 ::cppu::IPropertyArrayHelper& OTableColumnDescriptorWrapper::getInfoHelper() 556 { 557 return *static_cast< OIdPropertyArrayUsageHelper< OTableColumnDescriptorWrapper >* >(this)->getArrayHelper(m_nColTypeID); 558 } 559 560 //------------------------------------------------------------------------------ 561 void OTableColumnDescriptorWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const 562 { 563 if ( m_bPureWrap ) 564 { 565 rValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) ); 566 } 567 else 568 { 569 OColumnWrapper::getFastPropertyValue( rValue, nHandle ); 570 } 571 } 572 573 //------------------------------------------------------------------------------ 574 sal_Bool OTableColumnDescriptorWrapper::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw (IllegalArgumentException) 575 { 576 sal_Bool bModified(sal_False); 577 if ( m_bPureWrap ) 578 { 579 // do not delegate to OColumnWrapper: It would, for the properties which were registered with registerProperty, 580 // ask the OPropertyContainer base class, which is not what we want here. 581 // TODO: the whole "m_bPureWrap"-thingie is strange. We should have a dedicated class doing this wrapping, 582 // not a class which normally serves other purposes, and only sometimes does a "pure wrap". It makes the 583 // code unnecessarily hard to maintain, and error prone. 584 rOldValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) ); 585 if ( rOldValue != rValue ) 586 { 587 rConvertedValue = rValue; 588 bModified = sal_True; 589 } 590 } 591 else 592 { 593 bModified = OColumnWrapper::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue ); 594 } 595 return bModified; 596 } 597 598 //------------------------------------------------------------------------------ 599 void OTableColumnDescriptorWrapper::setFastPropertyValue_NoBroadcast( 600 sal_Int32 nHandle, 601 const Any& rValue 602 ) 603 throw (Exception) 604 { 605 if ( m_bPureWrap ) 606 { 607 m_xAggregate->setPropertyValue( impl_getPropertyNameFromHandle( nHandle ), rValue ); 608 } 609 else 610 { 611 OColumnWrapper::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 612 } 613 } 614 615 //============================================================ 616 //= OTableColumnWrapper 617 //============================================================ 618 //-------------------------------------------------------------------------- 619 OTableColumnWrapper::OTableColumnWrapper( const Reference< XPropertySet >& rCol, const Reference< XPropertySet >& _xColDefintion, 620 const bool _bPureWrap ) 621 :OTableColumnDescriptorWrapper( rCol, _bPureWrap, false ) 622 { 623 osl_incrementInterlockedCount( &m_refCount ); 624 if ( _xColDefintion.is() ) 625 { 626 try 627 { 628 ::comphelper::copyProperties( _xColDefintion, this ); 629 } 630 catch( const Exception& ) 631 { 632 DBG_UNHANDLED_EXCEPTION(); 633 } 634 } 635 osl_decrementInterlockedCount( &m_refCount ); 636 } 637 638 //-------------------------------------------------------------------------- 639 OTableColumnWrapper::~OTableColumnWrapper() 640 { 641 } 642 643 //-------------------------------------------------------------------------- 644 IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnWrapper ) 645 646 //------------------------------------------------------------------------------ 647 rtl::OUString OTableColumnWrapper::getImplementationName( ) throw (RuntimeException) 648 { 649 return rtl::OUString::createFromAscii( "com.sun.star.sdb.OTableColumnWrapper" ); 650 } 651 652 //------------------------------------------------------------------------------ 653 Sequence< ::rtl::OUString > OTableColumnWrapper::getSupportedServiceNames( ) throw (RuntimeException) 654 { 655 Sequence< ::rtl::OUString > aSNS( 2 ); 656 aSNS[0] = SERVICE_SDBCX_COLUMN; 657 aSNS[1] = SERVICE_SDB_COLUMNSETTINGS; 658 return aSNS; 659 } 660 661 //------------------------------------------------------------------------------ 662 ::cppu::IPropertyArrayHelper& OTableColumnWrapper::getInfoHelper() 663 { 664 return *static_cast< OIdPropertyArrayUsageHelper< OTableColumnWrapper >* >(this)->getArrayHelper(m_nColTypeID); 665 } 666 667 // comphelper::OPropertyArrayUsageHelper 668 //------------------------------------------------------------------------------ 669 ::cppu::IPropertyArrayHelper* OTableColumnWrapper::createArrayHelper( sal_Int32 nId ) const 670 { 671 return OTableColumnDescriptorWrapper::createArrayHelper( nId ); 672 } 673 674