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 throw( com::sun::star::uno::RuntimeException ) 306 { 307 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) 308 { 309 EventObject aEvt; 310 aEvt.Source = SAL_STATIC_CAST( XComponent*, this ); 311 m_pDisposeEventListeners->disposeAndClear( aEvt ); 312 } 313 314 if ( m_xNotifier.is() ) 315 m_xNotifier->removeChangesListener( this ); 316 } 317 318 //========================================================================= 319 // virtual 320 void SAL_CALL UniversalContentBroker::addEventListener( 321 const Reference< XEventListener >& Listener ) 322 throw( com::sun::star::uno::RuntimeException ) 323 { 324 if ( !m_pDisposeEventListeners ) 325 m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex ); 326 327 m_pDisposeEventListeners->addInterface( Listener ); 328 } 329 330 //========================================================================= 331 // virtual 332 void SAL_CALL UniversalContentBroker::removeEventListener( 333 const Reference< XEventListener >& Listener ) 334 throw( com::sun::star::uno::RuntimeException ) 335 { 336 if ( m_pDisposeEventListeners ) 337 m_pDisposeEventListeners->removeInterface( Listener ); 338 339 // Note: Don't want to delete empty container here -> performance. 340 } 341 342 //========================================================================= 343 // 344 // XServiceInfo methods. 345 // 346 //========================================================================= 347 348 XSERVICEINFO_IMPL_1( UniversalContentBroker, 349 OUString::createFromAscii( 350 "com.sun.star.comp.ucb.UniversalContentBroker" ), 351 OUString::createFromAscii( 352 UCB_SERVICE_NAME ) ); 353 354 //========================================================================= 355 // 356 // Service factory implementation. 357 // 358 //========================================================================= 359 360 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker ); 361 362 //========================================================================= 363 // 364 // XInitialization methods. 365 // 366 //========================================================================= 367 368 // virtual 369 void SAL_CALL UniversalContentBroker::initialize( 370 const com::sun::star::uno::Sequence< Any >& aArguments ) 371 throw( com::sun::star::uno::Exception, 372 com::sun::star::uno::RuntimeException ) 373 { 374 //@@@ At the moment, there's a problem when one (non-one-instance) factory 375 // 'wraps' another (one-instance) factory, causing this method to be 376 // called several times: 377 m_aArguments = aArguments; 378 379 oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount); 380 if (nCount == 1) 381 configureUcb(); 382 else 383 osl_decrementInterlockedCount(&m_nInitCount); 384 // make the possibility of overflow less likely... 385 } 386 387 //========================================================================= 388 // 389 // XContentProviderManager methods. 390 // 391 //========================================================================= 392 393 // virtual 394 Reference< XContentProvider > SAL_CALL 395 UniversalContentBroker::registerContentProvider( 396 const Reference< XContentProvider >& Provider, 397 const OUString& Scheme, 398 sal_Bool ReplaceExisting ) 399 throw( DuplicateProviderException, com::sun::star::uno::RuntimeException ) 400 { 401 osl::MutexGuard aGuard(m_aMutex); 402 403 ProviderMap_Impl::iterator aIt; 404 try 405 { 406 aIt = m_aProviders.find(Scheme); 407 } 408 catch (IllegalArgumentException const &) 409 { 410 return 0; //@@@ 411 } 412 413 Reference< XContentProvider > xPrevious; 414 if (aIt == m_aProviders.end()) 415 { 416 ProviderList_Impl aList; 417 aList.push_front(Provider); 418 try 419 { 420 m_aProviders.add(Scheme, aList, false); 421 } 422 catch (IllegalArgumentException const &) 423 { 424 return 0; //@@@ 425 } 426 } 427 else 428 { 429 if (!ReplaceExisting) 430 throw DuplicateProviderException(); 431 432 ProviderList_Impl & rList = aIt->getValue(); 433 xPrevious = rList.front().getProvider(); 434 rList.push_front(Provider); 435 } 436 437 return xPrevious; 438 } 439 440 //========================================================================= 441 // virtual 442 void SAL_CALL UniversalContentBroker::deregisterContentProvider( 443 const Reference< XContentProvider >& Provider, 444 const OUString& Scheme ) 445 throw( com::sun::star::uno::RuntimeException ) 446 { 447 osl::MutexGuard aGuard(m_aMutex); 448 449 ProviderMap_Impl::iterator aMapIt; 450 try 451 { 452 aMapIt = m_aProviders.find(Scheme); 453 } 454 catch (IllegalArgumentException const &) 455 { 456 return; //@@@ 457 } 458 459 if (aMapIt != m_aProviders.end()) 460 { 461 ProviderList_Impl & rList = aMapIt->getValue(); 462 463 ProviderList_Impl::iterator aListEnd(rList.end()); 464 for (ProviderList_Impl::iterator aListIt(rList.begin()); 465 aListIt != aListEnd; ++aListIt) 466 { 467 if ((*aListIt).getProvider() == Provider) 468 { 469 rList.erase(aListIt); 470 break; 471 } 472 } 473 474 if (rList.empty()) 475 m_aProviders.erase(aMapIt); 476 } 477 } 478 479 //========================================================================= 480 // virtual 481 com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL 482 UniversalContentBroker::queryContentProviders() 483 throw( com::sun::star::uno::RuntimeException ) 484 { 485 // Return a list with information about active(!) content providers. 486 487 osl::MutexGuard aGuard(m_aMutex); 488 489 com::sun::star::uno::Sequence< ContentProviderInfo > aSeq( 490 m_aProviders.size() ); 491 ContentProviderInfo* pInfo = aSeq.getArray(); 492 493 ProviderMap_Impl::const_iterator end = m_aProviders.end(); 494 for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end; 495 ++it) 496 { 497 // Note: Active provider is always the first list element. 498 pInfo->ContentProvider = it->getValue().front().getProvider(); 499 pInfo->Scheme = it->getRegexp(); 500 ++pInfo; 501 } 502 503 return aSeq; 504 } 505 506 //========================================================================= 507 // virtual 508 Reference< XContentProvider > SAL_CALL 509 UniversalContentBroker::queryContentProvider( const OUString& 510 Identifier ) 511 throw( com::sun::star::uno::RuntimeException ) 512 { 513 return queryContentProvider( Identifier, sal_False ); 514 } 515 516 //========================================================================= 517 // 518 // XContentProvider methods. 519 // 520 //========================================================================= 521 522 // virtual 523 Reference< XContent > SAL_CALL UniversalContentBroker::queryContent( 524 const Reference< XContentIdentifier >& Identifier ) 525 throw( IllegalIdentifierException, com::sun::star::uno::RuntimeException ) 526 { 527 ////////////////////////////////////////////////////////////////////// 528 // Let the content provider for the scheme given with the content 529 // identifier create the XContent instance. 530 ////////////////////////////////////////////////////////////////////// 531 532 if ( !Identifier.is() ) 533 return Reference< XContent >(); 534 535 Reference< XContentProvider > xProv = 536 queryContentProvider( Identifier->getContentIdentifier(), sal_True ); 537 if ( xProv.is() ) 538 return xProv->queryContent( Identifier ); 539 540 return Reference< XContent >(); 541 } 542 543 //========================================================================= 544 // virtual 545 sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds( 546 const Reference< XContentIdentifier >& Id1, 547 const Reference< XContentIdentifier >& Id2 ) 548 throw( com::sun::star::uno::RuntimeException ) 549 { 550 OUString aURI1( Id1->getContentIdentifier() ); 551 OUString aURI2( Id2->getContentIdentifier() ); 552 553 Reference< XContentProvider > xProv1 554 = queryContentProvider( aURI1, sal_True ); 555 Reference< XContentProvider > xProv2 556 = queryContentProvider( aURI2, sal_True ); 557 558 // When both identifiers belong to the same provider, let that provider 559 // compare them; otherwise, simply compare the URI strings (which must 560 // be different): 561 if ( xProv1.is() && ( xProv1 == xProv2 ) ) 562 return xProv1->compareContentIds( Id1, Id2 ); 563 else 564 return aURI1.compareTo( aURI2 ); 565 } 566 567 //========================================================================= 568 // 569 // XContentIdentifierFactory methods. 570 // 571 //========================================================================= 572 573 // virtual 574 Reference< XContentIdentifier > SAL_CALL 575 UniversalContentBroker::createContentIdentifier( 576 const OUString& ContentId ) 577 throw( com::sun::star::uno::RuntimeException ) 578 { 579 ////////////////////////////////////////////////////////////////////// 580 // Let the content provider for the scheme given with content 581 // identifier create the XContentIdentifier instance, if he supports 582 // the XContentIdentifierFactory interface. Otherwise create standard 583 // implementation object for XContentIdentifier. 584 ////////////////////////////////////////////////////////////////////// 585 586 Reference< XContentIdentifier > xIdentifier; 587 588 Reference< XContentProvider > xProv 589 = queryContentProvider( ContentId, sal_True ); 590 if ( xProv.is() ) 591 { 592 Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY ); 593 if ( xFac.is() ) 594 xIdentifier = xFac->createContentIdentifier( ContentId ); 595 } 596 597 if ( !xIdentifier.is() ) 598 xIdentifier = new ContentIdentifier( m_xSMgr, ContentId ); 599 600 return xIdentifier; 601 } 602 603 //========================================================================= 604 // 605 // XCommandProcessor methods. 606 // 607 //========================================================================= 608 609 // virtual 610 sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier() 611 throw( RuntimeException ) 612 { 613 osl::MutexGuard aGuard( m_aMutex ); 614 615 // Just increase counter on every call to generate an identifier. 616 return ++m_nCommandId; 617 } 618 619 //========================================================================= 620 // virtual 621 Any SAL_CALL UniversalContentBroker::execute( 622 const Command& aCommand, 623 sal_Int32, 624 const Reference< XCommandEnvironment >& Environment ) 625 throw( Exception, CommandAbortedException, RuntimeException ) 626 { 627 Any aRet; 628 629 ////////////////////////////////////////////////////////////////////// 630 // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo 631 // ctor in ucbcmds.cxx when adding new commands! 632 ////////////////////////////////////////////////////////////////////// 633 634 if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) || 635 aCommand.Name.equalsAsciiL( 636 RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME ) ) ) 637 { 638 ////////////////////////////////////////////////////////////////// 639 // getCommandInfo 640 ////////////////////////////////////////////////////////////////// 641 642 aRet <<= getCommandInfo(); 643 } 644 else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || 645 aCommand.Name.equalsAsciiL( 646 RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) ) 647 { 648 ////////////////////////////////////////////////////////////////// 649 // globalTransfer 650 ////////////////////////////////////////////////////////////////// 651 652 GlobalTransferCommandArgument aTransferArg; 653 if ( !( aCommand.Argument >>= aTransferArg ) ) 654 { 655 ucbhelper::cancelCommandExecution( 656 makeAny( IllegalArgumentException( 657 rtl::OUString::createFromAscii( 658 "Wrong argument type!" ), 659 static_cast< cppu::OWeakObject * >( this ), 660 -1 ) ), 661 Environment ); 662 // Unreachable 663 } 664 665 globalTransfer( aTransferArg, Environment ); 666 } 667 else 668 { 669 ////////////////////////////////////////////////////////////////// 670 // Unknown command 671 ////////////////////////////////////////////////////////////////// 672 673 ucbhelper::cancelCommandExecution( 674 makeAny( UnsupportedCommandException( 675 rtl::OUString(), 676 static_cast< cppu::OWeakObject * >( this ) ) ), 677 Environment ); 678 // Unreachable 679 } 680 681 return aRet; 682 } 683 684 //========================================================================= 685 // virtual 686 void SAL_CALL UniversalContentBroker::abort( sal_Int32 ) 687 throw( RuntimeException ) 688 { 689 // @@@ Not implemeted ( yet). 690 } 691 692 //========================================================================= 693 // 694 // XChangesListener methods 695 // 696 //========================================================================= 697 // virtual 698 void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event ) 699 throw( uno::RuntimeException ) 700 { 701 sal_Int32 nCount = Event.Changes.getLength(); 702 if ( nCount ) 703 { 704 uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess; 705 Event.Base >>= xHierNameAccess; 706 707 OSL_ASSERT( xHierNameAccess.is() ); 708 709 const util::ElementChange* pElementChanges 710 = Event.Changes.getConstArray(); 711 712 ContentProviderDataList aData; 713 for ( sal_Int32 n = 0; n < nCount; ++n ) 714 { 715 const util::ElementChange& rElem = pElementChanges[ n ]; 716 rtl::OUString aKey; 717 rElem.Accessor >>= aKey; 718 719 ContentProviderData aInfo; 720 721 // Removal of UCPs from the configuration leads to changesOccurred 722 // notifications, too, but it is hard to tell for a given 723 // ElementChange whether it is an addition or a removal, so as a 724 // heuristic consider as removals those that cause a 725 // NoSuchElementException in createContentProviderData. 726 // 727 // For now, removal of UCPs from the configuration is simply ignored 728 // (and not reflected in the UCB's data structures): 729 if (createContentProviderData(aKey, xHierNameAccess, aInfo)) 730 { 731 aData.push_back(aInfo); 732 } 733 } 734 735 prepareAndRegister(aData); 736 } 737 } 738 739 //========================================================================= 740 // 741 // XEventListener methods 742 // 743 //========================================================================= 744 // virtual 745 void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&) 746 throw( uno::RuntimeException ) 747 { 748 if ( m_xNotifier.is() ) 749 { 750 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 751 752 if ( m_xNotifier.is() ) 753 m_xNotifier.clear(); 754 } 755 } 756 757 //========================================================================= 758 // 759 // Non-interface methods 760 // 761 //========================================================================= 762 763 Reference< XContentProvider > UniversalContentBroker::queryContentProvider( 764 const OUString& Identifier, 765 sal_Bool bResolved ) 766 { 767 osl::MutexGuard aGuard( m_aMutex ); 768 769 ProviderList_Impl const * pList = m_aProviders.map( Identifier ); 770 return pList ? bResolved ? pList->front().getResolvedProvider() 771 : pList->front().getProvider() 772 : Reference< XContentProvider >(); 773 } 774 775 bool UniversalContentBroker::configureUcb() 776 throw (uno::RuntimeException) 777 { 778 rtl::OUString aKey1; 779 rtl::OUString aKey2; 780 if (m_aArguments.getLength() < 2 781 || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2)) 782 { 783 OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): Bad arguments"); 784 return false; 785 } 786 787 ContentProviderDataList aData; 788 if (!getContentProviderData(aKey1, aKey2, aData)) 789 { 790 OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): No configuration"); 791 return false; 792 } 793 794 prepareAndRegister(aData); 795 796 return true; 797 } 798 799 void UniversalContentBroker::prepareAndRegister( 800 const ContentProviderDataList& rData) 801 { 802 ContentProviderDataList::const_iterator aEnd(rData.end()); 803 for (ContentProviderDataList::const_iterator aIt(rData.begin()); 804 aIt != aEnd; ++aIt) 805 { 806 rtl::OUString aProviderArguments; 807 if (fillPlaceholders(aIt->Arguments, 808 m_aArguments, 809 &aProviderArguments)) 810 { 811 registerAtUcb(this, 812 m_xSMgr, 813 aIt->ServiceName, 814 aProviderArguments, 815 aIt->URLTemplate, 816 0); 817 818 } 819 else 820 OSL_ENSURE(false, 821 "UniversalContentBroker::prepareAndRegister(): Bad argument placeholders"); 822 } 823 } 824 825 //========================================================================= 826 bool UniversalContentBroker::getContentProviderData( 827 const rtl::OUString & rKey1, 828 const rtl::OUString & rKey2, 829 ContentProviderDataList & rListToFill ) 830 { 831 if ( !m_xSMgr.is() || !rKey1.getLength() || !rKey2.getLength() ) 832 { 833 OSL_ENSURE( false, 834 "UniversalContentBroker::getContentProviderData - Invalid argument!" ); 835 return false; 836 } 837 838 try 839 { 840 uno::Reference< lang::XMultiServiceFactory > xConfigProv( 841 m_xSMgr->createInstance( 842 rtl::OUString::createFromAscii( 843 "com.sun.star.configuration.ConfigurationProvider" ) ), 844 uno::UNO_QUERY_THROW ); 845 846 rtl::OUStringBuffer aFullPath; 847 aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" ); 848 makeAndAppendXMLName( aFullPath, rKey1 ); 849 aFullPath.appendAscii( "']/SecondaryKeys/['" ); 850 makeAndAppendXMLName( aFullPath, rKey2 ); 851 aFullPath.appendAscii( "']/ProviderData" ); 852 853 uno::Sequence< uno::Any > aArguments( 1 ); 854 beans::PropertyValue aProperty; 855 aProperty.Name 856 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 857 aProperty.Value <<= aFullPath.makeStringAndClear(); 858 aArguments[ 0 ] <<= aProperty; 859 860 uno::Reference< uno::XInterface > xInterface( 861 xConfigProv->createInstanceWithArguments( 862 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 863 "com.sun.star.configuration.ConfigurationAccess" ) ), 864 aArguments ) ); 865 866 if ( !m_xNotifier.is() ) 867 { 868 m_xNotifier = uno::Reference< util::XChangesNotifier >( 869 xInterface, uno::UNO_QUERY_THROW ); 870 871 m_xNotifier->addChangesListener( this ); 872 } 873 874 uno::Reference< container::XNameAccess > xNameAccess( 875 xInterface, uno::UNO_QUERY_THROW ); 876 877 uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); 878 const rtl::OUString* pElems = aElems.getConstArray(); 879 sal_Int32 nCount = aElems.getLength(); 880 881 if ( nCount > 0 ) 882 { 883 uno::Reference< container::XHierarchicalNameAccess > 884 xHierNameAccess( xInterface, uno::UNO_QUERY_THROW ); 885 886 // Iterate over children. 887 for ( sal_Int32 n = 0; n < nCount; ++n ) 888 { 889 890 try 891 { 892 893 ContentProviderData aInfo; 894 895 rtl::OUStringBuffer aElemBuffer; 896 aElemBuffer.appendAscii( "['" ); 897 makeAndAppendXMLName( aElemBuffer, pElems[ n ] ); 898 aElemBuffer.appendAscii( "']" ); 899 900 OSL_VERIFY( 901 createContentProviderData( 902 aElemBuffer.makeStringAndClear(), xHierNameAccess, 903 aInfo)); 904 905 rListToFill.push_back( aInfo ); 906 } 907 catch ( container::NoSuchElementException& ) 908 { 909 // getByHierarchicalName 910 OSL_ENSURE( false, 911 "UniversalContentBroker::getContentProviderData - " 912 "caught NoSuchElementException!" ); 913 } 914 } 915 } 916 } 917 catch ( uno::RuntimeException& ) 918 { 919 OSL_ENSURE( false, 920 "UniversalContentBroker::getContentProviderData - caught RuntimeException!" ); 921 return false; 922 } 923 catch ( uno::Exception& ) 924 { 925 // createInstance, createInstanceWithArguments 926 927 OSL_ENSURE( false, 928 "UniversalContentBroker::getContentProviderData - caught Exception!" ); 929 return false; 930 } 931 932 return true; 933 } 934 935 //========================================================================= 936 // 937 // ProviderListEntry_Impl implementation. 938 // 939 //========================================================================= 940 941 Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const 942 { 943 if ( !m_xResolvedProvider.is() ) 944 { 945 Reference< XContentProviderSupplier > xSupplier( 946 m_xProvider, UNO_QUERY ); 947 if ( xSupplier.is() ) 948 m_xResolvedProvider = xSupplier->getContentProvider(); 949 950 if ( !m_xResolvedProvider.is() ) 951 m_xResolvedProvider = m_xProvider; 952 } 953 954 return m_xResolvedProvider; 955 } 956