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 //------------------------------------------------------------------------------
84 class InputStreamWrapper
: public ::cppu::WeakImplHelper1
< io::XInputStream
>
86 uno::Reference
< io::XInputStream
> m_xStream
;
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
);
97 OSL_TRACE( "Read [%d] bytes: %s\n", n
, aData
.get()->elements
);
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
);
105 OSL_TRACE( "Read [%d] bytes: %s\n", n
, aData
.get()->elements
);
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)
121 #define INPUT_STREAM(i) i
124 //------------------------------------------------------------------------------
126 class ActiveDataSink
: public ::cppu::WeakImplHelper1
< io::XActiveDataSink
>
128 uno::Reference
< io::XInputStream
> m_xStream
;
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
,
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
; };
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
);
201 virtual ~UpdateInformationProvider();
202 static uno::Any
getConfigurationItem(uno::Reference
<lang::XMultiServiceFactory
> const & configurationProvider
, rtl::OUString
const & node
, rtl::OUString
const & item
);
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
;
230 osl::Condition m_bCancelled
;
232 sal_Int32 m_nCommandId
;
235 //------------------------------------------------------------------------------
237 class UpdateInformationEnumeration
: public ::cppu::WeakImplHelper1
< container::XEnumeration
>
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),
249 virtual ~UpdateInformationEnumeration() {};
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
) ); }
296 const uno::Reference
< UpdateInformationProvider
> m_xUpdateInformationProvider
;
297 const uno::Reference
< xml::dom::XNodeList
> m_xNodeList
;
298 const sal_Int32 m_nNodes
;
302 //------------------------------------------------------------------------------
304 class SingleUpdateInformationEnumeration
: public ::cppu::WeakImplHelper1
< container::XEnumeration
>
307 SingleUpdateInformationEnumeration(const uno::Reference
< xml::dom::XElement
>& xElement
)
308 : m_nCount(0) { m_aEntry
.UpdateDocument
= xElement
; };
309 virtual ~SingleUpdateInformationEnumeration() {};
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
)
316 throw container::NoSuchElementException(rtl::OUString::valueOf(m_nCount
), *this);
319 return uno::makeAny(m_aEntry
);
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"),
350 uno::UNO_QUERY_THROW
);
352 rtl::OUStringBuffer buf
;
354 getConfigurationItem(
355 xConfigurationProvider
,
356 UNISTRING("org.openoffice.Setup/Product"),
357 UNISTRING("ooName")) >>= name
;
359 buf
.append(sal_Unicode(' '));
360 rtl::OUString version
;
361 getConfigurationItem(
362 xConfigurationProvider
,
363 UNISTRING("org.openoffice.Setup/Product"),
364 UNISTRING("ooSetupVersion")) >>= version
;
366 rtl::OUString
edition(
368 "${${BRAND_BASE_DIR}/program/edition/edition.ini:"
370 rtl::Bootstrap::expandMacros(edition
);
371 if (edition
.getLength() != 0) {
372 buf
.append(sal_Unicode(' '));
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 );
399 aUserAgent
= aUserAgent
.replaceAt( nIndex
, aBrandBuildId
.getLength(), aBaseBuildId
);
402 for (sal_Int32 i
= 0;;) {
403 i
= aUserAgent
.indexOfAsciiL(
404 RTL_CONSTASCII_STRINGPARAM("<PRODUCT>"), i
);
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 //------------------------------------------------------------------------------
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"),
474 uno::UNO_QUERY_THROW
);
476 return xNameAccess
->getByName(item
);
479 //------------------------------------------------------------------------------
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
);
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
);
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
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());
597 return m_xXPathAPI
->selectSingleNode(rxNode
, UNISTRING( "./atom:" ) + rName
);
598 } catch (xml::xpath::XPathException
&) {
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
;
625 xElement
= xDocument
->getDocumentElement();
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("\']/..");
636 aXPathExpression
= UNISTRING("//atom:entry");
638 uno::Reference
< xml::dom::XNodeList
> xNodeList
;
640 xNodeList
= m_xXPathAPI
->selectNodeList(xDocument
.get(),
642 } catch (xml::xpath::XPathException
&) {
646 return new UpdateInformationEnumeration(xNodeList
, this);
650 return new SingleUpdateInformationEnumeration(xElement
);
654 if( m_bCancelled
.check() )
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() )
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();
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() ) )
708 // ignore files that can't be loaded
716 //------------------------------------------------------------------------------
719 UpdateInformationProvider::cancel() throw (uno::RuntimeException
)
723 osl::MutexGuard
aGuard(m_aMutex
);
724 if( m_xCommandProcessor
.is() )
725 m_xCommandProcessor
->abort(m_nCommandId
);
728 //------------------------------------------------------------------------------
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
;
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(
761 catch ( uno::RuntimeException
const & )
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");
781 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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
) )
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
[] =
835 UpdateInformationProvider::getImplName
,
836 UpdateInformationProvider::getServiceNames
,
837 cppu::createSingleComponentFactory
,
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(
860 kImplementations_entries
864 //------------------------------------------------------------------------------
867 component_getFactory(const sal_Char
*pszImplementationName
, void *pServiceManager
, void *pRegistryKey
)
869 return cppu::component_getFactoryHelper(
870 pszImplementationName
,
873 kImplementations_entries
) ;