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