LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/extensions/source/update/feed - updatefeed.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 236 0.0 %
Date: 2013-07-09 Functions: 0 38 0.0 %
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             : 
      21             : #include <cppuhelper/implbase1.hxx>
      22             : #include <cppuhelper/implbase4.hxx>
      23             : #include <cppuhelper/implementationentry.hxx>
      24             : #include <com/sun/star/beans/Property.hpp>
      25             : #include <com/sun/star/beans/PropertyValue.hpp>
      26             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      27             : #include <com/sun/star/beans/NamedValue.hpp>
      28             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      29             : #include <com/sun/star/container/XNameAccess.hpp>
      30             : #include <com/sun/star/deployment/UpdateInformationEntry.hpp>
      31             : #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
      32             : #include <com/sun/star/io/XActiveDataSink.hpp>
      33             : #include <com/sun/star/io/XInputStream.hpp>
      34             : #include <com/sun/star/lang/XComponent.hpp>
      35             : #include <com/sun/star/lang/XServiceInfo.hpp>
      36             : #include <com/sun/star/ucb/UniversalContentBroker.hpp>
      37             : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      38             : #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
      39             : #include <com/sun/star/ucb/XCommandProcessor2.hpp>
      40             : #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
      41             : #include <com/sun/star/ucb/XContentProvider.hpp>
      42             : #include "com/sun/star/ucb/XInteractionSupplyAuthentication.hpp"
      43             : #include <com/sun/star/ucb/OpenCommandArgument3.hpp>
      44             : #include <com/sun/star/ucb/OpenMode.hpp>
      45             : #include <com/sun/star/sdbc/XRow.hpp>
      46             : #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
      47             : #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
      48             : #include <com/sun/star/xml/xpath/XPathAPI.hpp>
      49             : 
      50             : #include <rtl/ref.hxx>
      51             : #include <rtl/bootstrap.hxx>
      52             : #include <rtl/ustrbuf.hxx>
      53             : #include <osl/process.h>
      54             : #include <osl/conditn.hxx>
      55             : 
      56             : namespace beans = com::sun::star::beans ;
      57             : namespace container = com::sun::star::container ;
      58             : namespace deployment = com::sun::star::deployment ;
      59             : namespace io = com::sun::star::io ;
      60             : namespace lang = com::sun::star::lang ;
      61             : namespace task = com::sun::star::task ;
      62             : namespace ucb = com::sun::star::ucb ;
      63             : namespace uno = com::sun::star::uno ;
      64             : namespace xml = com::sun::star::xml ;
      65             : namespace sdbc = com::sun::star::sdbc ;
      66             : 
      67             : 
      68             : //------------------------------------------------------------------------------
      69             : 
      70             : namespace
      71             : {
      72             : 
      73             : #ifdef DEBUG
      74             : 
      75             : class InputStreamWrapper : public ::cppu::WeakImplHelper1< io::XInputStream >
      76             : {
      77             :     uno::Reference< io::XInputStream > m_xStream;
      78             : 
      79             : public:
      80             :     InputStreamWrapper(const uno::Reference< io::XInputStream >& rxStream) :
      81             :         m_xStream(rxStream) {};
      82             : 
      83             :     virtual sal_Int32 SAL_CALL readBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
      84             :         throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
      85             :         {
      86             :             sal_Int32 n = m_xStream->readBytes(aData, nBytesToRead);
      87             :             if ( n )
      88             :                 OSL_TRACE( "Read [%d] bytes: %s", n, aData.get()->elements );
      89             :             return n;
      90             :         };
      91             :     virtual sal_Int32 SAL_CALL readSomeBytes(uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
      92             :         throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
      93             :         {
      94             :             sal_Int32 n = m_xStream->readSomeBytes(aData, nMaxBytesToRead);
      95             :             if ( n )
      96             :                 OSL_TRACE( "Read [%d] bytes: %s", n, aData.get()->elements );
      97             :             return n;
      98             :         };
      99             :     virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
     100             :         throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
     101             :         { m_xStream->skipBytes(nBytesToSkip); };
     102             :     virtual sal_Int32 SAL_CALL available()
     103             :         throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
     104             :         { return m_xStream->available(); };
     105             :     virtual void SAL_CALL closeInput( )
     106             :         throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
     107             :         {};
     108             : };
     109             : 
     110             : #define INPUT_STREAM(i) new InputStreamWrapper(i)
     111             : #else
     112             : #define INPUT_STREAM(i) i
     113             : #endif
     114             : 
     115             : //------------------------------------------------------------------------------
     116             : 
     117           0 : class ActiveDataSink : public ::cppu::WeakImplHelper1< io::XActiveDataSink >
     118             : {
     119             :     uno::Reference< io::XInputStream > m_xStream;
     120             : 
     121             : public:
     122           0 :     ActiveDataSink() {};
     123             : 
     124             :     inline operator uno::Reference< io::XActiveDataSink > () { return this; };
     125             : 
     126           0 :     virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
     127           0 :         throw (uno::RuntimeException) { return m_xStream; };
     128           0 :     virtual void SAL_CALL setInputStream( uno::Reference< io::XInputStream > const & rStream )
     129           0 :         throw (uno::RuntimeException) { m_xStream = rStream; };
     130             : };
     131             : 
     132             : //------------------------------------------------------------------------------
     133             : 
     134             : class UpdateInformationProvider :
     135             :     public ::cppu::WeakImplHelper4< deployment::XUpdateInformationProvider,
     136             :                                     ucb::XCommandEnvironment,
     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);
     156             : 
     157             :     virtual void SAL_CALL cancel()
     158             :         throw (uno::RuntimeException);
     159             : 
     160             :     virtual void SAL_CALL setInteractionHandler(
     161             :         uno::Reference< task::XInteractionHandler > const & handler )
     162             :         throw (uno::RuntimeException);
     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);
     169             : 
     170             :     // XCommandEnvironment
     171             :     virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
     172             :         throw ( uno::RuntimeException );
     173             : 
     174           0 :     virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
     175           0 :         throw ( uno::RuntimeException ) { return  uno::Reference< ucb::XProgressHandler >(); };
     176             : 
     177             :     // XWebDAVCommandEnvironment
     178           0 :     virtual uno::Sequence< beans::NamedValue > SAL_CALL getUserRequestHeaders(
     179             :         const OUString&, const OUString& )
     180           0 :         throw ( uno::RuntimeException ) { return m_aRequestHeaderList; };
     181             : 
     182             :     // XServiceInfo
     183             :     virtual OUString SAL_CALL getImplementationName()
     184             :         throw (uno::RuntimeException);
     185             :     virtual sal_Bool SAL_CALL supportsService(OUString const & serviceName)
     186             :         throw (uno::RuntimeException);
     187             :     virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
     188             :         throw (uno::RuntimeException);
     189             : 
     190             : protected:
     191             : 
     192             :     virtual ~UpdateInformationProvider();
     193             :     static uno::Any 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::NamedValue > 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) { return m_nCount < m_nNodes; };
     242           0 :     uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     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::valueOf(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) { return 0 == m_nCount; };
     302           0 :     uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
     303             :     {
     304           0 :         if( m_nCount > 0 )
     305           0 :             throw container::NoSuchElementException(OUString::valueOf(m_nCount), *this);
     306             : 
     307           0 :         ++m_nCount;
     308           0 :         return uno::makeAny(m_aEntry);
     309             :     };
     310             : 
     311             : private:
     312             :     sal_uInt8 m_nCount;
     313             :     deployment::UpdateInformationEntry m_aEntry;
     314             : };
     315             : 
     316             : 
     317             : //------------------------------------------------------------------------------
     318             : 
     319           0 : 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), m_xUniversalContentBroker(xUniversalContentBroker),
     325             :     m_xDocumentBuilder(xDocumentBuilder),
     326           0 :     m_xXPathAPI(xXPathAPI), m_aRequestHeaderList(1)
     327             : {
     328             :     uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
     329           0 :         com::sun::star::configuration::theDefaultProvider::get(xContext));
     330             : 
     331           0 :     OUStringBuffer buf;
     332           0 :     OUString name;
     333             :     getConfigurationItem(
     334             :         xConfigurationProvider,
     335             :         "org.openoffice.Setup/Product",
     336           0 :         "ooName") >>= name;
     337           0 :     buf.append(name);
     338           0 :     buf.append(sal_Unicode(' '));
     339           0 :     OUString version;
     340             :     getConfigurationItem(
     341             :         xConfigurationProvider,
     342             :         "org.openoffice.Setup/Product",
     343           0 :         "ooSetupVersion") >>= version;
     344           0 :     buf.append(version);
     345           0 :     OUString extension;
     346             :     getConfigurationItem(
     347             :         xConfigurationProvider,
     348             :         "org.openoffice.Setup/Product",
     349           0 :         "ooSetupExtension") >>= extension;
     350           0 :     if (!extension.isEmpty()) {
     351           0 :         buf.append(extension);
     352             :     }
     353           0 :     OUString product(buf.makeStringAndClear());
     354             : 
     355           0 :     OUString aUserAgent( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateUserAgent}" );
     356           0 :     rtl::Bootstrap::expandMacros( aUserAgent );
     357             : 
     358           0 :     for (sal_Int32 i = 0;;) {
     359             :         i = aUserAgent.indexOfAsciiL(
     360           0 :             RTL_CONSTASCII_STRINGPARAM("<PRODUCT>"), i);
     361           0 :         if (i == -1) {
     362           0 :             break;
     363             :         }
     364           0 :         aUserAgent = aUserAgent.replaceAt(
     365           0 :             i, RTL_CONSTASCII_LENGTH("<PRODUCT>"), product);
     366           0 :         i += product.getLength();
     367           0 :     }
     368             : 
     369             :     SAL_INFO("extensions.update", "UpdateUserAgent: " << aUserAgent);
     370             : 
     371           0 :     m_aRequestHeaderList[0].Name = "Accept-Language";
     372           0 :     m_aRequestHeaderList[0].Value = getConfigurationItem( xConfigurationProvider, "org.openoffice.Setup/L10N", "ooLocale" );
     373           0 :     if( !aUserAgent.isEmpty() )
     374             :     {
     375           0 :         m_aRequestHeaderList.realloc(2);
     376           0 :         m_aRequestHeaderList[1].Name = "User-Agent";
     377           0 :         m_aRequestHeaderList[1].Value = uno::makeAny(aUserAgent);
     378           0 :     }
     379           0 : }
     380             : 
     381             : //------------------------------------------------------------------------------
     382             : uno::Reference< uno::XInterface >
     383           0 : UpdateInformationProvider::createInstance(const uno::Reference<uno::XComponentContext>& xContext)
     384             : {
     385             :     uno::Reference< ucb::XUniversalContentBroker > xUniversalContentBroker =
     386           0 :         ucb::UniversalContentBroker::create(xContext);
     387             : 
     388             :     uno::Reference< xml::dom::XDocumentBuilder > xDocumentBuilder(
     389           0 :         xml::dom::DocumentBuilder::create(xContext));
     390             : 
     391           0 :     uno::Reference< xml::xpath::XXPathAPI > xXPath = xml::xpath::XPathAPI::create( xContext );
     392             : 
     393           0 :     xXPath->registerNS( "atom", "http://www.w3.org/2005/Atom" );
     394             : 
     395           0 :     return *new UpdateInformationProvider(xContext, xUniversalContentBroker, xDocumentBuilder, xXPath);
     396             : }
     397             : 
     398             : //------------------------------------------------------------------------------
     399             : 
     400           0 : UpdateInformationProvider::~UpdateInformationProvider()
     401             : {
     402           0 : }
     403             : 
     404             : //------------------------------------------------------------------------------
     405             : 
     406             : uno::Any
     407           0 : UpdateInformationProvider::getConfigurationItem(uno::Reference<lang::XMultiServiceFactory> const & configurationProvider, OUString const & node, OUString const & item)
     408             : {
     409           0 :     beans::NamedValue aProperty;
     410           0 :     aProperty.Name  = "nodepath";
     411           0 :     aProperty.Value = uno::makeAny(node);
     412             : 
     413           0 :     uno::Sequence< uno::Any > aArgumentList( 1 );
     414           0 :     aArgumentList[0] = uno::makeAny( aProperty );
     415             : 
     416             :     uno::Reference< container::XNameAccess > xNameAccess(
     417           0 :         configurationProvider->createInstanceWithArguments(
     418             :             "com.sun.star.configuration.ConfigurationAccess",
     419           0 :             aArgumentList ),
     420           0 :         uno::UNO_QUERY_THROW);
     421             : 
     422           0 :     return xNameAccess->getByName(item);
     423             : }
     424             : 
     425             : //------------------------------------------------------------------------------
     426             : 
     427             : void
     428           0 : UpdateInformationProvider::storeCommandInfo(
     429             :     sal_Int32 nCommandId,
     430             :     uno::Reference< ucb::XCommandProcessor > const & rxCommandProcessor)
     431             : {
     432           0 :     osl::MutexGuard aGuard(m_aMutex);
     433             : 
     434           0 :     m_nCommandId = nCommandId;
     435           0 :     m_xCommandProcessor = rxCommandProcessor;
     436           0 : }
     437             : 
     438             : //------------------------------------------------------------------------------
     439             : 
     440             : uno::Reference< io::XInputStream >
     441           0 : UpdateInformationProvider::load(const OUString& rURL)
     442             : {
     443           0 :     uno::Reference< ucb::XContentIdentifier > xId = m_xUniversalContentBroker->createContentIdentifier(rURL);
     444             : 
     445           0 :     if( !xId.is() )
     446             :         throw uno::RuntimeException(
     447           0 :             "unable to obtain universal content id", *this);
     448             : 
     449           0 :     uno::Reference< ucb::XCommandProcessor > xCommandProcessor(m_xUniversalContentBroker->queryContent(xId), uno::UNO_QUERY_THROW);
     450           0 :     rtl::Reference< ActiveDataSink > aSink(new ActiveDataSink());
     451             : 
     452             :     // Disable KeepAlive in webdav - don't want millions of office
     453             :     // instances phone home & clog up servers
     454           0 :     uno::Sequence< beans::NamedValue > aProps( 1 );
     455           0 :     aProps[ 0 ] = beans::NamedValue(
     456           0 :         "KeepAlive", uno::makeAny(sal_False));
     457             : 
     458           0 :     ucb::OpenCommandArgument3 aOpenArgument;
     459           0 :     aOpenArgument.Mode = ucb::OpenMode::DOCUMENT;
     460           0 :     aOpenArgument.Priority = 32768;
     461           0 :     aOpenArgument.Sink = *aSink;
     462           0 :     aOpenArgument.OpeningFlags = aProps;
     463             : 
     464           0 :     ucb::Command aCommand;
     465           0 :     aCommand.Name = "open";
     466           0 :     aCommand.Argument = uno::makeAny(aOpenArgument);
     467             : 
     468           0 :     sal_Int32 nCommandId = xCommandProcessor->createCommandIdentifier();
     469             : 
     470           0 :     storeCommandInfo(nCommandId, xCommandProcessor);
     471             :     try
     472             :     {
     473           0 :         uno::Any aResult = xCommandProcessor->execute(aCommand, nCommandId,
     474           0 :             static_cast < XCommandEnvironment *> (this));
     475             :     }
     476           0 :     catch( const uno::Exception & /* e */ )
     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 :         throw;
     485             :     }
     486           0 :     storeCommandInfo(0, uno::Reference< ucb::XCommandProcessor > ());
     487             : 
     488           0 :     uno::Reference< ucb::XCommandProcessor2 > xCommandProcessor2(xCommandProcessor, uno::UNO_QUERY);
     489           0 :     if( xCommandProcessor2.is() )
     490           0 :         xCommandProcessor2->releaseCommandIdentifier(nCommandId);
     491             : 
     492           0 :     return INPUT_STREAM(aSink->getInputStream());
     493             : }
     494             : 
     495             : //------------------------------------------------------------------------------
     496             : 
     497             : // TODO: docu content node
     498             : 
     499             : uno::Reference< xml::dom::XElement >
     500           0 : UpdateInformationProvider::getDocumentRoot(const uno::Reference< xml::dom::XNode >& rxNode)
     501             : {
     502             :     OSL_ASSERT(m_xDocumentBuilder.is());
     503             : 
     504           0 :     uno::Reference< xml::dom::XElement > xElement(rxNode, uno::UNO_QUERY_THROW);
     505             : 
     506             :     // load the document referenced in 'src' attribute ..
     507           0 :     if( xElement->hasAttribute( "src" ) )
     508             :     {
     509             :         uno::Reference< xml::dom::XDocument > xUpdateXML =
     510           0 :             m_xDocumentBuilder->parse(load(xElement->getAttribute( "src" )));
     511             : 
     512             :         OSL_ASSERT( xUpdateXML.is() );
     513             : 
     514           0 :         if( xUpdateXML.is() )
     515           0 :             return xUpdateXML->getDocumentElement();
     516             :     }
     517             :     // .. or return the (single) child element
     518             :     else
     519             :     {
     520           0 :         uno::Reference< xml::dom::XNodeList> xChildNodes = rxNode->getChildNodes();
     521             : 
     522             :         // ignore possible #text nodes
     523           0 :         sal_Int32 nmax = xChildNodes->getLength();
     524           0 :         for(sal_Int32 n=0; n < nmax; n++)
     525             :         {
     526           0 :             uno::Reference< xml::dom::XElement > xChildElement(xChildNodes->item(n), uno::UNO_QUERY);
     527           0 :             if( xChildElement.is() )
     528             :             {
     529             :                 /* Copy the content to a dedicated document since XXPathAPI->selectNodeList
     530             :                  * seems to evaluate expression always relative to the root node.
     531             :                  */
     532           0 :                 uno::Reference< xml::dom::XDocument > xUpdateXML = m_xDocumentBuilder->newDocument();
     533           0 :                 xUpdateXML->appendChild( xUpdateXML->importNode(xChildElement.get(), sal_True ) );
     534           0 :                 return xUpdateXML->getDocumentElement();
     535             :             }
     536           0 :         }
     537             :     }
     538             : 
     539           0 :     return uno::Reference< xml::dom::XElement > ();
     540             : }
     541             : 
     542             : //------------------------------------------------------------------------------
     543             : 
     544             : uno::Reference< xml::dom::XNode >
     545           0 : UpdateInformationProvider::getChildNode(const uno::Reference< xml::dom::XNode >& rxNode,
     546             :                                         const OUString& rName)
     547             : {
     548             :     OSL_ASSERT(m_xXPathAPI.is());
     549             :     try {
     550           0 :         return m_xXPathAPI->selectSingleNode(rxNode, "./atom:" + rName);
     551           0 :     } catch (const xml::xpath::XPathException &) {
     552             :         // ignore
     553           0 :         return 0;
     554             :     }
     555             : }
     556             : 
     557             : //------------------------------------------------------------------------------
     558             : 
     559             : uno::Reference< container::XEnumeration > SAL_CALL
     560           0 : UpdateInformationProvider::getUpdateInformationEnumeration(
     561             :     uno::Sequence< OUString > const & repositories,
     562             :     OUString const & extensionId
     563             : ) throw (uno::Exception, uno::RuntimeException)
     564             : {
     565             :     OSL_ASSERT(m_xDocumentBuilder.is());
     566             : 
     567             :     // reset cancelled flag
     568           0 :     m_bCancelled.reset();
     569             : 
     570           0 :     for(sal_Int32 n=0; n<repositories.getLength(); n++)
     571             :     {
     572             :         try
     573             :         {
     574           0 :             uno::Reference< xml::dom::XDocument > xDocument = m_xDocumentBuilder->parse(load(repositories[n]));
     575           0 :             uno::Reference< xml::dom::XElement > xElement;
     576             : 
     577           0 :             if( xDocument.is() )
     578           0 :                 xElement = xDocument->getDocumentElement();
     579             : 
     580           0 :             if( xElement.is() )
     581             :             {
     582           0 :                 if( xElement->getNodeName().equalsAsciiL("feed", 4) )
     583             :                 {
     584           0 :                     OUString aXPathExpression;
     585             : 
     586           0 :                     if( !extensionId.isEmpty() )
     587           0 :                         aXPathExpression = "//atom:entry/atom:category[@term=\'" + extensionId + "\']/..";
     588             :                     else
     589           0 :                         aXPathExpression = "//atom:entry";
     590             : 
     591           0 :                     uno::Reference< xml::dom::XNodeList > xNodeList;
     592             :                     try {
     593           0 :                         xNodeList = m_xXPathAPI->selectNodeList(xDocument.get(),
     594           0 :                             aXPathExpression);
     595           0 :                     } catch (const xml::xpath::XPathException &) {
     596             :                         // ignore
     597             :                     }
     598             : 
     599           0 :                     return new UpdateInformationEnumeration(xNodeList, this);
     600             :                 }
     601             :                 else
     602             :                 {
     603           0 :                     return new SingleUpdateInformationEnumeration(xElement);
     604             :                 }
     605             :             }
     606             : 
     607           0 :             if( m_bCancelled.check() )
     608           0 :                 break;
     609             :         }
     610           0 :         catch( uno::RuntimeException const& /*e*/)
     611             :         {
     612             :             // #i118675# ignore runtime exceptions for now
     613             :             // especially the "unsatisfied query for interface of
     614             :             // type com.sun.star.ucb.XCommandProcessor!" exception
     615             :         }
     616             : 
     617             :         // rethrow only if last url in the list
     618           0 :         catch( uno::Exception const & )
     619             :         {
     620           0 :             if( n+1 >= repositories.getLength() )
     621           0 :                 throw;
     622             :         }
     623             :     }
     624             : 
     625           0 :     return uno::Reference< container::XEnumeration >();
     626             : }
     627             : 
     628             : //------------------------------------------------------------------------------
     629             : 
     630             : uno::Sequence< uno::Reference< xml::dom::XElement > > SAL_CALL
     631           0 : UpdateInformationProvider::getUpdateInformation(
     632             :     uno::Sequence< OUString > const & repositories,
     633             :     OUString const & extensionId
     634             : ) throw (uno::Exception, uno::RuntimeException)
     635             : {
     636             :     uno::Reference< container::XEnumeration > xEnumeration(
     637           0 :         getUpdateInformationEnumeration(repositories, extensionId)
     638           0 :     );
     639             : 
     640           0 :     uno::Sequence< uno::Reference< xml::dom::XElement > > aRet;
     641             : 
     642           0 :     if( xEnumeration.is() )
     643             :     {
     644           0 :         while( xEnumeration->hasMoreElements() )
     645             :         {
     646             :             try
     647             :             {
     648           0 :                 deployment::UpdateInformationEntry aEntry;
     649           0 :                 if( (xEnumeration->nextElement() >>= aEntry ) && aEntry.UpdateDocument.is() )
     650             :                 {
     651           0 :                     sal_Int32 n = aRet.getLength();
     652           0 :                     aRet.realloc(n + 1);
     653           0 :                     aRet[n] = aEntry.UpdateDocument;
     654           0 :                 }
     655             :             }
     656             : 
     657           0 :             catch( const lang::WrappedTargetException& e )
     658             :             {
     659             :                 // command aborted, return what we have got so far
     660           0 :                 if( e.TargetException.isExtractableTo( ::cppu::UnoType< ::com::sun::star::ucb::CommandAbortedException >::get() ) )
     661             :                 {
     662           0 :                     break;
     663             :                 }
     664             : 
     665             :                 // ignore files that can't be loaded
     666           0 :             }
     667             :         }
     668             :     }
     669             : 
     670           0 :     return aRet;
     671             : }
     672             : 
     673             : //------------------------------------------------------------------------------
     674             : 
     675             : void SAL_CALL
     676           0 : UpdateInformationProvider::cancel() throw (uno::RuntimeException)
     677             : {
     678           0 :     m_bCancelled.set();
     679             : 
     680           0 :     osl::MutexGuard aGuard(m_aMutex);
     681           0 :     if( m_xCommandProcessor.is() )
     682           0 :         m_xCommandProcessor->abort(m_nCommandId);
     683           0 : }
     684             : 
     685             : //------------------------------------------------------------------------------
     686             : 
     687             : void SAL_CALL
     688           0 : UpdateInformationProvider::setInteractionHandler(
     689             :         uno::Reference< task::XInteractionHandler > const & handler )
     690             :     throw (uno::RuntimeException)
     691             : {
     692           0 :     osl::MutexGuard aGuard(m_aMutex);
     693           0 :     m_xInteractionHandler = handler;
     694           0 : }
     695             : 
     696             : //------------------------------------------------------------------------------
     697             : 
     698             : uno::Reference< task::XInteractionHandler > SAL_CALL
     699           0 : UpdateInformationProvider::getInteractionHandler()
     700             :     throw ( uno::RuntimeException )
     701             : {
     702           0 :     osl::MutexGuard aGuard( m_aMutex );
     703             : 
     704           0 :     if ( m_xInteractionHandler.is() )
     705           0 :         return m_xInteractionHandler;
     706             :     else
     707             :     {
     708             :         try
     709             :         {
     710             :             // Supply an interaction handler that uses the password container
     711             :             // service to obtain credentials without displaying a password gui.
     712             : 
     713           0 :             if ( !m_xPwContainerInteractionHandler.is() )
     714             :                 m_xPwContainerInteractionHandler
     715           0 :                     = task::PasswordContainerInteractionHandler::create(
     716           0 :                         m_xContext );
     717             :         }
     718           0 :         catch ( uno::RuntimeException const & )
     719             :         {
     720           0 :             throw;
     721             :         }
     722           0 :         catch ( uno::Exception const & )
     723             :         {
     724             :         }
     725           0 :         return m_xPwContainerInteractionHandler;
     726           0 :     }
     727             : }
     728             : //------------------------------------------------------------------------------
     729             : 
     730             : uno::Sequence< OUString >
     731           0 : UpdateInformationProvider::getServiceNames()
     732             : {
     733           0 :     uno::Sequence< OUString > aServiceList(1);
     734           0 :     aServiceList[0] = "com.sun.star.deployment.UpdateInformationProvider";
     735           0 :     return aServiceList;
     736             : };
     737             : 
     738             : //------------------------------------------------------------------------------
     739             : 
     740             : OUString
     741           0 : UpdateInformationProvider::getImplName()
     742             : {
     743           0 :     return OUString("vnd.sun.UpdateInformationProvider");
     744             : }
     745             : 
     746             : //------------------------------------------------------------------------------
     747             : 
     748             : OUString SAL_CALL
     749           0 : UpdateInformationProvider::getImplementationName() throw (uno::RuntimeException)
     750             : {
     751           0 :     return getImplName();
     752             : }
     753             : 
     754             : //------------------------------------------------------------------------------
     755             : 
     756             : uno::Sequence< OUString > SAL_CALL
     757           0 : UpdateInformationProvider::getSupportedServiceNames() throw (uno::RuntimeException)
     758             : {
     759           0 :     return getServiceNames();
     760             : }
     761             : 
     762             : //------------------------------------------------------------------------------
     763             : 
     764             : sal_Bool SAL_CALL
     765           0 : UpdateInformationProvider::supportsService( OUString const & serviceName ) throw (uno::RuntimeException)
     766             : {
     767           0 :     uno::Sequence< OUString > aServiceNameList = getServiceNames();
     768             : 
     769           0 :     for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
     770           0 :         if( aServiceNameList[n].equals(serviceName) )
     771           0 :             return sal_True;
     772             : 
     773           0 :     return sal_False;
     774             : }
     775             : 
     776             : } // anonymous namespace
     777             : 
     778             : //------------------------------------------------------------------------------
     779             : 
     780             : static uno::Reference<uno::XInterface> SAL_CALL
     781           0 : createInstance(uno::Reference<uno::XComponentContext> const & xContext)
     782             : {
     783           0 :     return UpdateInformationProvider::createInstance(xContext);
     784             : }
     785             : 
     786             : //------------------------------------------------------------------------------
     787             : 
     788             : static const cppu::ImplementationEntry kImplementations_entries[] =
     789             : {
     790             :     {
     791             :         createInstance,
     792             :         UpdateInformationProvider::getImplName,
     793             :         UpdateInformationProvider::getServiceNames,
     794             :         cppu::createSingleComponentFactory,
     795             :         NULL,
     796             :         0
     797             :     },
     798             :     { NULL, NULL, NULL, NULL, NULL, 0 }
     799             : } ;
     800             : 
     801             : //------------------------------------------------------------------------------
     802             : 
     803           0 : extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL updatefeed_component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
     804             : {
     805             :     return cppu::component_getFactoryHelper(
     806             :         pszImplementationName,
     807             :         pServiceManager,
     808             :         pRegistryKey,
     809           0 :         kImplementations_entries) ;
     810             : }
     811             : 
     812             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10