LibreOffice Module extensions (master) 1
updatefeed.cxx
Go to the documentation of this file.
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#include <sal/config.h>
21
22#include <string_view>
23
24#include <config_folders.h>
25
30#include <com/sun/star/beans/Property.hpp>
31#include <com/sun/star/beans/PropertyValue.hpp>
32#include <com/sun/star/beans/NamedValue.hpp>
33#include <com/sun/star/configuration/theDefaultProvider.hpp>
34#include <com/sun/star/container/XNameAccess.hpp>
35#include <com/sun/star/deployment/UpdateInformationEntry.hpp>
36#include <com/sun/star/deployment/XUpdateInformationProvider.hpp>
37#include <com/sun/star/io/XActiveDataSink.hpp>
38#include <com/sun/star/io/XInputStream.hpp>
39#include <com/sun/star/lang/XServiceInfo.hpp>
40#include <com/sun/star/ucb/CommandAbortedException.hpp>
41#include <com/sun/star/ucb/UniversalContentBroker.hpp>
42#include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
43#include <com/sun/star/ucb/XCommandProcessor2.hpp>
44#include <com/sun/star/ucb/OpenCommandArgument3.hpp>
45#include <com/sun/star/ucb/OpenMode.hpp>
46#include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
47#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
48#include <com/sun/star/xml/xpath/XPathAPI.hpp>
49#include <com/sun/star/xml/xpath/XPathException.hpp>
50#include <rtl/ref.hxx>
51#include <rtl/bootstrap.hxx>
52#include <rtl/ustrbuf.hxx>
53#include <sal/log.hxx>
54#include <osl/diagnose.h>
55#include <osl/conditn.hxx>
56#include <utility>
57#include <vcl/svapp.hxx>
58
59namespace beans = com::sun::star::beans ;
60namespace container = com::sun::star::container ;
62namespace io = com::sun::star::io ;
63namespace lang = com::sun::star::lang ;
64namespace task = com::sun::star::task ;
65namespace ucb = com::sun::star::ucb ;
66namespace uno = com::sun::star::uno ;
67namespace xml = com::sun::star::xml ;
68
69
70namespace
71{
72
73#ifdef DEBUG
74
75class InputStreamWrapper : public ::cppu::WeakImplHelper< io::XInputStream >
76{
77 uno::Reference< io::XInputStream > m_xStream;
78
79public:
80 explicit InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) :
81 m_xStream(rxStream) {};
82
83 virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
84 {
85 sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead);
86 return n;
87 };
88 virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
89 {
90 sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead);
91 return n;
92 };
93 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
94 { m_xStream->skipBytes(nBytesToSkip); };
95 virtual sal_Int32 SAL_CALL available()
96 { return m_xStream->available(); };
97 virtual void SAL_CALL closeInput( )
98 {};
99};
100
101#define INPUT_STREAM(i) new InputStreamWrapper(i)
102#else
103#define INPUT_STREAM(i) i
104#endif
105
106
107class ActiveDataSink : public ::cppu::WeakImplHelper< io::XActiveDataSink >
108{
109 uno::Reference< io::XInputStream > m_xStream;
110
111public:
112 ActiveDataSink() {};
113
114 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream() override { return m_xStream; };
115 virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream ) override { m_xStream = rStream; };
116};
117
118
119class UpdateInformationProvider :
120 public ::cppu::WeakImplHelper< deployment::XUpdateInformationProvider,
121 ucb::XWebDAVCommandEnvironment,
122 lang::XServiceInfo >
123{
124 OUString getUserAgent(bool bExtended);
125 bool isUserAgentExtended() const;
126public:
127 uno::Reference< xml::dom::XElement > getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode);
128 uno::Reference< xml::dom::XNode > getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, std::u16string_view rName);
129
130
131 // XUpdateInformationService
132 virtual uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
133 getUpdateInformation(
134 uno::Sequence< OUString > const & repositories,
135 OUString const & extensionId
136 ) override;
137
138 virtual void SAL_CALL cancel() override;
139
140 virtual void SAL_CALL setInteractionHandler(
141 uno::Reference< task::XInteractionHandler > const & handler ) override;
142
143 virtual uno::Reference< container::XEnumeration > SAL_CALL
144 getUpdateInformationEnumeration(
145 uno::Sequence< OUString > const & repositories,
146 OUString const & extensionId
147 ) override;
148
149 // XCommandEnvironment
150 virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
151
152 virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler() override { return uno::Reference< ucb::XProgressHandler >(); };
153
154 // XWebDAVCommandEnvironment
155 virtual uno::Sequence< beans::StringPair > SAL_CALL getUserRequestHeaders(
156 const OUString&, ucb::WebDAVHTTPMethod ) override;
157
158 // XServiceInfo
159 virtual OUString SAL_CALL getImplementationName() override;
160 virtual sal_Bool SAL_CALL supportsService(OUString const & serviceName) override;
161 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
162
163 UpdateInformationProvider(uno::Reference<uno::XComponentContext> xContext,
164 uno::Reference< ucb::XUniversalContentBroker > xUniversalContentBroker,
165 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder,
166 uno::Reference< xml::xpath::XXPathAPI > xXPathAPI);
167
168protected:
169
170 virtual ~UpdateInformationProvider() override;
171 static OUString getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item);
172 static uno::Any getConfigurationItemAny(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item);
173
174private:
175 uno::Reference< io::XInputStream > load(const OUString& rURL);
176
177 void storeCommandInfo( sal_Int32 nCommandId,
178 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor);
179
180 const uno::Reference< uno::XComponentContext> m_xContext;
181
182 const uno::Reference< ucb::XUniversalContentBroker > m_xUniversalContentBroker;
183 const uno::Reference< xml::dom::XDocumentBuilder > m_xDocumentBuilder;
184 const uno::Reference< xml::xpath::XXPathAPI > m_xXPathAPI;
185
186 uno::Sequence< beans::StringPair > m_aRequestHeaderList;
187
188 uno::Reference< ucb::XCommandProcessor > m_xCommandProcessor;
189 uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
190 uno::Reference< task::XInteractionHandler > m_xPwContainerInteractionHandler;
191
192 osl::Mutex m_aMutex;
193 osl::Condition m_bCancelled;
194
195 sal_Int32 m_nCommandId;
196};
197
198
199class UpdateInformationEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
200{
201public:
202 UpdateInformationEnumeration(const uno::Reference< xml::dom::XNodeList >& xNodeList,
203 rtl::Reference< UpdateInformationProvider > xUpdateInformationProvider) :
204 m_xUpdateInformationProvider(std::move(xUpdateInformationProvider)),
205 m_xNodeList(xNodeList),
206 m_nNodes(xNodeList.is() ? xNodeList->getLength() : 0),
207 m_nCount(0)
208 {
209 };
210
211 // XEnumeration
212 sal_Bool SAL_CALL hasMoreElements() override { return m_nCount < m_nNodes; };
213 uno::Any SAL_CALL nextElement() override
214 {
215 OSL_ASSERT( m_xNodeList.is() );
216 OSL_ASSERT( m_xUpdateInformationProvider.is() );
217
218 if( m_nCount >= m_nNodes )
219 throw container::NoSuchElementException(OUString::number(m_nCount), *this);
220
221 try
222 {
223 deployment::UpdateInformationEntry aEntry;
224
225 uno::Reference< xml::dom::XNode > xAtomEntryNode( m_xNodeList->item(m_nCount++) );
226
227 uno::Reference< xml::dom::XNode > xSummaryNode(
228 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, u"summary/text()" )
229 );
230
231 if( xSummaryNode.is() )
232 aEntry.Description = xSummaryNode->getNodeValue();
233
234 uno::Reference< xml::dom::XNode > xContentNode(
235 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, u"content" ) );
236
237 if( xContentNode.is() )
238 aEntry.UpdateDocument = m_xUpdateInformationProvider->getDocumentRoot(xContentNode);
239
240 return uno::Any(aEntry);
241 }
242 catch( ucb::CommandAbortedException const &)
243 {
244 // action has been aborted
245 css::uno::Any anyEx = cppu::getCaughtException();
246 throw lang::WrappedTargetException( "Command aborted", *this, anyEx );
247 }
248 catch( uno::RuntimeException const & )
249 {
250 // let runtime exception pass
251 throw;
252 }
253 catch( uno::Exception const &)
254 {
255 // document not accessible
256 css::uno::Any anyEx = cppu::getCaughtException();
257 throw lang::WrappedTargetException( "Document not accessible", *this, anyEx );
258 }
259 }
260
261private:
262 const rtl::Reference< UpdateInformationProvider > m_xUpdateInformationProvider;
263 const uno::Reference< xml::dom::XNodeList > m_xNodeList;
264 const sal_Int32 m_nNodes;
265 sal_Int32 m_nCount;
266};
267
268
269class SingleUpdateInformationEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
270{
271public:
272 explicit SingleUpdateInformationEnumeration(const uno::Reference< xml::dom::XElement >& xElement)
273 : m_nCount(0) { m_aEntry.UpdateDocument = xElement; };
274
275 // XEnumeration
276 sal_Bool SAL_CALL hasMoreElements() override { return 0 == m_nCount; };
277 uno::Any SAL_CALL nextElement() override
278 {
279 if( m_nCount > 0 )
280 throw container::NoSuchElementException(OUString::number(m_nCount), *this);
281
282 ++m_nCount;
283 return uno::Any(m_aEntry);
284 };
285
286private:
287 sal_Int32 m_nCount;
288 deployment::UpdateInformationEntry m_aEntry;
289};
290
291UpdateInformationProvider::UpdateInformationProvider(
292 uno::Reference<uno::XComponentContext> xContext,
293 uno::Reference< ucb::XUniversalContentBroker > xUniversalContentBroker,
294 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder,
295 uno::Reference< xml::xpath::XXPathAPI > xXPathAPI)
296 : m_xContext(std::move(xContext))
297 , m_xUniversalContentBroker(std::move(xUniversalContentBroker))
298 , m_xDocumentBuilder(std::move(xDocumentBuilder))
299 , m_xXPathAPI(std::move(xXPathAPI))
300 , m_aRequestHeaderList(2)
301 , m_nCommandId(0)
302{
303 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
304 css::configuration::theDefaultProvider::get(m_xContext));
305
306 auto pRequestHeaderList = m_aRequestHeaderList.getArray();
307 pRequestHeaderList[0].First = "Accept-Language";
308 pRequestHeaderList[0].Second = getConfigurationItem( xConfigurationProvider, "org.openoffice.Setup/L10N", "ooLocale" );
309}
310
311bool
312UpdateInformationProvider::isUserAgentExtended() const
313{
314 bool bExtendedUserAgent = false;
315 try {
316 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
317 css::configuration::theDefaultProvider::get(m_xContext));
318
319 uno::Any aExtended = getConfigurationItemAny(
320 xConfigurationProvider,
321 "org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments",
322 "ExtendedUserAgent");
323 aExtended >>= bExtendedUserAgent;
324 } catch (const uno::RuntimeException &) {
325 SAL_WARN("extensions.update", "Online update disabled");
326 }
327 return bExtendedUserAgent;
328}
329
330OUString UpdateInformationProvider::getUserAgent(bool bExtended)
331{
332 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
333 css::configuration::theDefaultProvider::get(m_xContext));
334
335 OUStringBuffer buf;
336 buf.append(
337 getConfigurationItem(
338 xConfigurationProvider,
339 "org.openoffice.Setup/Product",
340 "ooName"));
341 buf.append(' ');
342 buf.append(
343 getConfigurationItem(
344 xConfigurationProvider,
345 "org.openoffice.Setup/Product",
346 "ooSetupVersion"));
347
348 OUString extension(
349 getConfigurationItem(
350 xConfigurationProvider,
351 "org.openoffice.Setup/Product",
352 "ooSetupExtension"));
353 if (!extension.isEmpty())
354 buf.append(extension);
355
356 OUString product(buf.makeStringAndClear());
357
358 OUString aUserAgent( "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" );
359 OUString aExtended;
360 if( bExtended )
361 {
362 aExtended = Application::GetHWOSConfInfo();
363 }
364 rtl::Bootstrap::expandMacros( aUserAgent );
365 aUserAgent = aUserAgent.replaceAll("<PRODUCT>", product);
366 aUserAgent = aUserAgent.replaceAll("<OPTIONAL_OS_HW_DATA>", aExtended);
367 SAL_INFO("extensions.update", "UpdateUserAgent: " << aUserAgent);
368 // if you want to debug online updates from a dev version, then uncommenting this (adjust for platform)
369 // might be helpful
370 // return "LibreOffice 7.3.5.2 (184fe81b8c8c30d8b5082578aee2fed2ea847c01; Linux; X86_64; )";
371 return aUserAgent;
372}
373
374uno::Sequence< beans::StringPair > SAL_CALL UpdateInformationProvider::getUserRequestHeaders(
375 const OUString &aURL, ucb::WebDAVHTTPMethod )
376{
377 bool bExtendedUserAgent;
378 uno::Sequence< beans::StringPair > aPair = m_aRequestHeaderList;
379
380 // Internal use from cui/ some magic URLs
381 if( aURL.startsWith( "useragent:" ) )
382 bExtendedUserAgent = (aURL == "useragent:extended");
383 else
384 bExtendedUserAgent = isUserAgentExtended();
385
386 OUString aUserAgent = getUserAgent(bExtendedUserAgent);
387
388 if( aUserAgent.isEmpty() )
389 aPair.realloc(1);
390 else
391 {
392 auto pPair = aPair.getArray();
393 pPair[1].First = "User-Agent";
394 pPair[1].Second = aUserAgent;
395 }
396
397 return aPair;
398};
399
400UpdateInformationProvider::~UpdateInformationProvider()
401{
402}
403
405UpdateInformationProvider::getConfigurationItemAny(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item)
406{
407 beans::PropertyValue aProperty;
408 aProperty.Name = "nodepath";
409 aProperty.Value <<= node;
410
411 uno::Sequence< uno::Any > aArgumentList{ uno::Any(aProperty) };
412 uno::Reference< container::XNameAccess > xNameAccess(
413 configurationProvider->createInstanceWithArguments(
414 "com.sun.star.configuration.ConfigurationAccess",
415 aArgumentList ),
416 uno::UNO_QUERY_THROW);
417
418 return xNameAccess->getByName(item);
419}
420
421OUString
422UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item)
423{
424 OUString sRet;
425 getConfigurationItemAny(configurationProvider, node, item) >>= sRet;
426 return sRet;
427}
428
429void
430UpdateInformationProvider::storeCommandInfo(
431 sal_Int32 nCommandId,
432 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor)
433{
434 osl::MutexGuard aGuard(m_aMutex);
435
436 m_nCommandId = nCommandId;
437 m_xCommandProcessor = rxCommandProcessor;
438}
439
440uno::Reference< io::XInputStream >
441UpdateInformationProvider::load(const OUString& rURL)
442{
443 uno::Reference< ucb::XContentIdentifier > xId = m_xUniversalContentBroker->createContentIdentifier(rURL);
444
445 if( !xId.is() )
446 throw uno::RuntimeException(
447 "unable to obtain universal content id", *this);
448
449 uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xUniversalContentBroker->queryContent(xId), uno::UNO_QUERY_THROW);
450 rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink());
451
452 // Disable KeepAlive in webdav - don't want millions of office
453 // instances phone home & clog up servers
454 uno::Sequence< beans::NamedValue > aProps { { "KeepAlive", uno::Any(false) } };
455
456 ucb::OpenCommandArgument3 aOpenArgument;
457 aOpenArgument.Mode = ucb::OpenMode::DOCUMENT;
458 aOpenArgument.Priority = 32768;
459 aOpenArgument.Sink = *aSink;
460 aOpenArgument.OpeningFlags = aProps;
461
462 ucb::Command aCommand;
463 aCommand.Name = "open";
464 aCommand.Argument <<= aOpenArgument;
465
466 sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier();
467
468 storeCommandInfo(nCommandId, xCommandProcessor);
469 try
470 {
471 xCommandProcessor->execute(aCommand, nCommandId,
472 static_cast < XCommandEnvironment *> (this));
473 }
474 catch( const uno::Exception & /* e */ )
475 {
476 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
477
478 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
479 if( xCommandProcessor2.is() )
480 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
481
482 throw;
483 }
484 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
485
486 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
487 if( xCommandProcessor2.is() )
488 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
489
490 return INPUT_STREAM(aSink->getInputStream());
491}
492
493
494// TODO: docu content node
495
496uno::Reference< xml::dom::XElement >
497UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode)
498{
499 OSL_ASSERT(m_xDocumentBuilder.is());
500
501 uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW);
502
503 // load the document referenced in 'src' attribute ..
504 if( xElement->hasAttribute( "src" ) )
505 {
506 uno::Reference< xml::dom::XDocument > xUpdateXML =
507 m_xDocumentBuilder->parse(load(xElement->getAttribute( "src" )));
508
509 OSL_ASSERT( xUpdateXML.is() );
510
511 if( xUpdateXML.is() )
512 return xUpdateXML->getDocumentElement();
513 }
514 // .. or return the (single) child element
515 else
516 {
517 uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes();
518
519 // ignore possible #text nodes
520 sal_Int32 nmax = xChildNodes->getLength();
521 for(sal_Int32 n=0; n < nmax; n++)
522 {
523 uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY);
524 if( xChildElement.is() )
525 {
526 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList
527 * seems to evaluate expression always relative to the root node.
528 */
529 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument();
530 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement, true ) );
531 return xUpdateXML->getDocumentElement();
532 }
533 }
534 }
535
536 return uno::Reference< xml::dom::XElement > ();
537}
538
539
540uno::Reference< xml::dom::XNode >
541UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode,
542 std::u16string_view rName)
543{
544 OSL_ASSERT(m_xXPathAPI.is());
545 try {
546 return m_xXPathAPI->selectSingleNode(rxNode, OUString::Concat("./atom:") + rName);
547 } catch (const xml::xpath::XPathException &) {
548 // ignore
549 return nullptr;
550 }
551}
552
553
554uno::Reference< container::XEnumeration > SAL_CALL
555UpdateInformationProvider::getUpdateInformationEnumeration(
556 uno::Sequence< OUString > const & repositories,
557 OUString const & extensionId
558)
559{
560 OSL_ASSERT(m_xDocumentBuilder.is());
561
562 // reset cancelled flag
563 m_bCancelled.reset();
564
565 for(sal_Int32 n=0; n<repositories.getLength(); n++)
566 {
567 try
568 {
569 uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n]));
570 uno::Reference< xml::dom::XElement > xElement;
571
572 if( xDocument.is() )
573 xElement = xDocument->getDocumentElement();
574
575 if( xElement.is() )
576 {
577 if( xElement->getNodeName() == "feed" )
578 {
579 OUString aXPathExpression;
580
581 if( !extensionId.isEmpty() )
582 aXPathExpression = "//atom:entry/atom:category[@term=\'" + extensionId + "\']/..";
583 else
584 aXPathExpression = "//atom:entry";
585
586 uno::Reference< xml::dom::XNodeList > xNodeList;
587 try {
588 xNodeList = m_xXPathAPI->selectNodeList(xDocument,
589 aXPathExpression);
590 } catch (const xml::xpath::XPathException &) {
591 // ignore
592 }
593
594 return new UpdateInformationEnumeration(xNodeList, this);
595 }
596 else
597 {
598 return new SingleUpdateInformationEnumeration(xElement);
599 }
600 }
601
602 if( m_bCancelled.check() )
603 break;
604 }
605 catch( uno::RuntimeException const& /*e*/)
606 {
607 // #i118675# ignore runtime exceptions for now
608 // especially the "unsatisfied query for interface of
609 // type com.sun.star.ucb.XCommandProcessor!" exception
610 }
611
612 // rethrow only if last url in the list
613 catch( uno::Exception const & )
614 {
615 if( n+1 >= repositories.getLength() )
616 throw;
617 }
618 }
619
620 return uno::Reference< container::XEnumeration >();
621}
622
623
624uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
625UpdateInformationProvider::getUpdateInformation(
626 uno::Sequence< OUString > const & repositories,
627 OUString const & extensionId
628)
629{
630 uno::Reference< container::XEnumeration > xEnumeration(
631 getUpdateInformationEnumeration(repositories, extensionId)
632 );
633
634 std::vector< uno::Reference< xml::dom::XElement > > aRet;
635
636 if( xEnumeration.is() )
637 {
638 while( xEnumeration->hasMoreElements() )
639 {
640 try
641 {
642 deployment::UpdateInformationEntry aEntry;
643 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() )
644 {
645 aRet.push_back(aEntry.UpdateDocument);
646 }
647 }
648
649 catch( const lang::WrappedTargetException& e )
650 {
651 // command aborted, return what we have got so far
652 if( e.TargetException.isExtractableTo( ::cppu::UnoType< css::ucb::CommandAbortedException >::get() ) )
653 {
654 break;
655 }
656
657 // ignore files that can't be loaded
658 }
659 }
660 }
661
663}
664
665
666void SAL_CALL
667UpdateInformationProvider::cancel()
668{
669 m_bCancelled.set();
670
671 osl::MutexGuard aGuard(m_aMutex);
672 if( m_xCommandProcessor.is() )
673 m_xCommandProcessor->abort(m_nCommandId);
674}
675
676
677void SAL_CALL
678UpdateInformationProvider::setInteractionHandler(
679 uno::Reference< task::XInteractionHandler > const & handler )
680{
681 osl::MutexGuard aGuard(m_aMutex);
682 m_xInteractionHandler = handler;
683}
684
685
686uno::Reference< task::XInteractionHandler > SAL_CALL
687UpdateInformationProvider::getInteractionHandler()
688{
689 osl::MutexGuard aGuard( m_aMutex );
690
691 if ( m_xInteractionHandler.is() )
693 else
694 {
695 try
696 {
697 // Supply an interaction handler that uses the password container
698 // service to obtain credentials without displaying a password gui.
699
700 if ( !m_xPwContainerInteractionHandler.is() )
701 m_xPwContainerInteractionHandler
702 = task::PasswordContainerInteractionHandler::create(
703 m_xContext );
704 }
705 catch ( uno::RuntimeException const & )
706 {
707 throw;
708 }
709 catch ( uno::Exception const & )
710 {
711 }
712 return m_xPwContainerInteractionHandler;
713 }
714}
715
716
717
718OUString SAL_CALL
719UpdateInformationProvider::getImplementationName()
720{
721 return "vnd.sun.UpdateInformationProvider";
722}
723
724
725uno::Sequence< OUString > SAL_CALL
726UpdateInformationProvider::getSupportedServiceNames()
727{
728 return { "com.sun.star.deployment.UpdateInformationProvider" };
729}
730
731sal_Bool SAL_CALL
732UpdateInformationProvider::supportsService( OUString const & serviceName )
733{
734 return cppu::supportsService(this, serviceName);
735}
736
737} // anonymous namespace
738
739extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
741 css::uno::XComponentContext* xContext , css::uno::Sequence<css::uno::Any> const&)
742{
743 uno::Reference< ucb::XUniversalContentBroker > xUniversalContentBroker =
744 ucb::UniversalContentBroker::create(xContext);
745
746 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder(
747 xml::dom::DocumentBuilder::create(xContext));
748
749 uno::Reference< xml::xpath::XXPathAPI > xXPath = xml::xpath::XPathAPI::create( xContext );
750
751 xXPath->registerNS( "atom", "http://www.w3.org/2005/Atom" );
752
753 return cppu::acquire(
754 new UpdateInformationProvider(xContext, xUniversalContentBroker, xDocumentBuilder, xXPath));
755}
756
757
758/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OUString GetHWOSConfInfo(const int bSelection=0, bool bLocalize=true)
#define SAL_CONFIGFILE(name)
Reference< XInteractionHandler2 > m_xInteractionHandler
URL aURL
Reference< XComponentContext > m_xContext
Definition: filehandler.cxx:78
sal_Int64 n
sal_Int16 m_nCount
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
::osl::Mutex m_aMutex
Definition: logger.cxx:98
double getLength(const B2DPolygon &rCandidate)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
Object Value
OUString aCommand
unsigned char sal_Bool
Reference< XStream > m_xStream
#define INPUT_STREAM(i)
Definition: updatefeed.cxx:101
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * extensions_update_UpdateInformationProvider_get_implementation(css::uno::XComponentContext *xContext, css::uno::Sequence< css::uno::Any > const &)
Definition: updatefeed.cxx:740