LCOV - code coverage report
Current view: top level - extensions/source/update/feed - updatefeed.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 52 222 23.4 %
Date: 2014-04-11 Functions: 9 38 23.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10