bump product version to 6.3.0.0.beta1
[LibreOffice.git] / extensions / source / update / feed / updatefeed.cxx
blob6998da2f941bf987cc640dd0a02668aef7d3b199
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_folders.h>
22 #include <cppuhelper/exc_hlp.hxx>
23 #include <cppuhelper/implbase.hxx>
24 #include <cppuhelper/implementationentry.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <comphelper/sequence.hxx>
27 #include <com/sun/star/beans/Property.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/beans/XPropertySetInfo.hpp>
30 #include <com/sun/star/beans/NamedValue.hpp>
31 #include <com/sun/star/configuration/theDefaultProvider.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/deployment/UpdateInformationEntry.hpp>
34 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
35 #include <com/sun/star/io/XActiveDataSink.hpp>
36 #include <com/sun/star/io/XInputStream.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/ucb/CommandAbortedException.hpp>
40 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
41 #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
42 #include <com/sun/star/ucb/XCommandProcessor2.hpp>
43 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
44 #include <com/sun/star/ucb/XContentProvider.hpp>
45 #include <com/sun/star/ucb/XInteractionSupplyAuthentication.hpp>
46 #include <com/sun/star/ucb/OpenCommandArgument3.hpp>
47 #include <com/sun/star/ucb/OpenMode.hpp>
48 #include <com/sun/star/sdbc/XRow.hpp>
49 #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
50 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
51 #include <com/sun/star/xml/xpath/XPathAPI.hpp>
52 #include <com/sun/star/xml/xpath/XPathException.hpp>
53 #include <rtl/ref.hxx>
54 #include <rtl/bootstrap.hxx>
55 #include <rtl/ustrbuf.hxx>
56 #include <sal/log.hxx>
57 #include <osl/diagnose.h>
58 #include <osl/process.h>
59 #include <osl/conditn.hxx>
60 #include <vcl/svapp.hxx>
62 #ifdef DEBUG
63 #include <com/sun/star/io/NotConnectedException.hpp>
64 #include <com/sun/star/io/BufferSizeExceededException.hpp>
65 #endif
66 namespace beans = com::sun::star::beans ;
67 namespace container = com::sun::star::container ;
68 namespace deployment = com::sun::star::deployment ;
69 namespace io = com::sun::star::io ;
70 namespace lang = com::sun::star::lang ;
71 namespace task = com::sun::star::task ;
72 namespace ucb = com::sun::star::ucb ;
73 namespace uno = com::sun::star::uno ;
74 namespace xml = com::sun::star::xml ;
77 namespace
80 #ifdef DEBUG
82 class InputStreamWrapper : public ::cppu::WeakImplHelper< io::XInputStream >
84 uno::Reference< io::XInputStream > m_xStream;
86 public:
87 explicit InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) :
88 m_xStream(rxStream) {};
90 virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
91 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
93 sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead);
94 return n;
96 virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
97 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
99 sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead);
100 return n;
102 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
103 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
104 { m_xStream->skipBytes(nBytesToSkip); };
105 virtual sal_Int32 SAL_CALL available()
106 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
107 { return m_xStream->available(); };
108 virtual void SAL_CALL closeInput( )
109 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
113 #define INPUT_STREAM(i) new InputStreamWrapper(i)
114 #else
115 #define INPUT_STREAM(i) i
116 #endif
119 class ActiveDataSink : public ::cppu::WeakImplHelper< io::XActiveDataSink >
121 uno::Reference< io::XInputStream > m_xStream;
123 public:
124 ActiveDataSink() {};
126 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream() override { return m_xStream; };
127 virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream ) override { m_xStream = rStream; };
131 class UpdateInformationProvider :
132 public ::cppu::WeakImplHelper< deployment::XUpdateInformationProvider,
133 ucb::XWebDAVCommandEnvironment,
134 lang::XServiceInfo >
136 OUString getUserAgent(bool bExtended);
137 bool isUserAgentExtended();
138 public:
139 static uno::Reference< uno::XInterface > createInstance(const uno::Reference<uno::XComponentContext>& xContext);
141 static uno::Sequence< OUString > getServiceNames();
142 static OUString getImplName();
144 uno::Reference< xml::dom::XElement > getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode);
145 uno::Reference< xml::dom::XNode > getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, const OUString& rName);
148 // XUpdateInformationService
149 virtual uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
150 getUpdateInformation(
151 uno::Sequence< OUString > const & repositories,
152 OUString const & extensionId
153 ) override;
155 virtual void SAL_CALL cancel() override;
157 virtual void SAL_CALL setInteractionHandler(
158 uno::Reference< task::XInteractionHandler > const & handler ) override;
160 virtual uno::Reference< container::XEnumeration > SAL_CALL
161 getUpdateInformationEnumeration(
162 uno::Sequence< OUString > const & repositories,
163 OUString const & extensionId
164 ) override;
166 // XCommandEnvironment
167 virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
169 virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler() override { return uno::Reference< ucb::XProgressHandler >(); };
171 // XWebDAVCommandEnvironment
172 virtual uno::Sequence< beans::StringPair > SAL_CALL getUserRequestHeaders(
173 const OUString&, ucb::WebDAVHTTPMethod ) override;
175 // XServiceInfo
176 virtual OUString SAL_CALL getImplementationName() override;
177 virtual sal_Bool SAL_CALL supportsService(OUString const & serviceName) override;
178 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
180 protected:
182 virtual ~UpdateInformationProvider() override;
183 static OUString getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item);
184 static uno::Any getConfigurationItemAny(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item);
186 private:
187 uno::Reference< io::XInputStream > load(const OUString& rURL);
189 void storeCommandInfo( sal_Int32 nCommandId,
190 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor);
192 UpdateInformationProvider(const uno::Reference<uno::XComponentContext>& xContext,
193 const uno::Reference< ucb::XUniversalContentBroker >& xUniversalContentBroker,
194 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
195 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI);
197 const uno::Reference< uno::XComponentContext> m_xContext;
199 const uno::Reference< ucb::XUniversalContentBroker > m_xUniversalContentBroker;
200 const uno::Reference< xml::dom::XDocumentBuilder > m_xDocumentBuilder;
201 const uno::Reference< xml::xpath::XXPathAPI > m_xXPathAPI;
203 uno::Sequence< beans::StringPair > m_aRequestHeaderList;
205 uno::Reference< ucb::XCommandProcessor > m_xCommandProcessor;
206 uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
207 uno::Reference< task::XInteractionHandler > m_xPwContainerInteractionHandler;
209 osl::Mutex m_aMutex;
210 osl::Condition m_bCancelled;
212 sal_Int32 m_nCommandId;
216 class UpdateInformationEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
218 public:
219 UpdateInformationEnumeration(const uno::Reference< xml::dom::XNodeList >& xNodeList,
220 const rtl::Reference< UpdateInformationProvider >& xUpdateInformationProvider) :
221 m_xUpdateInformationProvider(xUpdateInformationProvider),
222 m_xNodeList(xNodeList),
223 m_nNodes(xNodeList.is() ? xNodeList->getLength() : 0),
224 m_nCount(0)
228 // XEnumeration
229 sal_Bool SAL_CALL hasMoreElements() override { return m_nCount < m_nNodes; };
230 uno::Any SAL_CALL nextElement() override
232 OSL_ASSERT( m_xNodeList.is() );
233 OSL_ASSERT( m_xUpdateInformationProvider.is() );
235 if( m_nCount >= m_nNodes )
236 throw container::NoSuchElementException(OUString::number(m_nCount), *this);
240 deployment::UpdateInformationEntry aEntry;
242 uno::Reference< xml::dom::XNode > xAtomEntryNode( m_xNodeList->item(m_nCount++) );
244 uno::Reference< xml::dom::XNode > xSummaryNode(
245 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, "summary/text()" )
248 if( xSummaryNode.is() )
249 aEntry.Description = xSummaryNode->getNodeValue();
251 uno::Reference< xml::dom::XNode > xContentNode(
252 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, "content" ) );
254 if( xContentNode.is() )
255 aEntry.UpdateDocument = m_xUpdateInformationProvider->getDocumentRoot(xContentNode);
257 return uno::makeAny(aEntry);
259 catch( ucb::CommandAbortedException const &)
261 // action has been aborted
262 css::uno::Any anyEx = cppu::getCaughtException();
263 throw lang::WrappedTargetException( "Command aborted", *this, anyEx );
265 catch( uno::RuntimeException const & )
267 // let runtime exception pass
268 throw;
270 catch( uno::Exception const &)
272 // document not accessible
273 css::uno::Any anyEx = cppu::getCaughtException();
274 throw lang::WrappedTargetException( "Document not accessible", *this, anyEx );
278 private:
279 const rtl::Reference< UpdateInformationProvider > m_xUpdateInformationProvider;
280 const uno::Reference< xml::dom::XNodeList > m_xNodeList;
281 const sal_Int32 m_nNodes;
282 sal_Int32 m_nCount;
286 class SingleUpdateInformationEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
288 public:
289 explicit SingleUpdateInformationEnumeration(const uno::Reference< xml::dom::XElement >& xElement)
290 : m_nCount(0) { m_aEntry.UpdateDocument = xElement; };
292 // XEnumeration
293 sal_Bool SAL_CALL hasMoreElements() override { return 0 == m_nCount; };
294 uno::Any SAL_CALL nextElement() override
296 if( m_nCount > 0 )
297 throw container::NoSuchElementException(OUString::number(m_nCount), *this);
299 ++m_nCount;
300 return uno::makeAny(m_aEntry);
303 private:
304 sal_Int32 m_nCount;
305 deployment::UpdateInformationEntry m_aEntry;
308 UpdateInformationProvider::UpdateInformationProvider(
309 const uno::Reference<uno::XComponentContext>& xContext,
310 const uno::Reference< ucb::XUniversalContentBroker >& xUniversalContentBroker,
311 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
312 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI)
313 : m_xContext(xContext)
314 , m_xUniversalContentBroker(xUniversalContentBroker)
315 , m_xDocumentBuilder(xDocumentBuilder)
316 , m_xXPathAPI(xXPathAPI)
317 , m_aRequestHeaderList(2)
318 , m_nCommandId(0)
320 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
321 css::configuration::theDefaultProvider::get(m_xContext));
323 m_aRequestHeaderList[0].First = "Accept-Language";
324 m_aRequestHeaderList[0].Second = getConfigurationItem( xConfigurationProvider, "org.openoffice.Setup/L10N", "ooLocale" );
327 bool
328 UpdateInformationProvider::isUserAgentExtended()
330 bool bExtendedUserAgent = false;
331 try {
332 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
333 css::configuration::theDefaultProvider::get(m_xContext));
335 uno::Any aExtended = getConfigurationItemAny(
336 xConfigurationProvider,
337 "org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments",
338 "ExtendedUserAgent");
339 aExtended >>= bExtendedUserAgent;
340 } catch (const uno::RuntimeException &) {
341 SAL_WARN("extensions.update", "Online update disabled");
343 return bExtendedUserAgent;
346 OUString UpdateInformationProvider::getUserAgent(bool bExtended)
348 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
349 css::configuration::theDefaultProvider::get(m_xContext));
351 OUStringBuffer buf;
352 buf.append(
353 getConfigurationItem(
354 xConfigurationProvider,
355 "org.openoffice.Setup/Product",
356 "ooName"));
357 buf.append(' ');
358 buf.append(
359 getConfigurationItem(
360 xConfigurationProvider,
361 "org.openoffice.Setup/Product",
362 "ooSetupVersion"));
364 OUString extension(
365 getConfigurationItem(
366 xConfigurationProvider,
367 "org.openoffice.Setup/Product",
368 "ooSetupExtension"));
369 if (!extension.isEmpty())
370 buf.append(extension);
372 OUString product(buf.makeStringAndClear());
374 OUString aUserAgent( "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" );
375 OUString aExtended;
376 if( bExtended )
378 aExtended = Application::GetHWOSConfInfo();
380 rtl::Bootstrap::expandMacros( aUserAgent );
381 aUserAgent = aUserAgent.replaceAll("<PRODUCT>", product);
382 aUserAgent = aUserAgent.replaceAll("<OPTIONAL_OS_HW_DATA>", aExtended);
383 SAL_INFO("extensions.update", "UpdateUserAgent: " << aUserAgent);
385 return aUserAgent;
388 uno::Sequence< beans::StringPair > SAL_CALL UpdateInformationProvider::getUserRequestHeaders(
389 const OUString &aURL, ucb::WebDAVHTTPMethod )
391 bool bExtendedUserAgent;
392 uno::Sequence< beans::StringPair > aPair = m_aRequestHeaderList;
394 // Internal use from cui/ some magic URLs
395 if( aURL.startsWith( "useragent:" ) )
396 bExtendedUserAgent = (aURL == "useragent:extended");
397 else
398 bExtendedUserAgent = isUserAgentExtended();
400 OUString aUserAgent = getUserAgent(bExtendedUserAgent);
402 if( aUserAgent.isEmpty() )
403 aPair.realloc(1);
404 else
406 aPair[1].First = "User-Agent";
407 aPair[1].Second = aUserAgent;
410 return aPair;
413 uno::Reference< uno::XInterface >
414 UpdateInformationProvider::createInstance(const uno::Reference<uno::XComponentContext>& xContext)
416 uno::Reference< ucb::XUniversalContentBroker > xUniversalContentBroker =
417 ucb::UniversalContentBroker::create(xContext);
419 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder(
420 xml::dom::DocumentBuilder::create(xContext));
422 uno::Reference< xml::xpath::XXPathAPI > xXPath = xml::xpath::XPathAPI::create( xContext );
424 xXPath->registerNS( "atom", "http://www.w3.org/2005/Atom" );
426 return *new UpdateInformationProvider(xContext, xUniversalContentBroker, xDocumentBuilder, xXPath);
429 UpdateInformationProvider::~UpdateInformationProvider()
433 uno::Any
434 UpdateInformationProvider::getConfigurationItemAny(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item)
436 beans::PropertyValue aProperty;
437 aProperty.Name = "nodepath";
438 aProperty.Value <<= node;
440 uno::Sequence< uno::Any > aArgumentList( 1 );
441 aArgumentList[0] <<= aProperty;
443 uno::Reference< container::XNameAccess > xNameAccess(
444 configurationProvider->createInstanceWithArguments(
445 "com.sun.star.configuration.ConfigurationAccess",
446 aArgumentList ),
447 uno::UNO_QUERY_THROW);
449 return xNameAccess->getByName(item);
452 OUString
453 UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item)
455 OUString sRet;
456 getConfigurationItemAny(configurationProvider, node, item) >>= sRet;
457 return sRet;
460 void
461 UpdateInformationProvider::storeCommandInfo(
462 sal_Int32 nCommandId,
463 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor)
465 osl::MutexGuard aGuard(m_aMutex);
467 m_nCommandId = nCommandId;
468 m_xCommandProcessor = rxCommandProcessor;
471 uno::Reference< io::XInputStream >
472 UpdateInformationProvider::load(const OUString& rURL)
474 uno::Reference< ucb::XContentIdentifier > xId = m_xUniversalContentBroker->createContentIdentifier(rURL);
476 if( !xId.is() )
477 throw uno::RuntimeException(
478 "unable to obtain universal content id", *this);
480 uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xUniversalContentBroker->queryContent(xId), uno::UNO_QUERY_THROW);
481 rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink());
483 // Disable KeepAlive in webdav - don't want millions of office
484 // instances phone home & clog up servers
485 uno::Sequence< beans::NamedValue > aProps { { "KeepAlive", uno::makeAny(false) } };
487 ucb::OpenCommandArgument3 aOpenArgument;
488 aOpenArgument.Mode = ucb::OpenMode::DOCUMENT;
489 aOpenArgument.Priority = 32768;
490 aOpenArgument.Sink = *aSink;
491 aOpenArgument.OpeningFlags = aProps;
493 ucb::Command aCommand;
494 aCommand.Name = "open";
495 aCommand.Argument <<= aOpenArgument;
497 sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier();
499 storeCommandInfo(nCommandId, xCommandProcessor);
502 xCommandProcessor->execute(aCommand, nCommandId,
503 static_cast < XCommandEnvironment *> (this));
505 catch( const uno::Exception & /* e */ )
507 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
509 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
510 if( xCommandProcessor2.is() )
511 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
513 throw;
515 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
517 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
518 if( xCommandProcessor2.is() )
519 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
521 return INPUT_STREAM(aSink->getInputStream());
525 // TODO: docu content node
527 uno::Reference< xml::dom::XElement >
528 UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode)
530 OSL_ASSERT(m_xDocumentBuilder.is());
532 uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW);
534 // load the document referenced in 'src' attribute ..
535 if( xElement->hasAttribute( "src" ) )
537 uno::Reference< xml::dom::XDocument > xUpdateXML =
538 m_xDocumentBuilder->parse(load(xElement->getAttribute( "src" )));
540 OSL_ASSERT( xUpdateXML.is() );
542 if( xUpdateXML.is() )
543 return xUpdateXML->getDocumentElement();
545 // .. or return the (single) child element
546 else
548 uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes();
550 // ignore possible #text nodes
551 sal_Int32 nmax = xChildNodes->getLength();
552 for(sal_Int32 n=0; n < nmax; n++)
554 uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY);
555 if( xChildElement.is() )
557 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList
558 * seems to evaluate expression always relative to the root node.
560 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument();
561 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement.get(), true ) );
562 return xUpdateXML->getDocumentElement();
567 return uno::Reference< xml::dom::XElement > ();
571 uno::Reference< xml::dom::XNode >
572 UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode,
573 const OUString& rName)
575 OSL_ASSERT(m_xXPathAPI.is());
576 try {
577 return m_xXPathAPI->selectSingleNode(rxNode, "./atom:" + rName);
578 } catch (const xml::xpath::XPathException &) {
579 // ignore
580 return nullptr;
585 uno::Reference< container::XEnumeration > SAL_CALL
586 UpdateInformationProvider::getUpdateInformationEnumeration(
587 uno::Sequence< OUString > const & repositories,
588 OUString const & extensionId
591 OSL_ASSERT(m_xDocumentBuilder.is());
593 // reset cancelled flag
594 m_bCancelled.reset();
596 for(sal_Int32 n=0; n<repositories.getLength(); n++)
600 uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n]));
601 uno::Reference< xml::dom::XElement > xElement;
603 if( xDocument.is() )
604 xElement = xDocument->getDocumentElement();
606 if( xElement.is() )
608 if( xElement->getNodeName() == "feed" )
610 OUString aXPathExpression;
612 if( !extensionId.isEmpty() )
613 aXPathExpression = "//atom:entry/atom:category[@term=\'" + extensionId + "\']/..";
614 else
615 aXPathExpression = "//atom:entry";
617 uno::Reference< xml::dom::XNodeList > xNodeList;
618 try {
619 xNodeList = m_xXPathAPI->selectNodeList(xDocument.get(),
620 aXPathExpression);
621 } catch (const xml::xpath::XPathException &) {
622 // ignore
625 return new UpdateInformationEnumeration(xNodeList, this);
627 else
629 return new SingleUpdateInformationEnumeration(xElement);
633 if( m_bCancelled.check() )
634 break;
636 catch( uno::RuntimeException const& /*e*/)
638 // #i118675# ignore runtime exceptions for now
639 // especially the "unsatisfied query for interface of
640 // type com.sun.star.ucb.XCommandProcessor!" exception
643 // rethrow only if last url in the list
644 catch( uno::Exception const & )
646 if( n+1 >= repositories.getLength() )
647 throw;
651 return uno::Reference< container::XEnumeration >();
655 uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
656 UpdateInformationProvider::getUpdateInformation(
657 uno::Sequence< OUString > const & repositories,
658 OUString const & extensionId
661 uno::Reference< container::XEnumeration > xEnumeration(
662 getUpdateInformationEnumeration(repositories, extensionId)
665 std::vector< uno::Reference< xml::dom::XElement > > aRet;
667 if( xEnumeration.is() )
669 while( xEnumeration->hasMoreElements() )
673 deployment::UpdateInformationEntry aEntry;
674 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() )
676 aRet.push_back(aEntry.UpdateDocument);
680 catch( const lang::WrappedTargetException& e )
682 // command aborted, return what we have got so far
683 if( e.TargetException.isExtractableTo( ::cppu::UnoType< css::ucb::CommandAbortedException >::get() ) )
685 break;
688 // ignore files that can't be loaded
693 return comphelper::containerToSequence(aRet);
697 void SAL_CALL
698 UpdateInformationProvider::cancel()
700 m_bCancelled.set();
702 osl::MutexGuard aGuard(m_aMutex);
703 if( m_xCommandProcessor.is() )
704 m_xCommandProcessor->abort(m_nCommandId);
708 void SAL_CALL
709 UpdateInformationProvider::setInteractionHandler(
710 uno::Reference< task::XInteractionHandler > const & handler )
712 osl::MutexGuard aGuard(m_aMutex);
713 m_xInteractionHandler = handler;
717 uno::Reference< task::XInteractionHandler > SAL_CALL
718 UpdateInformationProvider::getInteractionHandler()
720 osl::MutexGuard aGuard( m_aMutex );
722 if ( m_xInteractionHandler.is() )
723 return m_xInteractionHandler;
724 else
728 // Supply an interaction handler that uses the password container
729 // service to obtain credentials without displaying a password gui.
731 if ( !m_xPwContainerInteractionHandler.is() )
732 m_xPwContainerInteractionHandler
733 = task::PasswordContainerInteractionHandler::create(
734 m_xContext );
736 catch ( uno::RuntimeException const & )
738 throw;
740 catch ( uno::Exception const & )
743 return m_xPwContainerInteractionHandler;
748 uno::Sequence< OUString >
749 UpdateInformationProvider::getServiceNames()
751 uno::Sequence< OUString > aServiceList { "com.sun.star.deployment.UpdateInformationProvider" };
752 return aServiceList;
756 OUString
757 UpdateInformationProvider::getImplName()
759 return OUString("vnd.sun.UpdateInformationProvider");
763 OUString SAL_CALL
764 UpdateInformationProvider::getImplementationName()
766 return getImplName();
770 uno::Sequence< OUString > SAL_CALL
771 UpdateInformationProvider::getSupportedServiceNames()
773 return getServiceNames();
776 sal_Bool SAL_CALL
777 UpdateInformationProvider::supportsService( OUString const & serviceName )
779 return cppu::supportsService(this, serviceName);
782 } // anonymous namespace
785 static uno::Reference<uno::XInterface>
786 createInstance(uno::Reference<uno::XComponentContext> const & xContext)
788 return UpdateInformationProvider::createInstance(xContext);
792 static const cppu::ImplementationEntry kImplementations_entries[] =
795 createInstance,
796 UpdateInformationProvider::getImplName,
797 UpdateInformationProvider::getServiceNames,
798 cppu::createSingleComponentFactory,
799 nullptr,
802 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
806 extern "C" SAL_DLLPUBLIC_EXPORT void * updatefeed_component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
808 return cppu::component_getFactoryHelper(
809 pszImplementationName,
810 pServiceManager,
811 pRegistryKey,
812 kImplementations_entries) ;
815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */