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_ucb.hxx" 26 27 /************************************************************************** 28 TODO 29 ************************************************************************** 30 31 *************************************************************************/ 32 #include <osl/diagnose.h> 33 #include <cppuhelper/interfacecontainer.hxx> 34 #include <com/sun/star/lang/IllegalArgumentException.hpp> 35 #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp> 36 #include <com/sun/star/ucb/XCommandInfo.hpp> 37 #include <com/sun/star/ucb/XContentProvider.hpp> 38 #include <com/sun/star/ucb/XContentProviderSupplier.hpp> 39 #include <com/sun/star/ucb/XParameterizedContentProvider.hpp> 40 #include <com/sun/star/ucb/XContentProviderFactory.hpp> 41 #include <com/sun/star/beans/PropertyValue.hpp> 42 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 43 #include <com/sun/star/container/XNameAccess.hpp> 44 #include <com/sun/star/uno/Any.hxx> 45 #include <ucbhelper/cancelcommandexecution.hxx> 46 #include "identify.hxx" 47 #include "ucbcmds.hxx" 48 49 #include "ucb.hxx" 50 51 // Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template 52 // instantiations for these in another compilation unit...): 53 #ifndef _UCB_REGEXPMAP_TPT_ 54 #include <regexpmap.tpt> 55 #endif 56 57 using namespace rtl; 58 using namespace cppu; 59 using namespace com::sun::star::uno; 60 using namespace com::sun::star::lang; 61 using namespace com::sun::star::ucb; 62 using namespace ucb_impl; 63 using namespace com::sun::star; 64 using namespace ucbhelper; 65 66 67 #define CONFIG_CONTENTPROVIDERS_KEY \ 68 "/org.openoffice.ucb.Configuration/ContentProviders" 69 70 71 namespace { 72 73 bool fillPlaceholders(rtl::OUString const & rInput, 74 uno::Sequence< uno::Any > const & rReplacements, 75 rtl::OUString * pOutput) 76 { 77 sal_Unicode const * p = rInput.getStr(); 78 sal_Unicode const * pEnd = p + rInput.getLength(); 79 sal_Unicode const * pCopy = p; 80 rtl::OUStringBuffer aBuffer; 81 while (p != pEnd) 82 switch (*p++) 83 { 84 case '&': 85 if (pEnd - p >= 4 86 && p[0] == 'a' && p[1] == 'm' && p[2] == 'p' 87 && p[3] == ';') 88 { 89 aBuffer.append(pCopy, p - 1 - pCopy); 90 aBuffer.append(sal_Unicode('&')); 91 p += 4; 92 pCopy = p; 93 } 94 else if (pEnd - p >= 3 95 && p[0] == 'l' && p[1] == 't' && p[2] == ';') 96 { 97 aBuffer.append(pCopy, p - 1 - pCopy); 98 aBuffer.append(sal_Unicode('<')); 99 p += 3; 100 pCopy = p; 101 } 102 else if (pEnd - p >= 3 103 && p[0] == 'g' && p[1] == 't' && p[2] == ';') 104 { 105 aBuffer.append(pCopy, p - 1 - pCopy); 106 aBuffer.append(sal_Unicode('>')); 107 p += 3; 108 pCopy = p; 109 } 110 break; 111 112 case '<': 113 sal_Unicode const * q = p; 114 while (q != pEnd && *q != '>') 115 ++q; 116 if (q == pEnd) 117 break; 118 rtl::OUString aKey(p, q - p); 119 rtl::OUString aValue; 120 bool bFound = false; 121 for (sal_Int32 i = 2; i + 1 < rReplacements.getLength(); 122 i += 2) 123 { 124 rtl::OUString aReplaceKey; 125 if ((rReplacements[i] >>= aReplaceKey) 126 && aReplaceKey == aKey 127 && (rReplacements[i + 1] >>= aValue)) 128 { 129 bFound = true; 130 break; 131 } 132 } 133 if (!bFound) 134 return false; 135 aBuffer.append(pCopy, p - 1 - pCopy); 136 aBuffer.append(aValue); 137 p = q + 1; 138 pCopy = p; 139 break; 140 } 141 aBuffer.append(pCopy, pEnd - pCopy); 142 *pOutput = aBuffer.makeStringAndClear(); 143 return true; 144 } 145 146 void makeAndAppendXMLName( 147 rtl::OUStringBuffer & rBuffer, const rtl::OUString & rIn ) 148 { 149 sal_Int32 nCount = rIn.getLength(); 150 for ( sal_Int32 n = 0; n < nCount; ++n ) 151 { 152 const sal_Unicode c = rIn.getStr()[ n ]; 153 switch ( c ) 154 { 155 case '&': 156 rBuffer.appendAscii( "&" ); 157 break; 158 159 case '"': 160 rBuffer.appendAscii( """ ); 161 break; 162 163 case '\'': 164 rBuffer.appendAscii( "'" ); 165 break; 166 167 case '<': 168 rBuffer.appendAscii( "<" ); 169 break; 170 171 case '>': 172 rBuffer.appendAscii( ">" ); 173 break; 174 175 default: 176 rBuffer.append( c ); 177 break; 178 } 179 } 180 } 181 182 bool createContentProviderData( 183 const rtl::OUString & rProvider, 184 const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess, 185 ContentProviderData & rInfo) 186 { 187 // Obtain service name. 188 rtl::OUStringBuffer aKeyBuffer (rProvider); 189 aKeyBuffer.appendAscii( "/ServiceName" ); 190 191 rtl::OUString aValue; 192 try 193 { 194 if ( !( rxHierNameAccess->getByHierarchicalName( 195 aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) 196 { 197 OSL_ENSURE( false, 198 "UniversalContentBroker::getContentProviderData - " 199 "Error getting item value!" ); 200 } 201 } 202 catch (container::NoSuchElementException &) 203 { 204 return false; 205 } 206 207 rInfo.ServiceName = aValue; 208 209 // Obtain URL Template. 210 aKeyBuffer.append(rProvider); 211 aKeyBuffer.appendAscii( "/URLTemplate" ); 212 213 if ( !( rxHierNameAccess->getByHierarchicalName( 214 aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) 215 { 216 OSL_ENSURE( false, 217 "UniversalContentBroker::getContentProviderData - " 218 "Error getting item value!" ); 219 } 220 221 rInfo.URLTemplate = aValue; 222 223 // Obtain Arguments. 224 aKeyBuffer.append(rProvider); 225 aKeyBuffer.appendAscii( "/Arguments" ); 226 227 if ( !( rxHierNameAccess->getByHierarchicalName( 228 aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) 229 { 230 OSL_ENSURE( false, 231 "UniversalContentBroker::getContentProviderData - " 232 "Error getting item value!" ); 233 } 234 235 rInfo.Arguments = aValue; 236 return true; 237 } 238 239 } 240 241 //========================================================================= 242 // 243 // UniversalContentBroker Implementation. 244 // 245 //========================================================================= 246 247 UniversalContentBroker::UniversalContentBroker( 248 const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr ) 249 : m_xSMgr( rXSMgr ), 250 m_pDisposeEventListeners( NULL ), 251 m_nInitCount( 0 ), //@@@ see initialize() method 252 m_nCommandId( 0 ) 253 { 254 OSL_ENSURE( m_xSMgr.is(), 255 "UniversalContentBroker ctor: No service manager" ); 256 } 257 258 //========================================================================= 259 // virtual 260 UniversalContentBroker::~UniversalContentBroker() 261 { 262 delete m_pDisposeEventListeners; 263 } 264 265 //========================================================================= 266 // 267 // XInterface methods. 268 // 269 //========================================================================= 270 271 XINTERFACE_IMPL_8( UniversalContentBroker, 272 XTypeProvider, 273 XComponent, 274 XServiceInfo, 275 XInitialization, 276 XContentProviderManager, 277 XContentProvider, 278 XContentIdentifierFactory, 279 XCommandProcessor ); 280 281 //========================================================================= 282 // 283 // XTypeProvider methods. 284 // 285 //========================================================================= 286 287 XTYPEPROVIDER_IMPL_8( UniversalContentBroker, 288 XTypeProvider, 289 XComponent, 290 XServiceInfo, 291 XInitialization, 292 XContentProviderManager, 293 XContentProvider, 294 XContentIdentifierFactory, 295 XCommandProcessor ); 296 297 //========================================================================= 298 // 299 // XComponent methods. 300 // 301 //========================================================================= 302 303 // virtual 304 void SAL_CALL UniversalContentBroker::dispose() 305 { 306 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) 307 { 308 EventObject aEvt; 309 aEvt.Source = SAL_STATIC_CAST( XComponent*, this ); 310 m_pDisposeEventListeners->disposeAndClear( aEvt ); 311 } 312 313 if ( m_xNotifier.is() ) 314 m_xNotifier->removeChangesListener( this ); 315 } 316 317 //========================================================================= 318 // virtual 319 void SAL_CALL UniversalContentBroker::addEventListener( 320 const Reference< XEventListener >& Listener ) 321 { 322 if ( !m_pDisposeEventListeners ) 323 m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex ); 324 325 m_pDisposeEventListeners->addInterface( Listener ); 326 } 327 328 //========================================================================= 329 // virtual 330 void SAL_CALL UniversalContentBroker::removeEventListener( 331 const Reference< XEventListener >& Listener ) 332 { 333 if ( m_pDisposeEventListeners ) 334 m_pDisposeEventListeners->removeInterface( Listener ); 335 336 // Note: Don't want to delete empty container here -> performance. 337 } 338 339 //========================================================================= 340 // 341 // XServiceInfo methods. 342 // 343 //========================================================================= 344 345 XSERVICEINFO_IMPL_1( UniversalContentBroker, 346 OUString::createFromAscii( 347 "com.sun.star.comp.ucb.UniversalContentBroker" ), 348 OUString::createFromAscii( 349 UCB_SERVICE_NAME ) ); 350 351 //========================================================================= 352 // 353 // Service factory implementation. 354 // 355 //========================================================================= 356 357 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker ); 358 359 //========================================================================= 360 // 361 // XInitialization methods. 362 // 363 //========================================================================= 364 365 // virtual 366 void SAL_CALL UniversalContentBroker::initialize( 367 const com::sun::star::uno::Sequence< Any >& aArguments ) 368 { 369 //@@@ At the moment, there's a problem when one (non-one-instance) factory 370 // 'wraps' another (one-instance) factory, causing this method to be 371 // called several times: 372 m_aArguments = aArguments; 373 374 oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount); 375 if (nCount == 1) 376 configureUcb(); 377 else 378 osl_decrementInterlockedCount(&m_nInitCount); 379 // make the possibility of overflow less likely... 380 } 381 382 //========================================================================= 383 // 384 // XContentProviderManager methods. 385 // 386 //========================================================================= 387 388 // virtual 389 Reference< XContentProvider > SAL_CALL 390 UniversalContentBroker::registerContentProvider( 391 const Reference< XContentProvider >& Provider, 392 const OUString& Scheme, 393 sal_Bool ReplaceExisting ) 394 { 395 osl::MutexGuard aGuard(m_aMutex); 396 397 ProviderMap_Impl::iterator aIt; 398 try 399 { 400 aIt = m_aProviders.find(Scheme); 401 } 402 catch (IllegalArgumentException const &) 403 { 404 return 0; //@@@ 405 } 406 407 Reference< XContentProvider > xPrevious; 408 if (aIt == m_aProviders.end()) 409 { 410 ProviderList_Impl aList; 411 aList.push_front(Provider); 412 try 413 { 414 m_aProviders.add(Scheme, aList, false); 415 } 416 catch (IllegalArgumentException const &) 417 { 418 return 0; //@@@ 419 } 420 } 421 else 422 { 423 if (!ReplaceExisting) 424 throw DuplicateProviderException(); 425 426 ProviderList_Impl & rList = aIt->getValue(); 427 xPrevious = rList.front().getProvider(); 428 rList.push_front(Provider); 429 } 430 431 return xPrevious; 432 } 433 434 //========================================================================= 435 // virtual 436 void SAL_CALL UniversalContentBroker::deregisterContentProvider( 437 const Reference< XContentProvider >& Provider, 438 const OUString& Scheme ) 439 { 440 osl::MutexGuard aGuard(m_aMutex); 441 442 ProviderMap_Impl::iterator aMapIt; 443 try 444 { 445 aMapIt = m_aProviders.find(Scheme); 446 } 447 catch (IllegalArgumentException const &) 448 { 449 return; //@@@ 450 } 451 452 if (aMapIt != m_aProviders.end()) 453 { 454 ProviderList_Impl & rList = aMapIt->getValue(); 455 456 ProviderList_Impl::iterator aListEnd(rList.end()); 457 for (ProviderList_Impl::iterator aListIt(rList.begin()); 458 aListIt != aListEnd; ++aListIt) 459 { 460 if ((*aListIt).getProvider() == Provider) 461 { 462 rList.erase(aListIt); 463 break; 464 } 465 } 466 467 if (rList.empty()) 468 m_aProviders.erase(aMapIt); 469 } 470 } 471 472 //========================================================================= 473 // virtual 474 com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL 475 UniversalContentBroker::queryContentProviders() 476 { 477 // Return a list with information about active(!) content providers. 478 479 osl::MutexGuard aGuard(m_aMutex); 480 481 com::sun::star::uno::Sequence< ContentProviderInfo > aSeq( 482 m_aProviders.size() ); 483 ContentProviderInfo* pInfo = aSeq.getArray(); 484 485 ProviderMap_Impl::const_iterator end = m_aProviders.end(); 486 for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end; 487 ++it) 488 { 489 // Note: Active provider is always the first list element. 490 pInfo->ContentProvider = it->getValue().front().getProvider(); 491 pInfo->Scheme = it->getRegexp(); 492 ++pInfo; 493 } 494 495 return aSeq; 496 } 497 498 //========================================================================= 499 // virtual 500 Reference< XContentProvider > SAL_CALL 501 UniversalContentBroker::queryContentProvider( const OUString& 502 Identifier ) 503 { 504 return queryContentProvider( Identifier, sal_False ); 505 } 506 507 //========================================================================= 508 // 509 // XContentProvider methods. 510 // 511 //========================================================================= 512 513 // virtual 514 Reference< XContent > SAL_CALL UniversalContentBroker::queryContent( 515 const Reference< XContentIdentifier >& Identifier ) 516 { 517 ////////////////////////////////////////////////////////////////////// 518 // Let the content provider for the scheme given with the content 519 // identifier create the XContent instance. 520 ////////////////////////////////////////////////////////////////////// 521 522 if ( !Identifier.is() ) 523 return Reference< XContent >(); 524 525 Reference< XContentProvider > xProv = 526 queryContentProvider( Identifier->getContentIdentifier(), sal_True ); 527 if ( xProv.is() ) 528 return xProv->queryContent( Identifier ); 529 530 return Reference< XContent >(); 531 } 532 533 //========================================================================= 534 // virtual 535 sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds( 536 const Reference< XContentIdentifier >& Id1, 537 const Reference< XContentIdentifier >& Id2 ) 538 { 539 OUString aURI1( Id1->getContentIdentifier() ); 540 OUString aURI2( Id2->getContentIdentifier() ); 541 542 Reference< XContentProvider > xProv1 543 = queryContentProvider( aURI1, sal_True ); 544 Reference< XContentProvider > xProv2 545 = queryContentProvider( aURI2, sal_True ); 546 547 // When both identifiers belong to the same provider, let that provider 548 // compare them; otherwise, simply compare the URI strings (which must 549 // be different): 550 if ( xProv1.is() && ( xProv1 == xProv2 ) ) 551 return xProv1->compareContentIds( Id1, Id2 ); 552 else 553 return aURI1.compareTo( aURI2 ); 554 } 555 556 //========================================================================= 557 // 558 // XContentIdentifierFactory methods. 559 // 560 //========================================================================= 561 562 // virtual 563 Reference< XContentIdentifier > SAL_CALL 564 UniversalContentBroker::createContentIdentifier( 565 const OUString& ContentId ) 566 { 567 ////////////////////////////////////////////////////////////////////// 568 // Let the content provider for the scheme given with content 569 // identifier create the XContentIdentifier instance, if he supports 570 // the XContentIdentifierFactory interface. Otherwise create standard 571 // implementation object for XContentIdentifier. 572 ////////////////////////////////////////////////////////////////////// 573 574 Reference< XContentIdentifier > xIdentifier; 575 576 Reference< XContentProvider > xProv 577 = queryContentProvider( ContentId, sal_True ); 578 if ( xProv.is() ) 579 { 580 Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY ); 581 if ( xFac.is() ) 582 xIdentifier = xFac->createContentIdentifier( ContentId ); 583 } 584 585 if ( !xIdentifier.is() ) 586 xIdentifier = new ContentIdentifier( m_xSMgr, ContentId ); 587 588 return xIdentifier; 589 } 590 591 //========================================================================= 592 // 593 // XCommandProcessor methods. 594 // 595 //========================================================================= 596 597 // virtual 598 sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier() 599 { 600 osl::MutexGuard aGuard( m_aMutex ); 601 602 // Just increase counter on every call to generate an identifier. 603 return ++m_nCommandId; 604 } 605 606 //========================================================================= 607 // virtual 608 Any SAL_CALL UniversalContentBroker::execute( 609 const Command& aCommand, 610 sal_Int32, 611 const Reference< XCommandEnvironment >& Environment ) 612 { 613 Any aRet; 614 615 ////////////////////////////////////////////////////////////////////// 616 // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo 617 // ctor in ucbcmds.cxx when adding new commands! 618 ////////////////////////////////////////////////////////////////////// 619 620 if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) || 621 aCommand.Name.equalsAsciiL( 622 RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME ) ) ) 623 { 624 ////////////////////////////////////////////////////////////////// 625 // getCommandInfo 626 ////////////////////////////////////////////////////////////////// 627 628 aRet <<= getCommandInfo(); 629 } 630 else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || 631 aCommand.Name.equalsAsciiL( 632 RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) ) 633 { 634 ////////////////////////////////////////////////////////////////// 635 // globalTransfer 636 ////////////////////////////////////////////////////////////////// 637 638 GlobalTransferCommandArgument aTransferArg; 639 if ( !( aCommand.Argument >>= aTransferArg ) ) 640 { 641 ucbhelper::cancelCommandExecution( 642 makeAny( IllegalArgumentException( 643 rtl::OUString::createFromAscii( 644 "Wrong argument type!" ), 645 static_cast< cppu::OWeakObject * >( this ), 646 -1 ) ), 647 Environment ); 648 // Unreachable 649 } 650 651 globalTransfer( aTransferArg, Environment ); 652 } 653 else 654 { 655 ////////////////////////////////////////////////////////////////// 656 // Unknown command 657 ////////////////////////////////////////////////////////////////// 658 659 ucbhelper::cancelCommandExecution( 660 makeAny( UnsupportedCommandException( 661 rtl::OUString(), 662 static_cast< cppu::OWeakObject * >( this ) ) ), 663 Environment ); 664 // Unreachable 665 } 666 667 return aRet; 668 } 669 670 //========================================================================= 671 // virtual 672 void SAL_CALL UniversalContentBroker::abort( sal_Int32 ) 673 { 674 // @@@ Not implemented ( yet). 675 } 676 677 //========================================================================= 678 // 679 // XChangesListener methods 680 // 681 //========================================================================= 682 // virtual 683 void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event ) 684 { 685 sal_Int32 nCount = Event.Changes.getLength(); 686 if ( nCount ) 687 { 688 uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess; 689 Event.Base >>= xHierNameAccess; 690 691 OSL_ASSERT( xHierNameAccess.is() ); 692 693 const util::ElementChange* pElementChanges 694 = Event.Changes.getConstArray(); 695 696 ContentProviderDataList aData; 697 for ( sal_Int32 n = 0; n < nCount; ++n ) 698 { 699 const util::ElementChange& rElem = pElementChanges[ n ]; 700 rtl::OUString aKey; 701 rElem.Accessor >>= aKey; 702 703 ContentProviderData aInfo; 704 705 // Removal of UCPs from the configuration leads to changesOccurred 706 // notifications, too, but it is hard to tell for a given 707 // ElementChange whether it is an addition or a removal, so as a 708 // heuristic consider as removals those that cause a 709 // NoSuchElementException in createContentProviderData. 710 // 711 // For now, removal of UCPs from the configuration is simply ignored 712 // (and not reflected in the UCB's data structures): 713 if (createContentProviderData(aKey, xHierNameAccess, aInfo)) 714 { 715 aData.push_back(aInfo); 716 } 717 } 718 719 prepareAndRegister(aData); 720 } 721 } 722 723 //========================================================================= 724 // 725 // XEventListener methods 726 // 727 //========================================================================= 728 // virtual 729 void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&) 730 { 731 if ( m_xNotifier.is() ) 732 { 733 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 734 735 if ( m_xNotifier.is() ) 736 m_xNotifier.clear(); 737 } 738 } 739 740 //========================================================================= 741 // 742 // Non-interface methods 743 // 744 //========================================================================= 745 746 Reference< XContentProvider > UniversalContentBroker::queryContentProvider( 747 const OUString& Identifier, 748 sal_Bool bResolved ) 749 { 750 osl::MutexGuard aGuard( m_aMutex ); 751 752 ProviderList_Impl const * pList = m_aProviders.map( Identifier ); 753 return pList ? bResolved ? pList->front().getResolvedProvider() 754 : pList->front().getProvider() 755 : Reference< XContentProvider >(); 756 } 757 758 bool UniversalContentBroker::configureUcb() 759 { 760 rtl::OUString aKey1; 761 rtl::OUString aKey2; 762 if (m_aArguments.getLength() < 2 763 || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2)) 764 { 765 OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): Bad arguments"); 766 return false; 767 } 768 769 ContentProviderDataList aData; 770 if (!getContentProviderData(aKey1, aKey2, aData)) 771 { 772 OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): No configuration"); 773 return false; 774 } 775 776 prepareAndRegister(aData); 777 778 return true; 779 } 780 781 void UniversalContentBroker::prepareAndRegister( 782 const ContentProviderDataList& rData) 783 { 784 ContentProviderDataList::const_iterator aEnd(rData.end()); 785 for (ContentProviderDataList::const_iterator aIt(rData.begin()); 786 aIt != aEnd; ++aIt) 787 { 788 rtl::OUString aProviderArguments; 789 if (fillPlaceholders(aIt->Arguments, 790 m_aArguments, 791 &aProviderArguments)) 792 { 793 registerAtUcb(this, 794 m_xSMgr, 795 aIt->ServiceName, 796 aProviderArguments, 797 aIt->URLTemplate, 798 0); 799 800 } 801 else 802 OSL_ENSURE(false, 803 "UniversalContentBroker::prepareAndRegister(): Bad argument placeholders"); 804 } 805 } 806 807 //========================================================================= 808 bool UniversalContentBroker::getContentProviderData( 809 const rtl::OUString & rKey1, 810 const rtl::OUString & rKey2, 811 ContentProviderDataList & rListToFill ) 812 { 813 if ( !m_xSMgr.is() || !rKey1.getLength() || !rKey2.getLength() ) 814 { 815 OSL_ENSURE( false, 816 "UniversalContentBroker::getContentProviderData - Invalid argument!" ); 817 return false; 818 } 819 820 try 821 { 822 uno::Reference< lang::XMultiServiceFactory > xConfigProv( 823 m_xSMgr->createInstance( 824 rtl::OUString::createFromAscii( 825 "com.sun.star.configuration.ConfigurationProvider" ) ), 826 uno::UNO_QUERY_THROW ); 827 828 rtl::OUStringBuffer aFullPath; 829 aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" ); 830 makeAndAppendXMLName( aFullPath, rKey1 ); 831 aFullPath.appendAscii( "']/SecondaryKeys/['" ); 832 makeAndAppendXMLName( aFullPath, rKey2 ); 833 aFullPath.appendAscii( "']/ProviderData" ); 834 835 uno::Sequence< uno::Any > aArguments( 1 ); 836 beans::PropertyValue aProperty; 837 aProperty.Name 838 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 839 aProperty.Value <<= aFullPath.makeStringAndClear(); 840 aArguments[ 0 ] <<= aProperty; 841 842 uno::Reference< uno::XInterface > xInterface( 843 xConfigProv->createInstanceWithArguments( 844 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 845 "com.sun.star.configuration.ConfigurationAccess" ) ), 846 aArguments ) ); 847 848 if ( !m_xNotifier.is() ) 849 { 850 m_xNotifier = uno::Reference< util::XChangesNotifier >( 851 xInterface, uno::UNO_QUERY_THROW ); 852 853 m_xNotifier->addChangesListener( this ); 854 } 855 856 uno::Reference< container::XNameAccess > xNameAccess( 857 xInterface, uno::UNO_QUERY_THROW ); 858 859 uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); 860 const rtl::OUString* pElems = aElems.getConstArray(); 861 sal_Int32 nCount = aElems.getLength(); 862 863 if ( nCount > 0 ) 864 { 865 uno::Reference< container::XHierarchicalNameAccess > 866 xHierNameAccess( xInterface, uno::UNO_QUERY_THROW ); 867 868 // Iterate over children. 869 for ( sal_Int32 n = 0; n < nCount; ++n ) 870 { 871 872 try 873 { 874 875 ContentProviderData aInfo; 876 877 rtl::OUStringBuffer aElemBuffer; 878 aElemBuffer.appendAscii( "['" ); 879 makeAndAppendXMLName( aElemBuffer, pElems[ n ] ); 880 aElemBuffer.appendAscii( "']" ); 881 882 OSL_VERIFY( 883 createContentProviderData( 884 aElemBuffer.makeStringAndClear(), xHierNameAccess, 885 aInfo)); 886 887 rListToFill.push_back( aInfo ); 888 } 889 catch ( container::NoSuchElementException& ) 890 { 891 // getByHierarchicalName 892 OSL_ENSURE( false, 893 "UniversalContentBroker::getContentProviderData - " 894 "caught NoSuchElementException!" ); 895 } 896 } 897 } 898 } 899 catch ( uno::RuntimeException& ) 900 { 901 OSL_ENSURE( false, 902 "UniversalContentBroker::getContentProviderData - caught RuntimeException!" ); 903 return false; 904 } 905 catch ( uno::Exception& ) 906 { 907 // createInstance, createInstanceWithArguments 908 909 OSL_ENSURE( false, 910 "UniversalContentBroker::getContentProviderData - caught Exception!" ); 911 return false; 912 } 913 914 return true; 915 } 916 917 //========================================================================= 918 // 919 // ProviderListEntry_Impl implementation. 920 // 921 //========================================================================= 922 923 Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const 924 { 925 if ( !m_xResolvedProvider.is() ) 926 { 927 Reference< XContentProviderSupplier > xSupplier( 928 m_xProvider, UNO_QUERY ); 929 if ( xSupplier.is() ) 930 m_xResolvedProvider = xSupplier->getContentProvider(); 931 932 if ( !m_xResolvedProvider.is() ) 933 m_xResolvedProvider = m_xProvider; 934 } 935 936 return m_xResolvedProvider; 937 } 938