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

Generated by: LCOV version 1.11