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