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_svx.hxx" 30 #include <svx/dataaccessdescriptor.hxx> 31 #include <comphelper/stl_types.hxx> 32 #include <comphelper/propertysetinfo.hxx> 33 #include <comphelper/genericpropertyset.hxx> 34 #include <osl/diagnose.h> 35 #include <com/sun/star/sdbc/XConnection.hpp> 36 #include <com/sun/star/ucb/XContent.hpp> 37 #include <com/sun/star/beans/PropertyAttribute.hpp> 38 #include <tools/urlobj.hxx> 39 40 //........................................................................ 41 namespace svx 42 { 43 //........................................................................ 44 45 using namespace ::com::sun::star::uno; 46 using namespace ::com::sun::star::sdbc; 47 using namespace ::com::sun::star::beans; 48 using namespace ::com::sun::star::ucb; 49 using namespace ::comphelper; 50 51 #define CONST_CHAR( propname ) propname, sizeof(propname) - 1 52 53 #ifndef SVX_LIGHT 54 //==================================================================== 55 //= ODADescriptorImpl 56 //==================================================================== 57 class ODADescriptorImpl 58 { 59 protected: 60 sal_Bool m_bSetOutOfDate : 1; 61 sal_Bool m_bSequenceOutOfDate : 1; 62 63 public: 64 typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues; 65 DescriptorValues m_aValues; 66 Sequence< PropertyValue > m_aAsSequence; 67 Reference< XPropertySet > m_xAsSet; 68 69 typedef ::std::map< ::rtl::OUString, PropertyMapEntry* > MapString2PropertyEntry; 70 71 public: 72 ODADescriptorImpl(); 73 ODADescriptorImpl(const ODADescriptorImpl& _rSource); 74 75 void invalidateExternRepresentations(); 76 77 void updateSequence(); 78 void updateSet(); 79 80 /** builds the descriptor from a property value sequence 81 @return <TRUE/> 82 if and only if the sequence contained valid properties only 83 */ 84 sal_Bool buildFrom( const Sequence< PropertyValue >& _rValues ); 85 86 /** builds the descriptor from a property set 87 @return <TRUE/> 88 if and only if the set contained valid properties only 89 */ 90 sal_Bool buildFrom( const Reference< XPropertySet >& _rValues ); 91 92 protected: 93 static PropertyValue buildPropertyValue( const DescriptorValues::const_iterator& _rPos ); 94 static const MapString2PropertyEntry& getPropertyMap( ); 95 static PropertyMapEntry* getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos ); 96 }; 97 98 //-------------------------------------------------------------------- 99 ODADescriptorImpl::ODADescriptorImpl() 100 :m_bSetOutOfDate(sal_True) 101 ,m_bSequenceOutOfDate(sal_True) 102 { 103 } 104 105 //-------------------------------------------------------------------- 106 ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource) 107 :m_bSetOutOfDate( _rSource.m_bSetOutOfDate ) 108 ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate ) 109 ,m_aValues( _rSource.m_aValues ) 110 { 111 if (!m_bSetOutOfDate) 112 m_xAsSet = _rSource.m_xAsSet; 113 if (!m_bSequenceOutOfDate) 114 m_aAsSequence = _rSource.m_aAsSequence; 115 } 116 117 //-------------------------------------------------------------------- 118 sal_Bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues ) 119 { 120 const MapString2PropertyEntry& rProperties = getPropertyMap(); 121 122 sal_Bool bValidPropsOnly = sal_True; 123 124 // loop through the sequence, and fill our m_aValues 125 const PropertyValue* pValues = _rValues.getConstArray(); 126 const PropertyValue* pValuesEnd = pValues + _rValues.getLength(); 127 for (;pValues != pValuesEnd; ++pValues) 128 { 129 MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( pValues->Name ); 130 if ( aPropPos != rProperties.end() ) 131 { 132 DataAccessDescriptorProperty eProperty = (DataAccessDescriptorProperty)aPropPos->second->mnHandle; 133 m_aValues[eProperty] = pValues->Value; 134 } 135 else 136 // unknown property 137 bValidPropsOnly = sal_False; 138 } 139 140 if (bValidPropsOnly) 141 { 142 m_aAsSequence = _rValues; 143 m_bSequenceOutOfDate = sal_False; 144 } 145 else 146 m_bSequenceOutOfDate = sal_True; 147 148 return bValidPropsOnly; 149 } 150 151 //-------------------------------------------------------------------- 152 sal_Bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues ) 153 { 154 Reference< XPropertySetInfo > xPropInfo; 155 if (_rxValues.is()) 156 xPropInfo = _rxValues->getPropertySetInfo(); 157 if (!xPropInfo.is()) 158 { 159 OSL_ENSURE(sal_False, "ODADescriptorImpl::buildFrom: invalid property set!"); 160 return sal_False; 161 } 162 163 // build a PropertyValue sequence with the current values 164 Sequence< Property > aProperties = xPropInfo->getProperties(); 165 const Property* pProperty = aProperties.getConstArray(); 166 const Property* pPropertyEnd = pProperty + aProperties.getLength(); 167 168 Sequence< PropertyValue > aValues(aProperties.getLength()); 169 PropertyValue* pValues = aValues.getArray(); 170 171 for (;pProperty != pPropertyEnd; ++pProperty, ++pValues) 172 { 173 pValues->Name = pProperty->Name; 174 pValues->Value = _rxValues->getPropertyValue(pProperty->Name); 175 } 176 177 sal_Bool bValidPropsOnly = buildFrom(aValues); 178 if (bValidPropsOnly) 179 { 180 m_xAsSet = _rxValues; 181 m_bSetOutOfDate = sal_False; 182 } 183 else 184 m_bSetOutOfDate = sal_True; 185 186 return bValidPropsOnly; 187 } 188 189 //-------------------------------------------------------------------- 190 void ODADescriptorImpl::invalidateExternRepresentations() 191 { 192 m_bSetOutOfDate = sal_True; 193 m_bSequenceOutOfDate = sal_True; 194 } 195 196 //-------------------------------------------------------------------- 197 const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( ) 198 { 199 // the properties we know 200 static MapString2PropertyEntry s_aProperties; 201 if ( s_aProperties.empty() ) 202 { 203 static PropertyMapEntry s_aDesriptorProperties[] = 204 { 205 { CONST_CHAR("ActiveConnection"), daConnection, &::getCppuType( static_cast< Reference< XConnection >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 206 { CONST_CHAR("BookmarkSelection"), daBookmarkSelection, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 }, 207 { CONST_CHAR("Column"), daColumnObject, &::getCppuType( static_cast< Reference< XPropertySet >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 208 { CONST_CHAR("ColumnName"), daColumnName, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 209 { CONST_CHAR("Command"), daCommand, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 210 { CONST_CHAR("CommandType"), daCommandType, &::getCppuType( static_cast< sal_Int32* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 211 { CONST_CHAR("Component"), daComponent, &::getCppuType( static_cast< Reference< XContent >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 212 { CONST_CHAR("ConnectionResource"), daConnectionResource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 213 { CONST_CHAR("Cursor"), daCursor, &::getCppuType( static_cast< Reference< XResultSet>* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 214 { CONST_CHAR("DataSourceName"), daDataSource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 215 { CONST_CHAR("DatabaseLocation"), daDatabaseLocation, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 216 { CONST_CHAR("EscapeProcessing"), daEscapeProcessing, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 }, 217 { CONST_CHAR("Filter"), daFilter, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 218 { CONST_CHAR("Selection"), daSelection, &::getCppuType( static_cast< Sequence< Any >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, 219 { NULL, 0, 0, NULL, 0, 0 } 220 }; 221 222 PropertyMapEntry* pEntry = s_aDesriptorProperties; 223 while ( pEntry->mpName ) 224 { 225 s_aProperties[ ::rtl::OUString::createFromAscii( pEntry->mpName ) ] = pEntry; 226 ++pEntry; 227 } 228 } 229 230 return s_aProperties; 231 } 232 233 //-------------------------------------------------------------------- 234 PropertyMapEntry* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos ) 235 { 236 const MapString2PropertyEntry& rProperties = getPropertyMap(); 237 238 sal_Int32 nNeededHandle = (sal_Int32)(_rPos->first); 239 240 for ( MapString2PropertyEntry::const_iterator loop = rProperties.begin(); 241 loop != rProperties.end(); 242 ++loop 243 ) 244 { 245 if ( nNeededHandle == loop->second->mnHandle ) 246 return loop->second; 247 } 248 throw RuntimeException(); 249 } 250 251 //-------------------------------------------------------------------- 252 PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos ) 253 { 254 // the map entry 255 PropertyMapEntry* pProperty = getPropertyMapEntry( _rPos ); 256 257 // build the property value 258 PropertyValue aReturn; 259 aReturn.Name = ::rtl::OUString( pProperty->mpName, pProperty->mnNameLen, RTL_TEXTENCODING_ASCII_US ); 260 aReturn.Handle = pProperty->mnHandle; 261 aReturn.Value = _rPos->second; 262 aReturn.State = PropertyState_DIRECT_VALUE; 263 264 // outta here 265 return aReturn; 266 } 267 268 //-------------------------------------------------------------------- 269 void ODADescriptorImpl::updateSequence() 270 { 271 if (!m_bSequenceOutOfDate) 272 return; 273 274 m_aAsSequence.realloc(m_aValues.size()); 275 PropertyValue* pValue = m_aAsSequence.getArray(); 276 277 // loop through all our values 278 for ( DescriptorValues::const_iterator aLoop = m_aValues.begin(); 279 aLoop != m_aValues.end(); 280 ++aLoop, ++pValue 281 ) 282 { 283 *pValue = buildPropertyValue(aLoop); 284 } 285 286 // don't need to rebuild next time 287 m_bSequenceOutOfDate = sal_False; 288 } 289 290 //-------------------------------------------------------------------- 291 void ODADescriptorImpl::updateSet() 292 { 293 if (!m_bSetOutOfDate) 294 return; 295 296 // will be the current values 297 Sequence< PropertyValue > aValuesToSet(m_aValues.size()); 298 PropertyValue* pValuesToSet = aValuesToSet.getArray(); 299 300 // build a new property set info 301 PropertySetInfo* pPropSetInfo = new PropertySetInfo; 302 303 // loop through all our values 304 for ( DescriptorValues::const_iterator aLoop = m_aValues.begin(); 305 aLoop != m_aValues.end(); 306 ++aLoop, ++pValuesToSet 307 ) 308 { 309 PropertyMapEntry* pMapEntry = getPropertyMapEntry( aLoop ); 310 pPropSetInfo->add( pMapEntry, 1 ); 311 312 *pValuesToSet = buildPropertyValue(aLoop); 313 } 314 315 // create the generic set 316 m_xAsSet = GenericPropertySet_CreateInstance( pPropSetInfo ); 317 318 // no we have the set, still need to set the current values 319 const PropertyValue* pSetValues = aValuesToSet.getConstArray(); 320 const PropertyValue* pSetValuesEnd = pSetValues + aValuesToSet.getLength(); 321 for (; pSetValues != pSetValuesEnd; ++pSetValues) 322 m_xAsSet->setPropertyValue(pSetValues->Name, pSetValues->Value); 323 324 // don't need to rebuild next time 325 m_bSetOutOfDate = sal_True; 326 } 327 #endif 328 329 //==================================================================== 330 //= ODataAccessDescriptor 331 //==================================================================== 332 //-------------------------------------------------------------------- 333 ODataAccessDescriptor::ODataAccessDescriptor() 334 #ifndef SVX_LIGHT 335 :m_pImpl(new ODADescriptorImpl) 336 #else 337 :m_pImpl(NULL) 338 #endif 339 { 340 } 341 342 //-------------------------------------------------------------------- 343 ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource ) 344 #ifndef SVX_LIGHT 345 :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl)) 346 #else 347 :m_pImpl(NULL) 348 #endif 349 { 350 } 351 352 //-------------------------------------------------------------------- 353 const ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource) 354 { 355 #ifndef SVX_LIGHT 356 delete m_pImpl; 357 m_pImpl = new ODADescriptorImpl(*_rSource.m_pImpl); 358 #else 359 OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator=: not available in the SVX_LIGHT version!"); 360 #endif 361 return *this; 362 } 363 364 //-------------------------------------------------------------------- 365 ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues ) 366 #ifndef SVX_LIGHT 367 :m_pImpl(new ODADescriptorImpl) 368 #else 369 :m_pImpl(NULL) 370 #endif 371 { 372 #ifndef SVX_LIGHT 373 m_pImpl->buildFrom(_rValues); 374 #else 375 OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); 376 #endif 377 } 378 379 //-------------------------------------------------------------------- 380 ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues ) 381 #ifndef SVX_LIGHT 382 :m_pImpl(new ODADescriptorImpl) 383 #else 384 :m_pImpl(NULL) 385 #endif 386 { 387 #ifndef SVX_LIGHT 388 // check if we know the format in the Any 389 Sequence< PropertyValue > aValues; 390 Reference< XPropertySet > xValues; 391 if ( _rValues >>= aValues ) 392 m_pImpl->buildFrom( aValues ); 393 else if ( _rValues >>= xValues ) 394 m_pImpl->buildFrom( xValues ); 395 #else 396 OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); 397 #endif 398 } 399 400 //-------------------------------------------------------------------- 401 ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues ) 402 #ifndef SVX_LIGHT 403 :m_pImpl(new ODADescriptorImpl) 404 #else 405 :m_pImpl(NULL) 406 #endif 407 { 408 #ifndef SVX_LIGHT 409 m_pImpl->buildFrom(_rValues); 410 #else 411 OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); 412 #endif 413 } 414 415 //-------------------------------------------------------------------- 416 ODataAccessDescriptor::~ODataAccessDescriptor() 417 { 418 delete m_pImpl; 419 } 420 421 //-------------------------------------------------------------------- 422 void ODataAccessDescriptor::clear() 423 { 424 #ifndef SVX_LIGHT 425 m_pImpl->m_aValues.clear(); 426 #endif 427 } 428 429 //-------------------------------------------------------------------- 430 void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich) 431 { 432 #ifndef SVX_LIGHT 433 OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!"); 434 if (has(_eWhich)) 435 m_pImpl->m_aValues.erase(_eWhich); 436 #endif 437 } 438 439 //-------------------------------------------------------------------- 440 sal_Bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const 441 { 442 #ifndef SVX_LIGHT 443 return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end(); 444 #else 445 return sal_False; 446 #endif 447 } 448 449 //-------------------------------------------------------------------- 450 const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const 451 { 452 #ifndef SVX_LIGHT 453 if (!has(_eWhich)) 454 { 455 OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator[]: invalid acessor!"); 456 static const Any aDummy; 457 return aDummy; 458 } 459 460 return m_pImpl->m_aValues[_eWhich]; 461 #else 462 static const Any aDummy; 463 return aDummy; 464 #endif 465 } 466 467 //-------------------------------------------------------------------- 468 Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich ) 469 { 470 #ifndef SVX_LIGHT 471 m_pImpl->invalidateExternRepresentations(); 472 return m_pImpl->m_aValues[_eWhich]; 473 #else 474 static const Any aDummy; 475 return aDummy; 476 #endif 477 } 478 479 //-------------------------------------------------------------------- 480 void ODataAccessDescriptor::initializeFrom(const Reference< XPropertySet >& _rxValues, sal_Bool _bClear) 481 { 482 #ifndef SVX_LIGHT 483 if (_bClear) 484 clear(); 485 m_pImpl->buildFrom(_rxValues); 486 #endif 487 } 488 489 //-------------------------------------------------------------------- 490 void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues, sal_Bool _bClear) 491 { 492 #ifndef SVX_LIGHT 493 if (_bClear) 494 clear(); 495 m_pImpl->buildFrom(_rValues); 496 #endif 497 } 498 499 //-------------------------------------------------------------------- 500 Sequence< PropertyValue > ODataAccessDescriptor::createPropertyValueSequence() 501 { 502 #ifndef SVX_LIGHT 503 m_pImpl->updateSequence(); 504 return m_pImpl->m_aAsSequence; 505 #else 506 return Sequence< PropertyValue >(); 507 #endif 508 } 509 //-------------------------------------------------------------------- 510 Sequence< Any > ODataAccessDescriptor::createAnySequence() 511 { 512 #ifndef SVX_LIGHT 513 m_pImpl->updateSequence(); 514 Sequence< Any > aRet(m_pImpl->m_aAsSequence.getLength()); 515 const PropertyValue* pBegin = m_pImpl->m_aAsSequence.getConstArray(); 516 const PropertyValue* pEnd = pBegin + m_pImpl->m_aAsSequence.getLength(); 517 for(sal_Int32 i=0;pBegin != pEnd;++pBegin,++i) 518 aRet[i] <<= *pBegin; 519 return aRet; 520 #else 521 return Sequence< createAnySequence >(); 522 #endif 523 } 524 525 //-------------------------------------------------------------------- 526 Reference< XPropertySet > ODataAccessDescriptor::createPropertySet() 527 { 528 #ifndef SVX_LIGHT 529 m_pImpl->updateSet(); 530 return m_pImpl->m_xAsSet; 531 #else 532 return Reference< XPropertySet >(); 533 #endif 534 } 535 //-------------------------------------------------------------------- 536 ::rtl::OUString ODataAccessDescriptor::getDataSource() const 537 { 538 #ifndef SVX_LIGHT 539 ::rtl::OUString sDataSourceName; 540 if ( has(daDataSource) ) 541 (*this)[daDataSource] >>= sDataSourceName; 542 else if ( has(daDatabaseLocation) ) 543 (*this)[daDatabaseLocation] >>= sDataSourceName; 544 return sDataSourceName; 545 #else 546 return ::rtl::OUString(); 547 #endif 548 } 549 //-------------------------------------------------------------------- 550 void ODataAccessDescriptor::setDataSource(const ::rtl::OUString& _sDataSourceNameOrLocation) 551 { 552 #ifndef SVX_LIGHT 553 if ( _sDataSourceNameOrLocation.getLength() ) 554 { 555 INetURLObject aURL(_sDataSourceNameOrLocation); 556 (*this)[ (( aURL.GetProtocol() == INET_PROT_FILE ) ? daDatabaseLocation : daDataSource)] <<= _sDataSourceNameOrLocation; 557 } 558 else 559 (*this)[ daDataSource ] <<= ::rtl::OUString(); 560 #endif 561 } 562 563 //........................................................................ 564 } // namespace svx 565 //........................................................................ 566 567 568