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