merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / update / feed / updatefeed.cxx
blobe5eb490e29a265423204a5107753292b6a25a803
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include <cppuhelper/implbase1.hxx>
32 #include <cppuhelper/implbase4.hxx>
33 #include <cppuhelper/implementationentry.hxx>
34 #include <com/sun/star/beans/Property.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include <com/sun/star/deployment/UpdateInformationEntry.hpp>
39 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
40 #include <com/sun/star/io/XActiveDataSink.hpp>
41 #include <com/sun/star/io/XInputStream.hpp>
42 #include <com/sun/star/lang/XComponent.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
45 #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
46 #include <com/sun/star/ucb/XCommandProcessor2.hpp>
47 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
48 #include <com/sun/star/ucb/XContentProvider.hpp>
49 #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
50 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
51 #include <com/sun/star/ucb/OpenMode.hpp>
52 #include <com/sun/star/sdbc/XRow.hpp>
53 #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
54 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
55 #include <com/sun/star/xml/xpath/XXPathAPI.hpp>
57 #include <rtl/ref.hxx>
58 #include <rtl/memory.h>
59 #include <rtl/bootstrap.hxx>
60 #include <rtl/ustrbuf.hxx>
61 #include <osl/process.h>
62 #include <osl/conditn.hxx>
64 namespace beans = com::sun::star::beans ;
65 namespace container = com::sun::star::container ;
66 namespace deployment = com::sun::star::deployment ;
67 namespace io = com::sun::star::io ;
68 namespace lang = com::sun::star::lang ;
69 namespace task = com::sun::star::task ;
70 namespace ucb = com::sun::star::ucb ;
71 namespace uno = com::sun::star::uno ;
72 namespace xml = com::sun::star::xml ;
73 namespace sdbc = com::sun::star::sdbc ;
75 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
77 //------------------------------------------------------------------------------
79 namespace
82 #ifdef DEBUG
84 class InputStreamWrapper : public ::cppu::WeakImplHelper1< io::XInputStream >
86 uno::Reference< io::XInputStream > m_xStream;
88 public:
89 InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) :
90 m_xStream(rxStream) {};
92 virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
93 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
95 sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead);
96 if ( n )
97 OSL_TRACE( "Read [%d] bytes: %s\n", n, aData.get()->elements );
98 return n;
100 virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
101 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
103 sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead);
104 if ( n )
105 OSL_TRACE( "Read [%d] bytes: %s\n", n, aData.get()->elements );
106 return n;
108 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
109 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
110 { m_xStream->skipBytes(nBytesToSkip); };
111 virtual sal_Int32 SAL_CALL available()
112 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
113 { return m_xStream->available(); };
114 virtual void SAL_CALL closeInput( )
115 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
119 #define INPUT_STREAM(i) new InputStreamWrapper(i)
120 #else
121 #define INPUT_STREAM(i) i
122 #endif
124 //------------------------------------------------------------------------------
126 class ActiveDataSink : public ::cppu::WeakImplHelper1< io::XActiveDataSink >
128 uno::Reference< io::XInputStream > m_xStream;
130 public:
131 ActiveDataSink() {};
133 inline operator uno::Reference< io::XActiveDataSink > () { return this; };
135 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
136 throw (uno::RuntimeException) { return m_xStream; };
137 virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream )
138 throw (uno::RuntimeException) { m_xStream = rStream; };
141 //------------------------------------------------------------------------------
143 class UpdateInformationProvider :
144 public ::cppu::WeakImplHelper4< deployment::XUpdateInformationProvider,
145 ucb::XCommandEnvironment,
146 ucb::XWebDAVCommandEnvironment,
147 lang::XServiceInfo >
149 public:
150 static uno::Reference< uno::XInterface > createInstance(const uno::Reference<uno::XComponentContext>& xContext);
152 static uno::Sequence< rtl::OUString > getServiceNames();
153 static rtl::OUString getImplName();
155 uno::Reference< xml::dom::XElement > getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode);
156 uno::Reference< xml::dom::XNode > getChildNode(const uno::Reference< xml::dom::XNode >& rxNode, const rtl::OUString& rName);
159 // XUpdateInformationService
160 virtual uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
161 getUpdateInformation(
162 uno::Sequence< rtl::OUString > const & repositories,
163 rtl::OUString const & extensionId
164 ) throw (uno::Exception, uno::RuntimeException);
166 virtual void SAL_CALL cancel()
167 throw (uno::RuntimeException);
169 virtual void SAL_CALL setInteractionHandler(
170 uno::Reference< task::XInteractionHandler > const & handler )
171 throw (uno::RuntimeException);
173 virtual uno::Reference< container::XEnumeration > SAL_CALL
174 getUpdateInformationEnumeration(
175 uno::Sequence< rtl::OUString > const & repositories,
176 rtl::OUString const & extensionId
177 ) throw (uno::Exception, uno::RuntimeException);
179 // XCommandEnvironment
180 virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
181 throw ( uno::RuntimeException );
183 virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
184 throw ( uno::RuntimeException ) { return uno::Reference< ucb::XProgressHandler >(); };
186 // XWebDAVCommandEnvironment
187 virtual uno::Sequence< beans::NamedValue > SAL_CALL getUserRequestHeaders(
188 const rtl::OUString&, const rtl::OUString& )
189 throw ( uno::RuntimeException ) { return m_aRequestHeaderList; };
191 // XServiceInfo
192 virtual rtl::OUString SAL_CALL getImplementationName()
193 throw (uno::RuntimeException);
194 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
195 throw (uno::RuntimeException);
196 virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
197 throw (uno::RuntimeException);
199 protected:
201 virtual ~UpdateInformationProvider();
202 static uno::Any getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item);
204 private:
205 uno::Reference< io::XInputStream > load(const rtl::OUString& rURL);
207 void storeCommandInfo( sal_Int32 nCommandId,
208 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor);
210 UpdateInformationProvider(const uno::Reference<uno::XComponentContext>& xContext,
211 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory,
212 const uno::Reference< ucb::XContentProvider >& xContentProvider,
213 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
214 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI);
216 const uno::Reference< uno::XComponentContext> m_xContext;
218 const uno::Reference< ucb::XContentIdentifierFactory > m_xContentIdFactory;
219 const uno::Reference< ucb::XContentProvider > m_xContentProvider;
220 const uno::Reference< xml::dom::XDocumentBuilder > m_xDocumentBuilder;
221 const uno::Reference< xml::xpath::XXPathAPI > m_xXPathAPI;
223 uno::Sequence< beans::NamedValue > m_aRequestHeaderList;
225 uno::Reference< ucb::XCommandProcessor > m_xCommandProcessor;
226 uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
227 uno::Reference< task::XInteractionHandler > m_xPwContainerInteractionHandler;
229 osl::Mutex m_aMutex;
230 osl::Condition m_bCancelled;
232 sal_Int32 m_nCommandId;
235 //------------------------------------------------------------------------------
237 class UpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
239 public:
240 UpdateInformationEnumeration(const uno::Reference< xml::dom::XNodeList >& xNodeList,
241 const uno::Reference< UpdateInformationProvider > xUpdateInformationProvider) :
242 m_xUpdateInformationProvider(xUpdateInformationProvider),
243 m_xNodeList(xNodeList),
244 m_nNodes(xNodeList.is() ? xNodeList->getLength() : 0),
245 m_nCount(0)
249 virtual ~UpdateInformationEnumeration() {};
251 // XEnumeration
252 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return m_nCount < m_nNodes; };
253 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
255 OSL_ASSERT( m_xNodeList.is() );
256 OSL_ASSERT( m_xUpdateInformationProvider.is() );
258 if( !(m_nCount < m_nNodes ) )
259 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this);
263 deployment::UpdateInformationEntry aEntry;
265 uno::Reference< xml::dom::XNode > xAtomEntryNode( m_xNodeList->item(m_nCount++) );
267 uno::Reference< xml::dom::XNode > xSummaryNode(
268 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "summary/text()" ) )
271 if( xSummaryNode.is() )
272 aEntry.Description = xSummaryNode->getNodeValue();
274 uno::Reference< xml::dom::XNode > xContentNode(
275 m_xUpdateInformationProvider->getChildNode( xAtomEntryNode, UNISTRING( "content" ) ) );
277 if( xContentNode.is() )
278 aEntry.UpdateDocument = m_xUpdateInformationProvider->getDocumentRoot(xContentNode);
280 return uno::makeAny(aEntry);
283 // action has been aborted
284 catch( ucb::CommandAbortedException const & e)
285 { throw lang::WrappedTargetException( UNISTRING( "Command aborted" ), *this, uno::makeAny(e) ); }
287 // let runtime exception pass
288 catch( uno::RuntimeException const & ) { throw; }
290 // document not accessible
291 catch( uno::Exception const & e)
292 { throw lang::WrappedTargetException( UNISTRING( "Document not accessible" ), *this, uno::makeAny(e) ); }
295 private:
296 const uno::Reference< UpdateInformationProvider > m_xUpdateInformationProvider;
297 const uno::Reference< xml::dom::XNodeList > m_xNodeList;
298 const sal_Int32 m_nNodes;
299 sal_Int32 m_nCount;
302 //------------------------------------------------------------------------------
304 class SingleUpdateInformationEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
306 public:
307 SingleUpdateInformationEnumeration(const uno::Reference< xml::dom::XElement >& xElement)
308 : m_nCount(0) { m_aEntry.UpdateDocument = xElement; };
309 virtual ~SingleUpdateInformationEnumeration() {};
311 // XEnumeration
312 sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException) { return 0 == m_nCount; };
313 uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
315 if( m_nCount > 0 )
316 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount), *this);
318 ++m_nCount;
319 return uno::makeAny(m_aEntry);
322 private:
323 sal_uInt8 m_nCount;
324 deployment::UpdateInformationEntry m_aEntry;
328 //------------------------------------------------------------------------------
330 UpdateInformationProvider::UpdateInformationProvider(
331 const uno::Reference<uno::XComponentContext>& xContext,
332 const uno::Reference< ucb::XContentIdentifierFactory >& xContentIdFactory,
333 const uno::Reference< ucb::XContentProvider >& xContentProvider,
334 const uno::Reference< xml::dom::XDocumentBuilder >& xDocumentBuilder,
335 const uno::Reference< xml::xpath::XXPathAPI >& xXPathAPI
336 ) : m_xContext(xContext), m_xContentIdFactory(xContentIdFactory),
337 m_xContentProvider(xContentProvider), m_xDocumentBuilder(xDocumentBuilder),
338 m_xXPathAPI(xXPathAPI), m_aRequestHeaderList(1)
340 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
341 if( !xServiceManager.is() )
342 throw uno::RuntimeException(
343 UNISTRING("unable to obtain service manager from component context"),
344 uno::Reference< uno::XInterface >());
346 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
347 xServiceManager->createInstanceWithContext(
348 UNISTRING("com.sun.star.configuration.ConfigurationProvider"),
349 xContext ),
350 uno::UNO_QUERY_THROW);
352 rtl::OUStringBuffer buf;
353 rtl::OUString name;
354 getConfigurationItem(
355 xConfigurationProvider,
356 UNISTRING("org.openoffice.Setup/Product"),
357 UNISTRING("ooName")) >>= name;
358 buf.append(name);
359 buf.append(sal_Unicode(' '));
360 rtl::OUString version;
361 getConfigurationItem(
362 xConfigurationProvider,
363 UNISTRING("org.openoffice.Setup/Product"),
364 UNISTRING("ooSetupVersion")) >>= version;
365 buf.append(version);
366 rtl::OUString edition(
367 UNISTRING(
368 "${${BRAND_BASE_DIR}/program/edition/edition.ini:"
369 "EDITIONNAME}"));
370 rtl::Bootstrap::expandMacros(edition);
371 if (edition.getLength() != 0) {
372 buf.append(sal_Unicode(' '));
373 buf.append(edition);
375 rtl::OUString extension;
376 getConfigurationItem(
377 xConfigurationProvider,
378 UNISTRING("org.openoffice.Setup/Product"),
379 UNISTRING("ooSetupExtension")) >>= extension;
380 if (extension.getLength() != 0) {
381 buf.append(sal_Unicode(' '));
382 buf.append(extension);
384 rtl::OUString product(buf.makeStringAndClear());
386 rtl::OUString aBaseBuildId( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
387 rtl::Bootstrap::expandMacros( aBaseBuildId );
389 rtl::OUString aBrandBuildId( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
390 rtl::Bootstrap::expandMacros( aBrandBuildId );
392 rtl::OUString aUserAgent( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" ) );
393 rtl::Bootstrap::expandMacros( aUserAgent );
395 if ( ! aBaseBuildId.equals( aBrandBuildId ) )
397 sal_Int32 nIndex = aUserAgent.indexOf( aBrandBuildId, 0 );
398 if ( nIndex != -1 )
399 aUserAgent = aUserAgent.replaceAt( nIndex, aBrandBuildId.getLength(), aBaseBuildId );
402 for (sal_Int32 i = 0;;) {
403 i = aUserAgent.indexOfAsciiL(
404 RTL_CONSTASCII_STRINGPARAM("<PRODUCT>"), i);
405 if (i == -1) {
406 break;
408 aUserAgent = aUserAgent.replaceAt(
409 i, RTL_CONSTASCII_LENGTH("<PRODUCT>"), product);
410 i += product.getLength();
413 m_aRequestHeaderList[0].Name = UNISTRING("Accept-Language");
414 m_aRequestHeaderList[0].Value = getConfigurationItem( xConfigurationProvider, UNISTRING("org.openoffice.Setup/L10N"), UNISTRING("ooLocale") );
415 if( aUserAgent.getLength() > 0 )
417 m_aRequestHeaderList.realloc(2);
418 m_aRequestHeaderList[1].Name = UNISTRING("User-Agent");
419 m_aRequestHeaderList[1].Value = uno::makeAny(aUserAgent);
423 //------------------------------------------------------------------------------
424 uno::Reference< uno::XInterface >
425 UpdateInformationProvider::createInstance(const uno::Reference<uno::XComponentContext>& xContext)
427 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
428 if( !xServiceManager.is() )
429 throw uno::RuntimeException(
430 UNISTRING( "unable to obtain service manager from component context" ),
431 uno::Reference< uno::XInterface > ());
433 uno::Reference< ucb::XContentIdentifierFactory > xContentIdFactory(
434 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.ucb.UniversalContentBroker" ), xContext ),
435 uno::UNO_QUERY_THROW);
437 uno::Reference< ucb::XContentProvider > xContentProvider(xContentIdFactory, uno::UNO_QUERY_THROW);
439 uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder(
440 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.dom.DocumentBuilder" ), xContext ),
441 uno::UNO_QUERY_THROW);
443 uno::Reference< xml::xpath::XXPathAPI > xXPath(
444 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), xContext ),
445 uno::UNO_QUERY_THROW);
447 xXPath->registerNS( UNISTRING("atom"), UNISTRING("http://www.w3.org/2005/Atom") );
449 return *new UpdateInformationProvider(xContext, xContentIdFactory, xContentProvider, xDocumentBuilder, xXPath);
452 //------------------------------------------------------------------------------
454 UpdateInformationProvider::~UpdateInformationProvider()
458 //------------------------------------------------------------------------------
460 uno::Any
461 UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, rtl::OUString const & node, rtl::OUString const & item)
463 beans::PropertyValue aProperty;
464 aProperty.Name = UNISTRING("nodepath");
465 aProperty.Value = uno::makeAny(node);
467 uno::Sequence< uno::Any > aArgumentList( 1 );
468 aArgumentList[0] = uno::makeAny( aProperty );
470 uno::Reference< container::XNameAccess > xNameAccess(
471 configurationProvider->createInstanceWithArguments(
472 UNISTRING("com.sun.star.configuration.ConfigurationAccess"),
473 aArgumentList ),
474 uno::UNO_QUERY_THROW);
476 return xNameAccess->getByName(item);
479 //------------------------------------------------------------------------------
481 void
482 UpdateInformationProvider::storeCommandInfo(
483 sal_Int32 nCommandId,
484 uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor)
486 osl::MutexGuard aGuard(m_aMutex);
488 m_nCommandId = nCommandId;
489 m_xCommandProcessor = rxCommandProcessor;
492 //------------------------------------------------------------------------------
494 uno::Reference< io::XInputStream >
495 UpdateInformationProvider::load(const rtl::OUString& rURL)
497 uno::Reference< ucb::XContentIdentifier > xId = m_xContentIdFactory->createContentIdentifier(rURL);
499 if( !xId.is() )
500 throw uno::RuntimeException(
501 UNISTRING( "unable to obtain universal content id" ), *this);
503 uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xContentProvider->queryContent(xId), uno::UNO_QUERY_THROW);
504 rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink());
506 ucb::OpenCommandArgument2 aOpenArgument;
507 aOpenArgument.Mode = ucb::OpenMode::DOCUMENT;
508 aOpenArgument.Priority = 32768;
509 aOpenArgument.Sink = *aSink;
511 ucb::Command aCommand;
512 aCommand.Name = UNISTRING("open");
513 aCommand.Argument = uno::makeAny(aOpenArgument);
515 sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier();
517 storeCommandInfo(nCommandId, xCommandProcessor);
520 uno::Any aResult = xCommandProcessor->execute(aCommand, nCommandId,
521 static_cast < XCommandEnvironment *> (this));
523 catch( const uno::Exception & /* e */ )
525 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
527 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
528 if( xCommandProcessor2.is() )
529 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
531 throw;
533 storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
535 uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
536 if( xCommandProcessor2.is() )
537 xCommandProcessor2->releaseCommandIdentifier(nCommandId);
539 return INPUT_STREAM(aSink->getInputStream());
542 //------------------------------------------------------------------------------
544 // TODO: docu content node
546 uno::Reference< xml::dom::XElement >
547 UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode)
549 OSL_ASSERT(m_xDocumentBuilder.is());
551 uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW);
553 // load the document referenced in 'src' attribute ..
554 if( xElement->hasAttribute( UNISTRING("src") ) )
556 uno::Reference< xml::dom::XDocument > xUpdateXML =
557 m_xDocumentBuilder->parse(load(xElement->getAttribute( UNISTRING("src") )));
559 OSL_ASSERT( xUpdateXML.is() );
561 if( xUpdateXML.is() )
562 return xUpdateXML->getDocumentElement();
564 // .. or return the (single) child element
565 else
567 uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes();
569 // ignore possible #text nodes
570 sal_Int32 nmax = xChildNodes->getLength();
571 for(sal_Int32 n=0; n < nmax; n++)
573 uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY);
574 if( xChildElement.is() )
576 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList
577 * seems to evaluate expression always relative to the root node.
579 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument();
580 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement.get(), sal_True ) );
581 return xUpdateXML->getDocumentElement();
586 return uno::Reference< xml::dom::XElement > ();
589 //------------------------------------------------------------------------------
591 uno::Reference< xml::dom::XNode >
592 UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode,
593 const rtl::OUString& rName)
595 OSL_ASSERT(m_xXPathAPI.is());
596 try {
597 return m_xXPathAPI->selectSingleNode(rxNode, UNISTRING( "./atom:" ) + rName);
598 } catch (xml::xpath::XPathException &) {
599 // ignore
600 return 0;
604 //------------------------------------------------------------------------------
606 uno::Reference< container::XEnumeration > SAL_CALL
607 UpdateInformationProvider::getUpdateInformationEnumeration(
608 uno::Sequence< rtl::OUString > const & repositories,
609 rtl::OUString const & extensionId
610 ) throw (uno::Exception, uno::RuntimeException)
612 OSL_ASSERT(m_xDocumentBuilder.is());
614 // reset cancelled flag
615 m_bCancelled.reset();
617 for(sal_Int32 n=0; n<repositories.getLength(); n++)
621 uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n]));
622 uno::Reference< xml::dom::XElement > xElement;
624 if( xDocument.is() )
625 xElement = xDocument->getDocumentElement();
627 if( xElement.is() )
629 if( xElement->getNodeName().equalsAsciiL("feed", 4) )
631 rtl::OUString aXPathExpression;
633 if( extensionId.getLength() > 0 )
634 aXPathExpression = UNISTRING("//atom:entry/atom:category[@term=\'") + extensionId + UNISTRING("\']/..");
635 else
636 aXPathExpression = UNISTRING("//atom:entry");
638 uno::Reference< xml::dom::XNodeList > xNodeList;
639 try {
640 xNodeList = m_xXPathAPI->selectNodeList(xDocument.get(),
641 aXPathExpression);
642 } catch (xml::xpath::XPathException &) {
643 // ignore
646 return new UpdateInformationEnumeration(xNodeList, this);
648 else
650 return new SingleUpdateInformationEnumeration(xElement);
654 if( m_bCancelled.check() )
655 break;
657 // rethrow runtime exceptions
658 catch( uno::RuntimeException const & ) { throw; }
660 // rethrow only if last url in the list
661 catch( uno::Exception const & )
663 if( n+1 >= repositories.getLength() )
664 throw;
668 return uno::Reference< container::XEnumeration >();
671 //------------------------------------------------------------------------------
673 uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
674 UpdateInformationProvider::getUpdateInformation(
675 uno::Sequence< rtl::OUString > const & repositories,
676 rtl::OUString const & extensionId
677 ) throw (uno::Exception, uno::RuntimeException)
679 uno::Reference< container::XEnumeration > xEnumeration(
680 getUpdateInformationEnumeration(repositories, extensionId)
683 uno::Sequence< uno::Reference< xml::dom::XElement > > aRet;
685 if( xEnumeration.is() )
687 while( xEnumeration->hasMoreElements() )
691 deployment::UpdateInformationEntry aEntry;
692 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() )
694 sal_Int32 n = aRet.getLength();
695 aRet.realloc(n + 1);
696 aRet[n] = aEntry.UpdateDocument;
700 catch( const lang::WrappedTargetException& e )
702 // command aborted, return what we have got so far
703 if( e.TargetException.isExtractableTo( ::cppu::UnoType< ::com::sun::star::ucb::CommandAbortedException >::get() ) )
705 break;
708 // ignore files that can't be loaded
713 return aRet;
716 //------------------------------------------------------------------------------
718 void SAL_CALL
719 UpdateInformationProvider::cancel() throw (uno::RuntimeException)
721 m_bCancelled.set();
723 osl::MutexGuard aGuard(m_aMutex);
724 if( m_xCommandProcessor.is() )
725 m_xCommandProcessor->abort(m_nCommandId);
728 //------------------------------------------------------------------------------
730 void SAL_CALL
731 UpdateInformationProvider::setInteractionHandler(
732 uno::Reference< task::XInteractionHandler > const & handler )
733 throw (uno::RuntimeException)
735 osl::MutexGuard aGuard(m_aMutex);
736 m_xInteractionHandler = handler;
739 //------------------------------------------------------------------------------
741 uno::Reference< task::XInteractionHandler > SAL_CALL
742 UpdateInformationProvider::getInteractionHandler()
743 throw ( uno::RuntimeException )
745 osl::MutexGuard aGuard( m_aMutex );
747 if ( m_xInteractionHandler.is() )
748 return m_xInteractionHandler;
749 else
753 // Supply an interaction handler that uses the password container
754 // service to obtain credentials without displaying a password gui.
756 if ( !m_xPwContainerInteractionHandler.is() )
757 m_xPwContainerInteractionHandler
758 = task::PasswordContainerInteractionHandler::create(
759 m_xContext );
761 catch ( uno::RuntimeException const & )
763 throw;
765 catch ( uno::Exception const & )
768 return m_xPwContainerInteractionHandler;
771 //------------------------------------------------------------------------------
773 uno::Sequence< rtl::OUString >
774 UpdateInformationProvider::getServiceNames()
776 uno::Sequence< rtl::OUString > aServiceList(1);
777 aServiceList[0] = UNISTRING( "com.sun.star.deployment.UpdateInformationProvider");
778 return aServiceList;
781 //------------------------------------------------------------------------------
783 rtl::OUString
784 UpdateInformationProvider::getImplName()
786 return UNISTRING( "vnd.sun.UpdateInformationProvider");
789 //------------------------------------------------------------------------------
791 rtl::OUString SAL_CALL
792 UpdateInformationProvider::getImplementationName() throw (uno::RuntimeException)
794 return getImplName();
797 //------------------------------------------------------------------------------
799 uno::Sequence< rtl::OUString > SAL_CALL
800 UpdateInformationProvider::getSupportedServiceNames() throw (uno::RuntimeException)
802 return getServiceNames();
805 //------------------------------------------------------------------------------
807 sal_Bool SAL_CALL
808 UpdateInformationProvider::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException)
810 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
812 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
813 if( aServiceNameList[n].equals(serviceName) )
814 return sal_True;
816 return sal_False;
819 } // anonymous namespace
821 //------------------------------------------------------------------------------
823 static uno::Reference<uno::XInterface> SAL_CALL
824 createInstance(uno::Reference<uno::XComponentContext> const & xContext)
826 return UpdateInformationProvider::createInstance(xContext);
829 //------------------------------------------------------------------------------
831 static const cppu::ImplementationEntry kImplementations_entries[] =
834 createInstance,
835 UpdateInformationProvider::getImplName,
836 UpdateInformationProvider::getServiceNames,
837 cppu::createSingleComponentFactory,
838 NULL,
841 { NULL, NULL, NULL, NULL, NULL, 0 }
844 //------------------------------------------------------------------------------
846 extern "C" void SAL_CALL
847 component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **)
849 *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
852 //------------------------------------------------------------------------------
854 extern "C" sal_Bool SAL_CALL
855 component_writeInfo(void *pServiceManager, void *pRegistryKey)
857 return cppu::component_writeInfoHelper(
858 pServiceManager,
859 pRegistryKey,
860 kImplementations_entries
864 //------------------------------------------------------------------------------
866 extern "C" void *
867 component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
869 return cppu::component_getFactoryHelper(
870 pszImplementationName,
871 pServiceManager,
872 pRegistryKey,
873 kImplementations_entries) ;