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 //------------------------------------------------------------------------------
85 class InputStreamWrapper
: public ::cppu::WeakImplHelper1
< io::XInputStream
>
87 uno::Reference
< io::XInputStream
> m_xStream
;
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
);
98 OSL_TRACE( "Read [%d] bytes: %s", n
, aData
.get()->elements
);
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
);
106 OSL_TRACE( "Read [%d] bytes: %s", n
, aData
.get()->elements
);
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)
122 #define INPUT_STREAM(i) i
125 //------------------------------------------------------------------------------
127 class ActiveDataSink
: public ::cppu::WeakImplHelper1
< io::XActiveDataSink
>
129 uno::Reference
< io::XInputStream
> m_xStream
;
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
,
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
; };
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
);
202 virtual ~UpdateInformationProvider();
203 static uno::Any
getConfigurationItem(uno::Reference
<lang::XMultiServiceFactory
> const & configurationProvider
, rtl::OUString
const & node
, rtl::OUString
const & item
);
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
;
231 osl::Condition m_bCancelled
;
233 sal_Int32 m_nCommandId
;
236 //------------------------------------------------------------------------------
238 class UpdateInformationEnumeration
: public ::cppu::WeakImplHelper1
< container::XEnumeration
>
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),
250 virtual ~UpdateInformationEnumeration() {};
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
) ); }
297 const uno::Reference
< UpdateInformationProvider
> m_xUpdateInformationProvider
;
298 const uno::Reference
< xml::dom::XNodeList
> m_xNodeList
;
299 const sal_Int32 m_nNodes
;
303 //------------------------------------------------------------------------------
305 class SingleUpdateInformationEnumeration
: public ::cppu::WeakImplHelper1
< container::XEnumeration
>
308 SingleUpdateInformationEnumeration(const uno::Reference
< xml::dom::XElement
>& xElement
)
309 : m_nCount(0) { m_aEntry
.UpdateDocument
= xElement
; };
310 virtual ~SingleUpdateInformationEnumeration() {};
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
)
317 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount
), *this);
320 return uno::makeAny(m_aEntry
);
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
;
346 getConfigurationItem(
347 xConfigurationProvider
,
348 UNISTRING("org.openoffice.Setup/Product"),
349 UNISTRING("ooName")) >>= name
;
351 buf
.append(sal_Unicode(' '));
352 rtl::OUString version
;
353 getConfigurationItem(
354 xConfigurationProvider
,
355 UNISTRING("org.openoffice.Setup/Product"),
356 UNISTRING("ooSetupVersion")) >>= version
;
358 rtl::OUString
edition(
360 "${${BRAND_BASE_DIR}/program/edition/edition.ini:"
362 rtl::Bootstrap::expandMacros(edition
);
363 if (!edition
.isEmpty()) {
364 buf
.append(sal_Unicode(' '));
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
);
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 //------------------------------------------------------------------------------
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"),
453 uno::UNO_QUERY_THROW
);
455 return xNameAccess
->getByName(item
);
458 //------------------------------------------------------------------------------
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
);
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
);
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
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());
583 return m_xXPathAPI
->selectSingleNode(rxNode
, UNISTRING( "./atom:" ) + rName
);
584 } catch (const xml::xpath::XPathException
&) {
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
;
611 xElement
= xDocument
->getDocumentElement();
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("\']/..");
622 aXPathExpression
= UNISTRING("//atom:entry");
624 uno::Reference
< xml::dom::XNodeList
> xNodeList
;
626 xNodeList
= m_xXPathAPI
->selectNodeList(xDocument
.get(),
628 } catch (const xml::xpath::XPathException
&) {
632 return new UpdateInformationEnumeration(xNodeList
, this);
636 return new SingleUpdateInformationEnumeration(xElement
);
640 if( m_bCancelled
.check() )
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() )
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();
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() ) )
694 // ignore files that can't be loaded
702 //------------------------------------------------------------------------------
705 UpdateInformationProvider::cancel() throw (uno::RuntimeException
)
709 osl::MutexGuard
aGuard(m_aMutex
);
710 if( m_xCommandProcessor
.is() )
711 m_xCommandProcessor
->abort(m_nCommandId
);
714 //------------------------------------------------------------------------------
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
;
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(
747 catch ( uno::RuntimeException
const & )
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");
767 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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
) )
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
[] =
821 UpdateInformationProvider::getImplName
,
822 UpdateInformationProvider::getServiceNames
,
823 cppu::createSingleComponentFactory
,
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
,
838 kImplementations_entries
) ;
841 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */