1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
63 #include <com/sun/star/io/NotConnectedException.hpp>
64 #include <com/sun/star/io/BufferSizeExceededException.hpp>
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
;
82 class InputStreamWrapper
: public ::cppu::WeakImplHelper
< io::XInputStream
>
84 uno::Reference
< io::XInputStream
> m_xStream
;
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
);
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
);
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)
115 #define INPUT_STREAM(i) i
119 class ActiveDataSink
: public ::cppu::WeakImplHelper
< io::XActiveDataSink
>
121 uno::Reference
< io::XInputStream
> m_xStream
;
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
,
136 OUString
getUserAgent(bool bExtended
);
137 bool isUserAgentExtended();
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
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
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
;
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
;
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
);
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
;
210 osl::Condition m_bCancelled
;
212 sal_Int32 m_nCommandId
;
216 class UpdateInformationEnumeration
: public ::cppu::WeakImplHelper
< container::XEnumeration
>
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),
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
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
);
279 const rtl::Reference
< UpdateInformationProvider
> m_xUpdateInformationProvider
;
280 const uno::Reference
< xml::dom::XNodeList
> m_xNodeList
;
281 const sal_Int32 m_nNodes
;
286 class SingleUpdateInformationEnumeration
: public ::cppu::WeakImplHelper
< container::XEnumeration
>
289 explicit SingleUpdateInformationEnumeration(const uno::Reference
< xml::dom::XElement
>& xElement
)
290 : m_nCount(0) { m_aEntry
.UpdateDocument
= xElement
; };
293 sal_Bool SAL_CALL
hasMoreElements() override
{ return 0 == m_nCount
; };
294 uno::Any SAL_CALL
nextElement() override
297 throw container::NoSuchElementException(OUString::number(m_nCount
), *this);
300 return uno::makeAny(m_aEntry
);
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)
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" );
328 UpdateInformationProvider::isUserAgentExtended()
330 bool bExtendedUserAgent
= false;
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
));
353 getConfigurationItem(
354 xConfigurationProvider
,
355 "org.openoffice.Setup/Product",
359 getConfigurationItem(
360 xConfigurationProvider
,
361 "org.openoffice.Setup/Product",
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}" );
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
);
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");
398 bExtendedUserAgent
= isUserAgentExtended();
400 OUString aUserAgent
= getUserAgent(bExtendedUserAgent
);
402 if( aUserAgent
.isEmpty() )
406 aPair
[1].First
= "User-Agent";
407 aPair
[1].Second
= aUserAgent
;
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()
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",
447 uno::UNO_QUERY_THROW
);
449 return xNameAccess
->getByName(item
);
453 UpdateInformationProvider::getConfigurationItem(uno::Reference
<lang::XMultiServiceFactory
> const & configurationProvider
, OUString
const & node
, OUString
const & item
)
456 getConfigurationItemAny(configurationProvider
, node
, item
) >>= sRet
;
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
);
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
);
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
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());
577 return m_xXPathAPI
->selectSingleNode(rxNode
, "./atom:" + rName
);
578 } catch (const xml::xpath::XPathException
&) {
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
;
604 xElement
= xDocument
->getDocumentElement();
608 if( xElement
->getNodeName() == "feed" )
610 OUString aXPathExpression
;
612 if( !extensionId
.isEmpty() )
613 aXPathExpression
= "//atom:entry/atom:category[@term=\'" + extensionId
+ "\']/..";
615 aXPathExpression
= "//atom:entry";
617 uno::Reference
< xml::dom::XNodeList
> xNodeList
;
619 xNodeList
= m_xXPathAPI
->selectNodeList(xDocument
.get(),
621 } catch (const xml::xpath::XPathException
&) {
625 return new UpdateInformationEnumeration(xNodeList
, this);
629 return new SingleUpdateInformationEnumeration(xElement
);
633 if( m_bCancelled
.check() )
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() )
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() ) )
688 // ignore files that can't be loaded
693 return comphelper::containerToSequence(aRet
);
698 UpdateInformationProvider::cancel()
702 osl::MutexGuard
aGuard(m_aMutex
);
703 if( m_xCommandProcessor
.is() )
704 m_xCommandProcessor
->abort(m_nCommandId
);
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
;
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(
736 catch ( uno::RuntimeException
const & )
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" };
757 UpdateInformationProvider::getImplName()
759 return OUString("vnd.sun.UpdateInformationProvider");
764 UpdateInformationProvider::getImplementationName()
766 return getImplName();
770 uno::Sequence
< OUString
> SAL_CALL
771 UpdateInformationProvider::getSupportedServiceNames()
773 return getServiceNames();
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
[] =
796 UpdateInformationProvider::getImplName
,
797 UpdateInformationProvider::getServiceNames
,
798 cppu::createSingleComponentFactory
,
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
,
812 kImplementations_entries
) ;
815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */