Bump for 3.6-28
[LibreOffice.git] / extensions / source / update / feed / updatefeed.cxx
blobae69e7c177c8f40a20b014f1b98f6567bb3f7381
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <cppuhelper/implbase1.hxx>
31 #include <cppuhelper/implbase4.hxx>
32 #include <cppuhelper/implementationentry.hxx>
33 #include <com/sun/star/beans/Property.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/configuration/theDefaultProvider.hpp>
38 #include <com/sun/star/container/XNameAccess.hpp>
39 #include <com/sun/star/deployment/UpdateInformationEntry.hpp>
40 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
41 #include <com/sun/star/io/XActiveDataSink.hpp>
42 #include <com/sun/star/io/XInputStream.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
44 #include <com/sun/star/lang/XServiceInfo.hpp>
45 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
46 #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
47 #include <com/sun/star/ucb/XCommandProcessor2.hpp>
48 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
49 #include <com/sun/star/ucb/XContentProvider.hpp>
50 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
51 #include <com/sun/star/ucb/OpenCommandArgument3.hpp>
52 #include <com/sun/star/ucb/OpenMode.hpp>
53 #include <com/sun/star/sdbc/XRow.hpp>
54 #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
55 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
56 #include <com/sun/star/xml/xpath/XXPathAPI.hpp>
58 #include <rtl/ref.hxx>
59 #include <rtl/memory.h>
60 #include <rtl/bootstrap.hxx>
61 #include <rtl/ustrbuf.hxx>
62 #include <osl/process.h>
63 #include <osl/conditn.hxx>
65 namespace beans = com::sun::star::beans ;
66 namespace container = com::sun::star::container ;
67 namespace deployment = com::sun::star::deployment ;
68 namespace io = com::sun::star::io ;
69 namespace lang = com::sun::star::lang ;
70 namespace task = com::sun::star::task ;
71 namespace ucb = com::sun::star::ucb ;
72 namespace uno = com::sun::star::uno ;
73 namespace xml = com::sun::star::xml ;
74 namespace sdbc = com::sun::star::sdbc ;
76 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
78 //------------------------------------------------------------------------------
80 namespace
83 #ifdef DEBUG
85 class InputStreamWrapper : public ::cppu::WeakImplHelper1< io::XInputStream >
87 uno::Reference< io::XInputStream > m_xStream;
89 public:
90 InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) :
91 m_xStream(rxStream) {};
93 virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
94 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
96 sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead);
97 if ( n )
98 OSL_TRACE( "Read [%d] bytes: %s", n, aData.get()->elements );
99 return n;
101 virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
102 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
104 sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead);
105 if ( n )
106 OSL_TRACE( "Read [%d] bytes: %s", n, aData.get()->elements );
107 return n;
109 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
110 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
111 { m_xStream->skipBytes(nBytesToSkip); };
112 virtual sal_Int32 SAL_CALL available()
113 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
114 { return m_xStream->available(); };
115 virtual void SAL_CALL closeInput( )
116 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
120 #define INPUT_STREAM(i) new InputStreamWrapper(i)
121 #else
122 #define INPUT_STREAM(i) i
123 #endif
125 //------------------------------------------------------------------------------
127 class ActiveDataSink : public ::cppu::WeakImplHelper1< io::XActiveDataSink >
129 uno::Reference< io::XInputStream > m_xStream;
131 public:
132 ActiveDataSink() {};
134 inline operator uno::Reference< io::XActiveDataSink > () { return this; };
136 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
137 throw (uno::RuntimeException) { return m_xStream; };
138 virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream )
139 throw (uno::RuntimeException) { m_xStream = rStream; };
142 //------------------------------------------------------------------------------
144 class UpdateInformationProvider :
145 public ::cppu::WeakImplHelper4< deployment::XUpdateInformationProvider,
146 ucb::XCommandEnvironment,
147 ucb::XWebDAVCommandEnvironment,
148 lang::XServiceInfo >
150 public:
151 static uno::Reference< uno::XInterface > createInstance(const uno::Reference<uno::XComponentContext>& xContext);
153 static uno::Sequence< rtl::OUString > getServiceNames();
154 static rtl::OUString getImplName();
156 uno::Reference< xml::dom::XElement > getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode);
157 uno::Reference< xml::dom::XNode > getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, const rtl::OUString& rName);
160 // XUpdateInformationService
161 virtual uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
162 getUpdateInformation(
163 uno::Sequence< rtl::OUString > const & repositories,
164 rtl::OUString const & extensionId
165 ) throw (uno::Exception, uno::RuntimeException);
167 virtual void SAL_CALL cancel()
168 throw (uno::RuntimeException);
170 virtual void SAL_CALL setInteractionHandler(
171 uno::Reference< task::XInteractionHandler > const & handler )
172 throw (uno::RuntimeException);
174 virtual uno::Reference< container::XEnumeration > SAL_CALL
175 getUpdateInformationEnumeration(
176 uno::Sequence< rtl::OUString > const & repositories,
177 rtl::OUString const & extensionId
178 ) throw (uno::Exception, uno::RuntimeException);
180 // XCommandEnvironment
181 virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
182 throw ( uno::RuntimeException );
184 virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
185 throw ( uno::RuntimeException ) { return uno::Reference< ucb::XProgressHandler >(); };
187 // XWebDAVCommandEnvironment
188 virtual uno::Sequence< beans::NamedValue > SAL_CALL getUserRequestHeaders(
189 const rtl::OUString&, const rtl::OUString& )
190 throw ( uno::RuntimeException ) { return m_aRequestHeaderList; };
192 // XServiceInfo
193 virtual rtl::OUString SAL_CALL getImplementationName()
194 throw (uno::RuntimeException);
195 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
196 throw (uno::RuntimeException);
197 virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
198 throw (uno::RuntimeException);
200 protected:
202 virtual ~UpdateInformationProvider();
203 static uno::Any getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item);
205 private:
206 uno::Reference< io::XInputStream > load(const rtl::OUString& rURL);
208 void storeCommandInfo( sal_Int32 nCommandId,
209 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor);
211 UpdateInformationProvider(const uno::Reference<uno::XComponentContext>& xContext,
212 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory,
213 const uno::Reference< ucb::XContentProvider >& xContentProvider,
214 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
215 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI);
217 const uno::Reference< uno::XComponentContext> m_xContext;
219 const uno::Reference< ucb::XContentIdentifierFactory > m_xContentIdFactory;
220 const uno::Reference< ucb::XContentProvider > m_xContentProvider;
221 const uno::Reference< xml::dom::XDocumentBuilder > m_xDocumentBuilder;
222 const uno::Reference< xml::xpath::XXPathAPI > m_xXPathAPI;
224 uno::Sequence< beans::NamedValue > m_aRequestHeaderList;
226 uno::Reference< ucb::XCommandProcessor > m_xCommandProcessor;
227 uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
228 uno::Reference< task::XInteractionHandler > m_xPwContainerInteractionHandler;
230 osl::Mutex m_aMutex;
231 osl::Condition m_bCancelled;
233 sal_Int32 m_nCommandId;
236 //------------------------------------------------------------------------------
238 class UpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
240 public:
241 UpdateInformationEnumeration(const uno::Reference< xml::dom::XNodeList >& xNodeList,
242 const uno::Reference< UpdateInformationProvider > xUpdateInformationProvider) :
243 m_xUpdateInformationProvider(xUpdateInformationProvider),
244 m_xNodeList(xNodeList),
245 m_nNodes(xNodeList.is() ? xNodeList->getLength() : 0),
246 m_nCount(0)
250 virtual ~UpdateInformationEnumeration() {};
252 // XEnumeration
253 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return m_nCount < m_nNodes; };
254 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
256 OSL_ASSERT( m_xNodeList.is() );
257 OSL_ASSERT( m_xUpdateInformationProvider.is() );
259 if( !(m_nCount < m_nNodes ) )
260 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this);
264 deployment::UpdateInformationEntry aEntry;
266 uno::Reference< xml::dom::XNode > xAtomEntryNode( m_xNodeList->item(m_nCount++) );
268 uno::Reference< xml::dom::XNode > xSummaryNode(
269 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "summary/text()" ) )
272 if( xSummaryNode.is() )
273 aEntry.Description = xSummaryNode->getNodeValue();
275 uno::Reference< xml::dom::XNode > xContentNode(
276 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "content" ) ) );
278 if( xContentNode.is() )
279 aEntry.UpdateDocument = m_xUpdateInformationProvider->getDocumentRoot(xContentNode);
281 return uno::makeAny(aEntry);
284 // action has been aborted
285 catch( ucb::CommandAbortedException const & e)
286 { throw lang::WrappedTargetException( UNISTRING( "Command aborted" ), *this, uno::makeAny(e) ); }
288 // let runtime exception pass
289 catch( uno::RuntimeException const & ) { throw; }
291 // document not accessible
292 catch( uno::Exception const & e)
293 { throw lang::WrappedTargetException( UNISTRING( "Document not accessible" ), *this, uno::makeAny(e) ); }
296 private:
297 const uno::Reference< UpdateInformationProvider > m_xUpdateInformationProvider;
298 const uno::Reference< xml::dom::XNodeList > m_xNodeList;
299 const sal_Int32 m_nNodes;
300 sal_Int32 m_nCount;
303 //------------------------------------------------------------------------------
305 class SingleUpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
307 public:
308 SingleUpdateInformationEnumeration(const uno::Reference< xml::dom::XElement >& xElement)
309 : m_nCount(0) { m_aEntry.UpdateDocument = xElement; };
310 virtual ~SingleUpdateInformationEnumeration() {};
312 // XEnumeration
313 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return 0 == m_nCount; };
314 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
316 if( m_nCount > 0 )
317 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this);
319 ++m_nCount;
320 return uno::makeAny(m_aEntry);
323 private:
324 sal_uInt8 m_nCount;
325 deployment::UpdateInformationEntry m_aEntry;
329 //------------------------------------------------------------------------------
331 UpdateInformationProvider::UpdateInformationProvider(
332 const uno::Reference<uno::XComponentContext>& xContext,
333 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory,
334 const uno::Reference< ucb::XContentProvider >& xContentProvider,
335 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
336 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI
337 ) : m_xContext(xContext), m_xContentIdFactory(xContentIdFactory),
338 m_xContentProvider(xContentProvider), m_xDocumentBuilder(xDocumentBuilder),
339 m_xXPathAPI(xXPathAPI), m_aRequestHeaderList(1)
341 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
342 com::sun::star::configuration::theDefaultProvider::get(xContext));
344 rtl::OUStringBuffer buf;
345 rtl::OUString name;
346 getConfigurationItem(
347 xConfigurationProvider,
348 UNISTRING("org.openoffice.Setup/Product"),
349 UNISTRING("ooName")) >>= name;
350 buf.append(name);
351 buf.append(sal_Unicode(' '));
352 rtl::OUString version;
353 getConfigurationItem(
354 xConfigurationProvider,
355 UNISTRING("org.openoffice.Setup/Product"),
356 UNISTRING("ooSetupVersion")) >>= version;
357 buf.append(version);
358 rtl::OUString edition(
359 UNISTRING(
360 "${${BRAND_BASE_DIR}/program/edition/edition.ini:"
361 "EDITIONNAME}"));
362 rtl::Bootstrap::expandMacros(edition);
363 if (!edition.isEmpty()) {
364 buf.append(sal_Unicode(' '));
365 buf.append(edition);
367 rtl::OUString extension;
368 getConfigurationItem(
369 xConfigurationProvider,
370 UNISTRING("org.openoffice.Setup/Product"),
371 UNISTRING("ooSetupExtension")) >>= extension;
372 if (!extension.isEmpty()) {
373 buf.append(sal_Unicode(' '));
374 buf.append(extension);
376 rtl::OUString product(buf.makeStringAndClear());
378 rtl::OUString aUserAgent( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" ) );
379 rtl::Bootstrap::expandMacros( aUserAgent );
381 for (sal_Int32 i = 0;;) {
382 i = aUserAgent.indexOfAsciiL(
383 RTL_CONSTASCII_STRINGPARAM("<PRODUCT>"), i);
384 if (i == -1) {
385 break;
387 aUserAgent = aUserAgent.replaceAt(
388 i, RTL_CONSTASCII_LENGTH("<PRODUCT>"), product);
389 i += product.getLength();
392 m_aRequestHeaderList[0].Name = UNISTRING("Accept-Language");
393 m_aRequestHeaderList[0].Value = getConfigurationItem( xConfigurationProvider, UNISTRING("org.openoffice.Setup/L10N"), UNISTRING("ooLocale") );
394 if( !aUserAgent.isEmpty() )
396 m_aRequestHeaderList.realloc(2);
397 m_aRequestHeaderList[1].Name = UNISTRING("User-Agent");
398 m_aRequestHeaderList[1].Value = uno::makeAny(aUserAgent);
402 //------------------------------------------------------------------------------
403 uno::Reference< uno::XInterface >
404 UpdateInformationProvider::createInstance(const uno::Reference<uno::XComponentContext>& xContext)
406 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
407 if( !xServiceManager.is() )
408 throw uno::RuntimeException(
409 UNISTRING( "unable to obtain service manager from component context" ),
410 uno::Reference< uno::XInterface > ());
412 uno::Reference< ucb::XContentIdentifierFactory > xContentIdFactory(
413 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.ucb.UniversalContentBroker" ), xContext ),
414 uno::UNO_QUERY_THROW);
416 uno::Reference< ucb::XContentProvider > xContentProvider(xContentIdFactory, uno::UNO_QUERY_THROW);
418 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder(
419 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.dom.DocumentBuilder" ), xContext ),
420 uno::UNO_QUERY_THROW);
422 uno::Reference< xml::xpath::XXPathAPI > xXPath(
423 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), xContext ),
424 uno::UNO_QUERY_THROW);
426 xXPath->registerNS( UNISTRING("atom"), UNISTRING("http://www.w3.org/2005/Atom") );
428 return *new UpdateInformationProvider(xContext, xContentIdFactory, xContentProvider, xDocumentBuilder, xXPath);
431 //------------------------------------------------------------------------------
433 UpdateInformationProvider::~UpdateInformationProvider()
437 //------------------------------------------------------------------------------
439 uno::Any
440 UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item)
442 beans::NamedValue aProperty;
443 aProperty.Name = UNISTRING("nodepath");
444 aProperty.Value = uno::makeAny(node);
446 uno::Sequence< uno::Any > aArgumentList( 1 );
447 aArgumentList[0] = uno::makeAny( aProperty );
449 uno::Reference< container::XNameAccess > xNameAccess(
450 configurationProvider->createInstanceWithArguments(
451 UNISTRING("com.sun.star.configuration.ConfigurationAccess"),
452 aArgumentList ),
453 uno::UNO_QUERY_THROW);
455 return xNameAccess->getByName(item);
458 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
473 uno::Reference< io::XInputStream >
474 UpdateInformationProvider::load(const rtl::OUString& rURL)
476 uno::Reference< ucb::XContentIdentifier > xId = m_xContentIdFactory->createContentIdentifier(rURL);
478 if( !xId.is() )
479 throw uno::RuntimeException(
480 UNISTRING( "unable to obtain universal content id" ), *this);
482 uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xContentProvider->queryContent(xId), uno::UNO_QUERY_THROW);
483 rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink());
485 // Disable KeepAlive in webdav - don't want millions of office
486 // instances phone home & clog up servers
487 uno::Sequence< beans::NamedValue > aProps( 1 );
488 aProps[ 0 ] = beans::NamedValue(
489 UNISTRING("KeepAlive"), uno::makeAny(sal_False));
491 ucb::OpenCommandArgument3 aOpenArgument;
492 aOpenArgument.Mode = ucb::OpenMode::DOCUMENT;
493 aOpenArgument.Priority = 32768;
494 aOpenArgument.Sink = *aSink;
495 aOpenArgument.OpeningFlags = aProps;
497 ucb::Command aCommand;
498 aCommand.Name = UNISTRING("open");
499 aCommand.Argument = uno::makeAny(aOpenArgument);
501 sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier();
503 storeCommandInfo(nCommandId, xCommandProcessor);
506 uno::Any aResult = xCommandProcessor->execute(aCommand, nCommandId,
507 static_cast < XCommandEnvironment *> (this));
509 catch( const uno::Exception & /* e */ )
511 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
513 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
514 if( xCommandProcessor2.is() )
515 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
517 throw;
519 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
521 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
522 if( xCommandProcessor2.is() )
523 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
525 return INPUT_STREAM(aSink->getInputStream());
528 //------------------------------------------------------------------------------
530 // TODO: docu content node
532 uno::Reference< xml::dom::XElement >
533 UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode)
535 OSL_ASSERT(m_xDocumentBuilder.is());
537 uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW);
539 // load the document referenced in 'src' attribute ..
540 if( xElement->hasAttribute( UNISTRING("src") ) )
542 uno::Reference< xml::dom::XDocument > xUpdateXML =
543 m_xDocumentBuilder->parse(load(xElement->getAttribute( UNISTRING("src") )));
545 OSL_ASSERT( xUpdateXML.is() );
547 if( xUpdateXML.is() )
548 return xUpdateXML->getDocumentElement();
550 // .. or return the (single) child element
551 else
553 uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes();
555 // ignore possible #text nodes
556 sal_Int32 nmax = xChildNodes->getLength();
557 for(sal_Int32 n=0; n < nmax; n++)
559 uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY);
560 if( xChildElement.is() )
562 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList
563 * seems to evaluate expression always relative to the root node.
565 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument();
566 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement.get(), sal_True ) );
567 return xUpdateXML->getDocumentElement();
572 return uno::Reference< xml::dom::XElement > ();
575 //------------------------------------------------------------------------------
577 uno::Reference< xml::dom::XNode >
578 UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode,
579 const rtl::OUString& rName)
581 OSL_ASSERT(m_xXPathAPI.is());
582 try {
583 return m_xXPathAPI->selectSingleNode(rxNode, UNISTRING( "./atom:" ) + rName);
584 } catch (const xml::xpath::XPathException &) {
585 // ignore
586 return 0;
590 //------------------------------------------------------------------------------
592 uno::Reference< container::XEnumeration > SAL_CALL
593 UpdateInformationProvider::getUpdateInformationEnumeration(
594 uno::Sequence< rtl::OUString > const & repositories,
595 rtl::OUString const & extensionId
596 ) throw (uno::Exception, uno::RuntimeException)
598 OSL_ASSERT(m_xDocumentBuilder.is());
600 // reset cancelled flag
601 m_bCancelled.reset();
603 for(sal_Int32 n=0; n<repositories.getLength(); n++)
607 uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n]));
608 uno::Reference< xml::dom::XElement > xElement;
610 if( xDocument.is() )
611 xElement = xDocument->getDocumentElement();
613 if( xElement.is() )
615 if( xElement->getNodeName().equalsAsciiL("feed", 4) )
617 rtl::OUString aXPathExpression;
619 if( !extensionId.isEmpty() )
620 aXPathExpression = UNISTRING("//atom:entry/atom:category[@term=\'") + extensionId + UNISTRING("\']/..");
621 else
622 aXPathExpression = UNISTRING("//atom:entry");
624 uno::Reference< xml::dom::XNodeList > xNodeList;
625 try {
626 xNodeList = m_xXPathAPI->selectNodeList(xDocument.get(),
627 aXPathExpression);
628 } catch (const xml::xpath::XPathException &) {
629 // ignore
632 return new UpdateInformationEnumeration(xNodeList, this);
634 else
636 return new SingleUpdateInformationEnumeration(xElement);
640 if( m_bCancelled.check() )
641 break;
643 // rethrow runtime exceptions
644 catch( uno::RuntimeException const & ) { throw; }
646 // rethrow only if last url in the list
647 catch( uno::Exception const & )
649 if( n+1 >= repositories.getLength() )
650 throw;
654 return uno::Reference< container::XEnumeration >();
657 //------------------------------------------------------------------------------
659 uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
660 UpdateInformationProvider::getUpdateInformation(
661 uno::Sequence< rtl::OUString > const & repositories,
662 rtl::OUString const & extensionId
663 ) throw (uno::Exception, uno::RuntimeException)
665 uno::Reference< container::XEnumeration > xEnumeration(
666 getUpdateInformationEnumeration(repositories, extensionId)
669 uno::Sequence< uno::Reference< xml::dom::XElement > > aRet;
671 if( xEnumeration.is() )
673 while( xEnumeration->hasMoreElements() )
677 deployment::UpdateInformationEntry aEntry;
678 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() )
680 sal_Int32 n = aRet.getLength();
681 aRet.realloc(n + 1);
682 aRet[n] = aEntry.UpdateDocument;
686 catch( const lang::WrappedTargetException& e )
688 // command aborted, return what we have got so far
689 if( e.TargetException.isExtractableTo( ::cppu::UnoType< ::com::sun::star::ucb::CommandAbortedException >::get() ) )
691 break;
694 // ignore files that can't be loaded
699 return aRet;
702 //------------------------------------------------------------------------------
704 void SAL_CALL
705 UpdateInformationProvider::cancel() throw (uno::RuntimeException)
707 m_bCancelled.set();
709 osl::MutexGuard aGuard(m_aMutex);
710 if( m_xCommandProcessor.is() )
711 m_xCommandProcessor->abort(m_nCommandId);
714 //------------------------------------------------------------------------------
716 void SAL_CALL
717 UpdateInformationProvider::setInteractionHandler(
718 uno::Reference< task::XInteractionHandler > const & handler )
719 throw (uno::RuntimeException)
721 osl::MutexGuard aGuard(m_aMutex);
722 m_xInteractionHandler = handler;
725 //------------------------------------------------------------------------------
727 uno::Reference< task::XInteractionHandler > SAL_CALL
728 UpdateInformationProvider::getInteractionHandler()
729 throw ( uno::RuntimeException )
731 osl::MutexGuard aGuard( m_aMutex );
733 if ( m_xInteractionHandler.is() )
734 return m_xInteractionHandler;
735 else
739 // Supply an interaction handler that uses the password container
740 // service to obtain credentials without displaying a password gui.
742 if ( !m_xPwContainerInteractionHandler.is() )
743 m_xPwContainerInteractionHandler
744 = task::PasswordContainerInteractionHandler::create(
745 m_xContext );
747 catch ( uno::RuntimeException const & )
749 throw;
751 catch ( uno::Exception const & )
754 return m_xPwContainerInteractionHandler;
757 //------------------------------------------------------------------------------
759 uno::Sequence< rtl::OUString >
760 UpdateInformationProvider::getServiceNames()
762 uno::Sequence< rtl::OUString > aServiceList(1);
763 aServiceList[0] = UNISTRING( "com.sun.star.deployment.UpdateInformationProvider");
764 return aServiceList;
767 //------------------------------------------------------------------------------
769 rtl::OUString
770 UpdateInformationProvider::getImplName()
772 return UNISTRING( "vnd.sun.UpdateInformationProvider");
775 //------------------------------------------------------------------------------
777 rtl::OUString SAL_CALL
778 UpdateInformationProvider::getImplementationName() throw (uno::RuntimeException)
780 return getImplName();
783 //------------------------------------------------------------------------------
785 uno::Sequence< rtl::OUString > SAL_CALL
786 UpdateInformationProvider::getSupportedServiceNames() throw (uno::RuntimeException)
788 return getServiceNames();
791 //------------------------------------------------------------------------------
793 sal_Bool SAL_CALL
794 UpdateInformationProvider::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException)
796 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
798 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
799 if( aServiceNameList[n].equals(serviceName) )
800 return sal_True;
802 return sal_False;
805 } // anonymous namespace
807 //------------------------------------------------------------------------------
809 static uno::Reference<uno::XInterface> SAL_CALL
810 createInstance(uno::Reference<uno::XComponentContext> const & xContext)
812 return UpdateInformationProvider::createInstance(xContext);
815 //------------------------------------------------------------------------------
817 static const cppu::ImplementationEntry kImplementations_entries[] =
820 createInstance,
821 UpdateInformationProvider::getImplName,
822 UpdateInformationProvider::getServiceNames,
823 cppu::createSingleComponentFactory,
824 NULL,
827 { NULL, NULL, NULL, NULL, NULL, 0 }
830 //------------------------------------------------------------------------------
832 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
834 return cppu::component_getFactoryHelper(
835 pszImplementationName,
836 pServiceManager,
837 pRegistryKey,
838 kImplementations_entries) ;
841 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */