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_extensions.hxx" 26 27 #include <cppuhelper/implbase1.hxx> 28 #include <cppuhelper/implbase3.hxx> 29 #include <cppuhelper/implementationentry.hxx> 30 #include <com/sun/star/beans/Property.hpp> 31 #include <com/sun/star/beans/XPropertySetInfo.hpp> 32 #include <com/sun/star/beans/PropertyValue.hpp> 33 #include <com/sun/star/container/XNameAccess.hpp> 34 #include <com/sun/star/deployment/UpdateInformationEntry.hpp> 35 #include <com/sun/star/deployment/UpdateInformationProvider.hpp> 36 #include <com/sun/star/io/XActiveDataSink.hpp> 37 #include <com/sun/star/io/XInputStream.hpp> 38 #include <com/sun/star/lang/XComponent.hpp> 39 #include <com/sun/star/lang/XServiceInfo.hpp> 40 #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp> 41 #include <com/sun/star/ucb/XCommandProcessor2.hpp> 42 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp> 43 #include <com/sun/star/ucb/XContentProvider.hpp> 44 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp" 45 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 46 #include <com/sun/star/ucb/OpenMode.hpp> 47 #include <com/sun/star/sdbc/XRow.hpp> 48 #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp> 49 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp> 50 #include <com/sun/star/xml/xpath/XXPathAPI.hpp> 51 52 #include <rtl/ref.hxx> 53 #include <rtl/memory.h> 54 #include <rtl/bootstrap.hxx> 55 #include <rtl/ustrbuf.hxx> 56 #include <osl/process.h> 57 #include <osl/conditn.hxx> 58 59 namespace beans = com::sun::star::beans ; 60 namespace container = com::sun::star::container ; 61 namespace deployment = com::sun::star::deployment ; 62 namespace io = com::sun::star::io ; 63 namespace lang = com::sun::star::lang ; 64 namespace task = com::sun::star::task ; 65 namespace ucb = com::sun::star::ucb ; 66 namespace uno = com::sun::star::uno ; 67 namespace xml = com::sun::star::xml ; 68 namespace sdbc = com::sun::star::sdbc ; 69 70 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 71 72 //------------------------------------------------------------------------------ 73 74 namespace 75 { 76 77 #ifdef DEBUG 78 79 class InputStreamWrapper : public ::cppu::WeakImplHelper1< io::XInputStream > 80 { 81 uno::Reference< io::XInputStream > m_xStream; 82 83 public: 84 InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) : 85 m_xStream(rxStream) {}; 86 87 virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 88 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 89 { 90 sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead); 91 if ( n ) 92 OSL_TRACE( "Read [%d] bytes: %s\n", n, aData.get()->elements ); 93 return n; 94 }; 95 virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 96 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 97 { 98 sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead); 99 if ( n ) 100 OSL_TRACE( "Read [%d] bytes: %s\n", n, aData.get()->elements ); 101 return n; 102 }; 103 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) 104 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) 105 { m_xStream->skipBytes(nBytesToSkip); }; 106 virtual sal_Int32 SAL_CALL available() 107 throw (io::NotConnectedException, io::IOException, uno::RuntimeException) 108 { return m_xStream->available(); }; 109 virtual void SAL_CALL closeInput( ) 110 throw (io::NotConnectedException, io::IOException, uno::RuntimeException) 111 {}; 112 }; 113 114 #define INPUT_STREAM(i) new InputStreamWrapper(i) 115 #else 116 #define INPUT_STREAM(i) i 117 #endif 118 119 //------------------------------------------------------------------------------ 120 121 class ActiveDataSink : public ::cppu::WeakImplHelper1< io::XActiveDataSink > 122 { 123 uno::Reference< io::XInputStream > m_xStream; 124 125 public: 126 ActiveDataSink() {}; 127 128 inline operator uno::Reference< io::XActiveDataSink > () { return this; }; 129 130 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream() 131 throw (uno::RuntimeException) { return m_xStream; }; 132 virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream ) 133 throw (uno::RuntimeException) { m_xStream = rStream; }; 134 }; 135 136 //------------------------------------------------------------------------------ 137 138 class UpdateInformationProvider : 139 public ::cppu::WeakImplHelper3< deployment::XUpdateInformationProvider, 140 ucb::XWebDAVCommandEnvironment, 141 lang::XServiceInfo > 142 { 143 public: 144 static uno::Reference< uno::XInterface > createInstance(const uno::Reference<uno::XComponentContext>& xContext); 145 146 static uno::Sequence< rtl::OUString > getServiceNames(); 147 static rtl::OUString getImplName(); 148 149 uno::Reference< xml::dom::XElement > getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode); 150 uno::Reference< xml::dom::XNode > getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, const rtl::OUString& rName); 151 152 153 // XUpdateInformationService 154 virtual uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL 155 getUpdateInformation( 156 uno::Sequence< rtl::OUString > const & repositories, 157 rtl::OUString const & extensionId 158 ) throw (uno::Exception, uno::RuntimeException); 159 160 virtual void SAL_CALL cancel() 161 throw (uno::RuntimeException); 162 163 virtual void SAL_CALL setInteractionHandler( 164 uno::Reference< task::XInteractionHandler > const & handler ) 165 throw (uno::RuntimeException); 166 167 virtual uno::Reference< container::XEnumeration > SAL_CALL 168 getUpdateInformationEnumeration( 169 uno::Sequence< rtl::OUString > const & repositories, 170 rtl::OUString const & extensionId 171 ) throw (uno::Exception, uno::RuntimeException); 172 173 // XCommandEnvironment 174 virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() 175 throw ( uno::RuntimeException ); 176 177 virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler() 178 throw ( uno::RuntimeException ) { return uno::Reference< ucb::XProgressHandler >(); }; 179 180 // XWebDAVCommandEnvironment 181 virtual uno::Sequence< beans::StringPair > SAL_CALL getUserRequestHeaders( 182 const rtl::OUString&, const rtl::OUString& ) 183 throw ( uno::RuntimeException ) { return m_aRequestHeaderList; }; 184 185 // XServiceInfo 186 virtual rtl::OUString SAL_CALL getImplementationName() 187 throw (uno::RuntimeException); 188 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName) 189 throw (uno::RuntimeException); 190 virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() 191 throw (uno::RuntimeException); 192 193 protected: 194 195 virtual ~UpdateInformationProvider(); 196 static rtl::OUString getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item); 197 198 private: 199 uno::Reference< io::XInputStream > load(const rtl::OUString& rURL); 200 201 void storeCommandInfo( sal_Int32 nCommandId, 202 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor); 203 204 UpdateInformationProvider(const uno::Reference<uno::XComponentContext>& xContext, 205 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory, 206 const uno::Reference< ucb::XContentProvider >& xContentProvider, 207 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder, 208 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI); 209 210 const uno::Reference< uno::XComponentContext> m_xContext; 211 212 const uno::Reference< ucb::XContentIdentifierFactory > m_xContentIdFactory; 213 const uno::Reference< ucb::XContentProvider > m_xContentProvider; 214 const uno::Reference< xml::dom::XDocumentBuilder > m_xDocumentBuilder; 215 const uno::Reference< xml::xpath::XXPathAPI > m_xXPathAPI; 216 217 uno::Sequence< beans::StringPair > m_aRequestHeaderList; 218 219 uno::Reference< ucb::XCommandProcessor > m_xCommandProcessor; 220 uno::Reference< task::XInteractionHandler > m_xInteractionHandler; 221 uno::Reference< task::XInteractionHandler > m_xPwContainerInteractionHandler; 222 223 osl::Mutex m_aMutex; 224 osl::Condition m_bCancelled; 225 226 sal_Int32 m_nCommandId; 227 }; 228 229 //------------------------------------------------------------------------------ 230 231 class UpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration > 232 { 233 public: 234 UpdateInformationEnumeration(const uno::Reference< xml::dom::XNodeList >& xNodeList, 235 const uno::Reference< UpdateInformationProvider > xUpdateInformationProvider) : 236 m_xUpdateInformationProvider(xUpdateInformationProvider), 237 m_xNodeList(xNodeList), 238 m_nNodes(xNodeList.is() ? xNodeList->getLength() : 0), 239 m_nCount(0) 240 { 241 }; 242 243 virtual ~UpdateInformationEnumeration() {}; 244 245 // XEnumeration 246 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return m_nCount < m_nNodes; }; 247 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 248 { 249 OSL_ASSERT( m_xNodeList.is() ); 250 OSL_ASSERT( m_xUpdateInformationProvider.is() ); 251 252 if( !(m_nCount < m_nNodes ) ) 253 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this); 254 255 try 256 { 257 deployment::UpdateInformationEntry aEntry; 258 259 uno::Reference< xml::dom::XNode > xAtomEntryNode( m_xNodeList->item(m_nCount++) ); 260 261 uno::Reference< xml::dom::XNode > xSummaryNode( 262 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "summary/text()" ) ) 263 ); 264 265 if( xSummaryNode.is() ) 266 aEntry.Description = xSummaryNode->getNodeValue(); 267 268 uno::Reference< xml::dom::XNode > xContentNode( 269 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "content" ) ) ); 270 271 if( xContentNode.is() ) 272 aEntry.UpdateDocument = m_xUpdateInformationProvider->getDocumentRoot(xContentNode); 273 274 return uno::makeAny(aEntry); 275 } 276 277 // action has been aborted 278 catch( ucb::CommandAbortedException const & e) 279 { throw lang::WrappedTargetException( UNISTRING( "Command aborted" ), *this, uno::makeAny(e) ); } 280 281 // let runtime exception pass 282 catch( uno::RuntimeException const & ) { throw; } 283 284 // document not accessible 285 catch( uno::Exception const & e) 286 { throw lang::WrappedTargetException( UNISTRING( "Document not accessible" ), *this, uno::makeAny(e) ); } 287 } 288 289 private: 290 const uno::Reference< UpdateInformationProvider > m_xUpdateInformationProvider; 291 const uno::Reference< xml::dom::XNodeList > m_xNodeList; 292 const sal_Int32 m_nNodes; 293 sal_Int32 m_nCount; 294 }; 295 296 //------------------------------------------------------------------------------ 297 298 class SingleUpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration > 299 { 300 public: 301 SingleUpdateInformationEnumeration(const uno::Reference< xml::dom::XElement >& xElement) 302 : m_nCount(0) { m_aEntry.UpdateDocument = xElement; }; 303 virtual ~SingleUpdateInformationEnumeration() {}; 304 305 // XEnumeration 306 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return 0 == m_nCount; }; 307 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 308 { 309 if( m_nCount > 0 ) 310 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this); 311 312 ++m_nCount; 313 return uno::makeAny(m_aEntry); 314 }; 315 316 private: 317 sal_uInt8 m_nCount; 318 deployment::UpdateInformationEntry m_aEntry; 319 }; 320 321 322 //------------------------------------------------------------------------------ 323 324 UpdateInformationProvider::UpdateInformationProvider( 325 const uno::Reference<uno::XComponentContext>& xContext, 326 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory, 327 const uno::Reference< ucb::XContentProvider >& xContentProvider, 328 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder, 329 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI 330 ) : m_xContext(xContext), m_xContentIdFactory(xContentIdFactory), 331 m_xContentProvider(xContentProvider), m_xDocumentBuilder(xDocumentBuilder), 332 m_xXPathAPI(xXPathAPI), m_aRequestHeaderList(1) 333 { 334 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager()); 335 if( !xServiceManager.is() ) 336 throw uno::RuntimeException( 337 UNISTRING("unable to obtain service manager from component context"), 338 uno::Reference< uno::XInterface >()); 339 340 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider( 341 xServiceManager->createInstanceWithContext( 342 UNISTRING("com.sun.star.configuration.ConfigurationProvider"), 343 xContext ), 344 uno::UNO_QUERY_THROW); 345 346 rtl::OUStringBuffer buf; 347 buf.append( 348 getConfigurationItem( 349 xConfigurationProvider, 350 UNISTRING("org.openoffice.Setup/Product"), 351 UNISTRING("ooName"))); 352 buf.append(sal_Unicode(' ')); 353 buf.append( 354 getConfigurationItem( 355 xConfigurationProvider, 356 UNISTRING("org.openoffice.Setup/Product"), 357 UNISTRING("ooSetupVersion"))); 358 rtl::OUString edition( 359 UNISTRING( 360 "${${BRAND_BASE_DIR}/program/edition/edition.ini:" 361 "EDITIONNAME}")); 362 rtl::Bootstrap::expandMacros(edition); 363 if (edition.getLength() != 0) { 364 buf.append(sal_Unicode(' ')); 365 buf.append(edition); 366 } 367 rtl::OUString extension( 368 getConfigurationItem( 369 xConfigurationProvider, 370 UNISTRING("org.openoffice.Setup/Product"), 371 UNISTRING("ooSetupExtension"))); 372 if (extension.getLength() != 0) { 373 buf.append(sal_Unicode(' ')); 374 buf.append(extension); 375 } 376 rtl::OUString product(buf.makeStringAndClear()); 377 378 rtl::OUString aBaseBuildId( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) ); 379 rtl::Bootstrap::expandMacros( aBaseBuildId ); 380 381 rtl::OUString aBrandBuildId( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) ); 382 rtl::Bootstrap::expandMacros( aBrandBuildId ); 383 384 rtl::OUString aUserAgent( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" ) ); 385 rtl::Bootstrap::expandMacros( aUserAgent ); 386 387 if ( ! aBaseBuildId.equals( aBrandBuildId ) ) 388 { 389 sal_Int32 nIndex = aUserAgent.indexOf( aBrandBuildId, 0 ); 390 if ( nIndex != -1 ) 391 aUserAgent = aUserAgent.replaceAt( nIndex, aBrandBuildId.getLength(), aBaseBuildId ); 392 } 393 394 for (sal_Int32 i = 0;;) { 395 i = aUserAgent.indexOfAsciiL( 396 RTL_CONSTASCII_STRINGPARAM("<PRODUCT>"), i); 397 if (i == -1) { 398 break; 399 } 400 aUserAgent = aUserAgent.replaceAt( 401 i, RTL_CONSTASCII_LENGTH("<PRODUCT>"), product); 402 i += product.getLength(); 403 } 404 405 m_aRequestHeaderList[0].First = UNISTRING("Accept-Language"); 406 m_aRequestHeaderList[0].Second = getConfigurationItem( xConfigurationProvider, UNISTRING("org.openoffice.Setup/L10N"), UNISTRING("ooLocale") ); 407 if( aUserAgent.getLength() > 0 ) 408 { 409 m_aRequestHeaderList.realloc(2); 410 m_aRequestHeaderList[1].First = UNISTRING("User-Agent"); 411 m_aRequestHeaderList[1].Second = aUserAgent; 412 } 413 } 414 415 //------------------------------------------------------------------------------ 416 uno::Reference< uno::XInterface > 417 UpdateInformationProvider::createInstance(const uno::Reference<uno::XComponentContext>& xContext) 418 { 419 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager()); 420 if( !xServiceManager.is() ) 421 throw uno::RuntimeException( 422 UNISTRING( "unable to obtain service manager from component context" ), 423 uno::Reference< uno::XInterface > ()); 424 425 uno::Reference< ucb::XContentIdentifierFactory > xContentIdFactory( 426 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.ucb.UniversalContentBroker" ), xContext ), 427 uno::UNO_QUERY_THROW); 428 429 uno::Reference< ucb::XContentProvider > xContentProvider(xContentIdFactory, uno::UNO_QUERY_THROW); 430 431 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder( 432 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.dom.DocumentBuilder" ), xContext ), 433 uno::UNO_QUERY_THROW); 434 435 uno::Reference< xml::xpath::XXPathAPI > xXPath( 436 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), xContext ), 437 uno::UNO_QUERY_THROW); 438 439 xXPath->registerNS( UNISTRING("atom"), UNISTRING("http://www.w3.org/2005/Atom") ); 440 441 return *new UpdateInformationProvider(xContext, xContentIdFactory, xContentProvider, xDocumentBuilder, xXPath); 442 } 443 444 //------------------------------------------------------------------------------ 445 446 UpdateInformationProvider::~UpdateInformationProvider() 447 { 448 } 449 450 //------------------------------------------------------------------------------ 451 452 rtl::OUString 453 UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item) 454 { 455 rtl::OUString sRet; 456 beans::PropertyValue aProperty; 457 aProperty.Name = UNISTRING("nodepath"); 458 aProperty.Value = uno::makeAny(node); 459 460 uno::Sequence< uno::Any > aArgumentList( 1 ); 461 aArgumentList[0] = uno::makeAny( aProperty ); 462 463 uno::Reference< container::XNameAccess > xNameAccess( 464 configurationProvider->createInstanceWithArguments( 465 UNISTRING("com.sun.star.configuration.ConfigurationAccess"), 466 aArgumentList ), 467 uno::UNO_QUERY_THROW); 468 469 xNameAccess->getByName(item) >>= sRet; 470 return sRet; 471 } 472 473 //------------------------------------------------------------------------------ 474 475 void 476 UpdateInformationProvider::storeCommandInfo( 477 sal_Int32 nCommandId, 478 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor) 479 { 480 osl::MutexGuard aGuard(m_aMutex); 481 482 m_nCommandId = nCommandId; 483 m_xCommandProcessor = rxCommandProcessor; 484 } 485 486 //------------------------------------------------------------------------------ 487 488 uno::Reference< io::XInputStream > 489 UpdateInformationProvider::load(const rtl::OUString& rURL) 490 { 491 uno::Reference< ucb::XContentIdentifier > xId = m_xContentIdFactory->createContentIdentifier(rURL); 492 493 if( !xId.is() ) 494 throw uno::RuntimeException( 495 UNISTRING( "unable to obtain universal content id" ), *this); 496 497 uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xContentProvider->queryContent(xId), uno::UNO_QUERY_THROW); 498 rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink()); 499 500 ucb::OpenCommandArgument2 aOpenArgument; 501 aOpenArgument.Mode = ucb::OpenMode::DOCUMENT; 502 aOpenArgument.Priority = 32768; 503 aOpenArgument.Sink = *aSink; 504 505 ucb::Command aCommand; 506 aCommand.Name = UNISTRING("open"); 507 aCommand.Argument = uno::makeAny(aOpenArgument); 508 509 sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier(); 510 511 storeCommandInfo(nCommandId, xCommandProcessor); 512 try 513 { 514 uno::Any aResult = xCommandProcessor->execute(aCommand, nCommandId, 515 static_cast < XCommandEnvironment *> (this)); 516 } 517 catch( const uno::Exception & /* e */ ) 518 { 519 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ()); 520 521 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY); 522 if( xCommandProcessor2.is() ) 523 xCommandProcessor2->releaseCommandIdentifier(nCommandId); 524 525 throw; 526 } 527 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ()); 528 529 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY); 530 if( xCommandProcessor2.is() ) 531 xCommandProcessor2->releaseCommandIdentifier(nCommandId); 532 533 return INPUT_STREAM(aSink->getInputStream()); 534 } 535 536 //------------------------------------------------------------------------------ 537 538 // TODO: docu content node 539 540 uno::Reference< xml::dom::XElement > 541 UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode) 542 { 543 OSL_ASSERT(m_xDocumentBuilder.is()); 544 545 uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW); 546 547 // load the document referenced in 'src' attribute .. 548 if( xElement->hasAttribute( UNISTRING("src") ) ) 549 { 550 uno::Reference< xml::dom::XDocument > xUpdateXML = 551 m_xDocumentBuilder->parse(load(xElement->getAttribute( UNISTRING("src") ))); 552 553 OSL_ASSERT( xUpdateXML.is() ); 554 555 if( xUpdateXML.is() ) 556 return xUpdateXML->getDocumentElement(); 557 } 558 // .. or return the (single) child element 559 else 560 { 561 uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes(); 562 563 // ignore possible #text nodes 564 sal_Int32 nmax = xChildNodes->getLength(); 565 for(sal_Int32 n=0; n < nmax; n++) 566 { 567 uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY); 568 if( xChildElement.is() ) 569 { 570 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList 571 * seems to evaluate expression always relative to the root node. 572 */ 573 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument(); 574 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement.get(), sal_True ) ); 575 return xUpdateXML->getDocumentElement(); 576 } 577 } 578 } 579 580 return uno::Reference< xml::dom::XElement > (); 581 } 582 583 //------------------------------------------------------------------------------ 584 585 uno::Reference< xml::dom::XNode > 586 UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, 587 const rtl::OUString& rName) 588 { 589 OSL_ASSERT(m_xXPathAPI.is()); 590 try { 591 return m_xXPathAPI->selectSingleNode(rxNode, UNISTRING( "./atom:" ) + rName); 592 } catch (xml::xpath::XPathException &) { 593 // ignore 594 return 0; 595 } 596 } 597 598 //------------------------------------------------------------------------------ 599 600 uno::Reference< container::XEnumeration > SAL_CALL 601 UpdateInformationProvider::getUpdateInformationEnumeration( 602 uno::Sequence< rtl::OUString > const & repositories, 603 rtl::OUString const & extensionId 604 ) throw (uno::Exception, uno::RuntimeException) 605 { 606 OSL_ASSERT(m_xDocumentBuilder.is()); 607 608 // reset cancelled flag 609 m_bCancelled.reset(); 610 611 for(sal_Int32 n=0; n<repositories.getLength(); n++) 612 { 613 try 614 { 615 uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n])); 616 uno::Reference< xml::dom::XElement > xElement; 617 618 if( xDocument.is() ) 619 xElement = xDocument->getDocumentElement(); 620 621 if( xElement.is() ) 622 { 623 if( xElement->getNodeName().equalsAsciiL("feed", 4) ) 624 { 625 rtl::OUString aXPathExpression; 626 627 if( extensionId.getLength() > 0 ) 628 aXPathExpression = UNISTRING("//atom:entry/atom:category[@term=\'") + extensionId + UNISTRING("\']/.."); 629 else 630 aXPathExpression = UNISTRING("//atom:entry"); 631 632 uno::Reference< xml::dom::XNodeList > xNodeList; 633 try { 634 xNodeList = m_xXPathAPI->selectNodeList(xDocument.get(), 635 aXPathExpression); 636 } catch (xml::xpath::XPathException &) { 637 // ignore 638 } 639 640 return new UpdateInformationEnumeration(xNodeList, this); 641 } 642 else 643 { 644 return new SingleUpdateInformationEnumeration(xElement); 645 } 646 } 647 648 if( m_bCancelled.check() ) 649 break; 650 } 651 catch( uno::RuntimeException const& /*e*/) 652 { 653 // #i118675# ignore runtime exceptions for now 654 // especially the "unsatisfied query for interface of type com.sun.star.ucb.XCommandProcessor!" exception 655 } 656 657 // rethrow only if last url in the list 658 catch( uno::Exception const & ) 659 { 660 if( n+1 >= repositories.getLength() ) 661 throw; 662 } 663 } 664 665 return uno::Reference< container::XEnumeration >(); 666 } 667 668 //------------------------------------------------------------------------------ 669 670 uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL 671 UpdateInformationProvider::getUpdateInformation( 672 uno::Sequence< rtl::OUString > const & repositories, 673 rtl::OUString const & extensionId 674 ) throw (uno::Exception, uno::RuntimeException) 675 { 676 uno::Reference< container::XEnumeration > xEnumeration( 677 getUpdateInformationEnumeration(repositories, extensionId) 678 ); 679 680 uno::Sequence< uno::Reference< xml::dom::XElement > > aRet; 681 682 if( xEnumeration.is() ) 683 { 684 while( xEnumeration->hasMoreElements() ) 685 { 686 try 687 { 688 deployment::UpdateInformationEntry aEntry; 689 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() ) 690 { 691 sal_Int32 n = aRet.getLength(); 692 aRet.realloc(n + 1); 693 aRet[n] = aEntry.UpdateDocument; 694 } 695 } 696 697 catch( const lang::WrappedTargetException& e ) 698 { 699 // command aborted, return what we have got so far 700 if( e.TargetException.isExtractableTo( ::cppu::UnoType< ::com::sun::star::ucb::CommandAbortedException >::get() ) ) 701 { 702 break; 703 } 704 705 // ignore files that can't be loaded 706 } 707 } 708 } 709 710 return aRet; 711 } 712 713 //------------------------------------------------------------------------------ 714 715 void SAL_CALL 716 UpdateInformationProvider::cancel() throw (uno::RuntimeException) 717 { 718 m_bCancelled.set(); 719 720 osl::MutexGuard aGuard(m_aMutex); 721 if( m_xCommandProcessor.is() ) 722 m_xCommandProcessor->abort(m_nCommandId); 723 } 724 725 //------------------------------------------------------------------------------ 726 727 void SAL_CALL 728 UpdateInformationProvider::setInteractionHandler( 729 uno::Reference< task::XInteractionHandler > const & handler ) 730 throw (uno::RuntimeException) 731 { 732 osl::MutexGuard aGuard(m_aMutex); 733 m_xInteractionHandler = handler; 734 } 735 736 //------------------------------------------------------------------------------ 737 738 uno::Reference< task::XInteractionHandler > SAL_CALL 739 UpdateInformationProvider::getInteractionHandler() 740 throw ( uno::RuntimeException ) 741 { 742 osl::MutexGuard aGuard( m_aMutex ); 743 744 if ( m_xInteractionHandler.is() ) 745 return m_xInteractionHandler; 746 else 747 { 748 try 749 { 750 // Supply an interaction handler that uses the password container 751 // service to obtain credentials without displaying a password gui. 752 753 if ( !m_xPwContainerInteractionHandler.is() ) 754 m_xPwContainerInteractionHandler 755 = task::PasswordContainerInteractionHandler::create( 756 m_xContext ); 757 } 758 catch ( uno::RuntimeException const & ) 759 { 760 throw; 761 } 762 catch ( uno::Exception const & ) 763 { 764 } 765 return m_xPwContainerInteractionHandler; 766 } 767 } 768 //------------------------------------------------------------------------------ 769 770 uno::Sequence< rtl::OUString > 771 UpdateInformationProvider::getServiceNames() 772 { 773 uno::Sequence< rtl::OUString > aServiceList(1); 774 aServiceList[0] = UNISTRING( "com.sun.star.deployment.UpdateInformationProvider"); 775 return aServiceList; 776 }; 777 778 //------------------------------------------------------------------------------ 779 780 rtl::OUString 781 UpdateInformationProvider::getImplName() 782 { 783 return UNISTRING( "vnd.sun.UpdateInformationProvider"); 784 } 785 786 //------------------------------------------------------------------------------ 787 788 rtl::OUString SAL_CALL 789 UpdateInformationProvider::getImplementationName() throw (uno::RuntimeException) 790 { 791 return getImplName(); 792 } 793 794 //------------------------------------------------------------------------------ 795 796 uno::Sequence< rtl::OUString > SAL_CALL 797 UpdateInformationProvider::getSupportedServiceNames() throw (uno::RuntimeException) 798 { 799 return getServiceNames(); 800 } 801 802 //------------------------------------------------------------------------------ 803 804 sal_Bool SAL_CALL 805 UpdateInformationProvider::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException) 806 { 807 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames(); 808 809 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ ) 810 if( aServiceNameList[n].equals(serviceName) ) 811 return sal_True; 812 813 return sal_False; 814 } 815 816 } // anonymous namespace 817 818 //------------------------------------------------------------------------------ 819 820 static uno::Reference<uno::XInterface> SAL_CALL 821 createInstance(uno::Reference<uno::XComponentContext> const & xContext) 822 { 823 return UpdateInformationProvider::createInstance(xContext); 824 } 825 826 //------------------------------------------------------------------------------ 827 828 static const cppu::ImplementationEntry kImplementations_entries[] = 829 { 830 { 831 createInstance, 832 UpdateInformationProvider::getImplName, 833 UpdateInformationProvider::getServiceNames, 834 cppu::createSingleComponentFactory, 835 NULL, 836 0 837 }, 838 { NULL, NULL, NULL, NULL, NULL, 0 } 839 } ; 840 841 //------------------------------------------------------------------------------ 842 843 extern "C" void SAL_CALL 844 component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **) 845 { 846 *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; 847 } 848 849 //------------------------------------------------------------------------------ 850 851 extern "C" void * 852 component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey) 853 { 854 return cppu::component_getFactoryHelper( 855 pszImplementationName, 856 pServiceManager, 857 pRegistryKey, 858 kImplementations_entries) ; 859 } 860 861