LCOV - code coverage report
Current view: top level - ucb/source/ucp/ftp - ftpcontent.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 42 390 10.8 %
Date: 2015-06-13 12:38:46 Functions: 7 34 20.6 %
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             : /**************************************************************************
      22             :                                 TODO
      23             :  **************************************************************************
      24             : 
      25             :  *************************************************************************/
      26             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      27             : 
      28             : #include "ftpdynresultset.hxx"
      29             : #include "ftpresultsetfactory.hxx"
      30             : #include "ftpresultsetI.hxx"
      31             : #include "ftpcontent.hxx"
      32             : #include "ftpcontentprovider.hxx"
      33             : #include "ftpdirp.hxx"
      34             : #include "ftpcontentidentifier.hxx"
      35             : #include "ftpcfunc.hxx"
      36             : #include "ftpstrcont.hxx"
      37             : #include "ftpintreq.hxx"
      38             : 
      39             : #include <memory>
      40             : #include <vector>
      41             : #include <string.h>
      42             : #include "curl.hxx"
      43             : #include <curl/easy.h>
      44             : #include <comphelper/processfactory.hxx>
      45             : #include <ucbhelper/cancelcommandexecution.hxx>
      46             : #include <ucbhelper/contentidentifier.hxx>
      47             : #include <ucbhelper/fd_inputstream.hxx>
      48             : #include <ucbhelper/propertyvalueset.hxx>
      49             : #include <ucbhelper/simpleauthenticationrequest.hxx>
      50             : #include <com/sun/star/lang/IllegalAccessException.hpp>
      51             : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
      52             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      53             : #include <com/sun/star/beans/Property.hpp>
      54             : #include <com/sun/star/beans/PropertyValue.hpp>
      55             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      56             : #include <com/sun/star/io/XActiveDataSink.hpp>
      57             : #include <com/sun/star/io/XOutputStream.hpp>
      58             : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      59             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      60             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      61             : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
      62             : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
      63             : #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
      64             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      65             : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
      66             : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
      67             : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      68             : #include <com/sun/star/ucb/NameClashException.hpp>
      69             : #include <com/sun/star/ucb/OpenMode.hpp>
      70             : #include <com/sun/star/ucb/IOErrorCode.hpp>
      71             : 
      72             : using namespace ftp;
      73             : using namespace com::sun::star::task;
      74             : using namespace com::sun::star::container;
      75             : using namespace com::sun::star::lang;
      76             : using namespace com::sun::star::uno;
      77             : using namespace com::sun::star::ucb;
      78             : using namespace com::sun::star::beans;
      79             : using namespace com::sun::star::io;
      80             : using namespace com::sun::star::sdbc;
      81             : 
      82             : 
      83             : // Content Implementation.
      84             : 
      85           2 : FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
      86             :                         FTPContentProvider* pProvider,
      87             :                         const Reference< XContentIdentifier >& Identifier,
      88             :                         const FTPURL& aFTPURL)
      89             :     : ContentImplHelper(rxContext,pProvider,Identifier)
      90             :     , m_pFCP(pProvider)
      91             :     , m_aFTPURL(aFTPURL)
      92             :     , m_bInserted(false)
      93           2 :     , m_bTitleSet(false)
      94             : {
      95           2 : }
      96             : 
      97           0 : FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
      98             :                         FTPContentProvider* pProvider,
      99             :                         const Reference< XContentIdentifier >& Identifier,
     100             :                         const ContentInfo& Info)
     101             :     : ContentImplHelper(rxContext,pProvider,Identifier)
     102             :     , m_pFCP(pProvider)
     103           0 :     , m_aFTPURL(Identifier->getContentIdentifier(), pProvider)
     104             :     , m_bInserted(true)
     105             :     , m_bTitleSet(false)
     106           0 :     , m_aInfo(Info)
     107             : {
     108           0 : }
     109             : 
     110           4 : FTPContent::~FTPContent()
     111             : {
     112           4 : }
     113             : 
     114             : // XInterface methods.
     115             : 
     116          17 : void SAL_CALL FTPContent::acquire()
     117             :     throw()
     118             : {
     119          17 :     OWeakObject::acquire();
     120          17 : }
     121             : 
     122          17 : void SAL_CALL FTPContent::release()
     123             :     throw()
     124             : {
     125          17 :     OWeakObject::release();
     126          17 : }
     127             : 
     128           6 : css::uno::Any SAL_CALL FTPContent::queryInterface( const css::uno::Type & rType )
     129             :     throw( css::uno::RuntimeException, std::exception )
     130             : {
     131             :     css::uno::Any aRet = cppu::queryInterface( rType,
     132             :                                                (static_cast< XTypeProvider* >(this)),
     133             :                                                (static_cast< XServiceInfo* >(this)),
     134             :                                                (static_cast< XContent* >(this)),
     135             :                                                (static_cast< XCommandProcessor* >(this)),
     136             :                                                (static_cast< XContentCreator* >(this)),
     137             :                                                (static_cast< XChild* >(this))
     138           6 :                                                );
     139           6 :     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
     140             : }
     141             : 
     142             : // XTypeProvider methods.
     143             : 
     144           0 : css::uno::Sequence< sal_Int8 > SAL_CALL FTPContent::getImplementationId()
     145             :     throw( css::uno::RuntimeException,
     146             :            std::exception )
     147             : {
     148           0 :     return css::uno::Sequence<sal_Int8>();
     149             : }
     150             : 
     151           0 : css::uno::Sequence< css::uno::Type > SAL_CALL FTPContent::getTypes()
     152             :     throw( css::uno::RuntimeException,
     153             :            std::exception )
     154             : {
     155             :     static cppu::OTypeCollection* pCollection = NULL;
     156           0 :     if ( !pCollection )
     157             :     {
     158           0 :         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
     159           0 :         if ( !pCollection )
     160             :         {
     161             :             static cppu::OTypeCollection collection(
     162           0 :                     cppu::UnoType<XTypeProvider>::get(),
     163           0 :                     cppu::UnoType<XServiceInfo>::get(),
     164           0 :                     cppu::UnoType<XContent>::get(),
     165           0 :                     cppu::UnoType<XCommandProcessor>::get(),
     166           0 :                     cppu::UnoType<XContentCreator>::get(),
     167           0 :                     cppu::UnoType<XChild>::get()
     168           0 :                 );
     169           0 :             pCollection = &collection;
     170           0 :         }
     171             :     }
     172           0 :     return (*pCollection).getTypes();
     173             : }
     174             : 
     175             : 
     176             : 
     177             : // XServiceInfo methods.
     178             : 
     179           0 : OUString SAL_CALL FTPContent::getImplementationName()
     180             :     throw( css::uno::RuntimeException, std::exception )
     181             : {
     182           0 :     return getImplementationName_Static();
     183             : }
     184             : 
     185           0 : OUString FTPContent::getImplementationName_Static()
     186             : {
     187           0 :     return OUString( "com.sun.star.comp.FTPContent");
     188             : }
     189             : 
     190           0 : sal_Bool SAL_CALL FTPContent::supportsService( const OUString& ServiceName )
     191             :     throw( css::uno::RuntimeException, std::exception )
     192             : {
     193           0 :     return cppu::supportsService( this, ServiceName );
     194             : }
     195             : 
     196           0 : css::uno::Sequence< OUString > SAL_CALL FTPContent::getSupportedServiceNames()
     197             :     throw( css::uno::RuntimeException, std::exception )
     198             : {
     199           0 :     return getSupportedServiceNames_Static();
     200             : }
     201             : 
     202           0 : css::uno::Sequence< OUString > FTPContent::getSupportedServiceNames_Static()
     203             : {
     204           0 :     css::uno::Sequence< OUString > aSNS( 1 );
     205           0 :     aSNS.getArray()[ 0 ] = "com.sun.star.ucb.FTPContent";
     206           0 :     return aSNS;
     207             : }
     208             : 
     209             : 
     210             : 
     211             : 
     212             : 
     213             : // XContent methods.
     214             : 
     215             : // virtual
     216           0 : OUString SAL_CALL FTPContent::getContentType()
     217             :     throw( RuntimeException, std::exception )
     218             : {
     219           0 :     return OUString(FTP_CONTENT_TYPE);
     220             : }
     221             : 
     222             : // XCommandProcessor methods.
     223             : 
     224             : //virtual
     225           0 : void SAL_CALL FTPContent::abort( sal_Int32 /*CommandId*/ )
     226             :     throw( RuntimeException, std::exception )
     227             : {
     228           0 : }
     229             : 
     230             : /***************************************************************************/
     231             : /*                                                                         */
     232             : /*                     Internal implementation class.                      */
     233             : /*                                                                         */
     234             : /***************************************************************************/
     235             : 
     236           0 : class ResultSetFactoryI : public ResultSetFactory
     237             : {
     238             : public:
     239             : 
     240           0 :     ResultSetFactoryI(const Reference<XComponentContext >&  rxContext,
     241             :                       const Reference<XContentProvider >&  xProvider,
     242             :                       sal_Int32 nOpenMode,
     243             :                       const Sequence<Property>& seq,
     244             :                       const Sequence<NumberedSortingInfo>& seqSort,
     245             :                       const std::vector<FTPDirentry>& dirvec)
     246             :         : m_xContext(rxContext),
     247             :           m_xProvider(xProvider),
     248             :           m_nOpenMode(nOpenMode),
     249             :           m_seq(seq),
     250             :           m_seqSort(seqSort),
     251           0 :           m_dirvec(dirvec)
     252             :     {
     253           0 :     }
     254             : 
     255           0 :     virtual ResultSetBase* createResultSet() SAL_OVERRIDE
     256             :     {
     257             :         return new ResultSetI(m_xContext,
     258             :                               m_xProvider,
     259             :                               m_nOpenMode,
     260             :                               m_seq,
     261             :                               m_seqSort,
     262           0 :                               m_dirvec);
     263             :     }
     264             : 
     265             : public:
     266             : 
     267             :     Reference< XComponentContext >                  m_xContext;
     268             :     Reference< XContentProvider >                   m_xProvider;
     269             :     sal_Int32                                       m_nOpenMode;
     270             :     Sequence< Property >                            m_seq;
     271             :     Sequence< NumberedSortingInfo >                 m_seqSort;
     272             :     std::vector<FTPDirentry>                        m_dirvec;
     273             : };
     274             : 
     275             : // XCommandProcessor methods.
     276             : 
     277             : enum ACTION { NOACTION,
     278             :               THROWAUTHENTICATIONREQUEST,
     279             :               THROWACCESSDENIED,
     280             :               THROWINTERACTIVECONNECT,
     281             :               THROWRESOLVENAME,
     282             :               THROWQUOTE,
     283             :               THROWNOFILE,
     284             :               THROWGENERAL };
     285             : 
     286             : // virtual
     287           1 : Any SAL_CALL FTPContent::execute( const Command& aCommand,
     288             :                                   sal_Int32 /*CommandId*/,
     289             :                                   const Reference<
     290             :                                   XCommandEnvironment >& Environment)
     291             :     throw( Exception,
     292             :            CommandAbortedException,
     293             :            RuntimeException,
     294             :            std::exception)
     295             : {
     296           1 :     ACTION action(NOACTION);
     297           1 :     Any aRet;
     298             : 
     299             :     while(true)
     300             :     {
     301             :         try
     302             :         {
     303           2 :             if(action == THROWAUTHENTICATIONREQUEST)
     304             :             {
     305             :                 // try to get a continuation first
     306           0 :                 OUString aRealm,aPassword,aAccount;
     307             :                 m_pFCP->forHost(m_aFTPURL.host(),
     308             :                                 m_aFTPURL.port(),
     309             :                                 m_aFTPURL.username(),
     310             :                                 aPassword,
     311           0 :                                 aAccount);
     312             :                 rtl::Reference<ucbhelper::SimpleAuthenticationRequest>
     313             :                     p( new ucbhelper::SimpleAuthenticationRequest(
     314             :                         m_aFTPURL.ident(false, false),
     315             :                         m_aFTPURL.host(),      // ServerName
     316             :                         ucbhelper::SimpleAuthenticationRequest::ENTITY_NA,
     317             :                         aRealm,
     318             :                         ucbhelper::SimpleAuthenticationRequest
     319             :                         ::ENTITY_FIXED,
     320             :                         m_aFTPURL.username(),
     321             :                         ucbhelper::SimpleAuthenticationRequest
     322             :                         ::ENTITY_MODIFY,
     323           0 :                         aPassword));
     324             : 
     325           0 :                 Reference<XInteractionHandler> xInteractionHandler;
     326           0 :                 if(Environment.is())
     327           0 :                     xInteractionHandler =
     328           0 :                         Environment->getInteractionHandler();
     329             : 
     330           0 :                 if( xInteractionHandler.is()) {
     331           0 :                     xInteractionHandler->handle(p.get());
     332             : 
     333             :                     Reference<XInterface> xSelection(
     334           0 :                         p->getSelection().get());
     335             : 
     336           0 :                     if(Reference<XInteractionRetry>(
     337           0 :                         xSelection,UNO_QUERY).is())
     338           0 :                         action = NOACTION;
     339           0 :                     else if(Reference<XInteractionSupplyAuthentication>(
     340           0 :                         xSelection,UNO_QUERY).is()) {
     341             :                         m_pFCP->setHost(
     342             :                             m_aFTPURL.host(),
     343             :                             m_aFTPURL.port(),
     344             :                             m_aFTPURL.username(),
     345           0 :                             p->getAuthenticationSupplier()->getPassword(),
     346           0 :                             aAccount);
     347           0 :                         action = NOACTION;
     348           0 :                     }
     349             :                 }
     350           0 :                 aRet = p->getRequest();
     351             :             }
     352             : 
     353             : //              if(aCommand.Name.equalsAscii(
     354             : //                  "getPropertyValues") &&
     355             : //                 action != NOACTION) {
     356             : //                  // It is not allowed to throw if
     357             : //                  // command is getPropertyValues
     358             : //                  rtl::Reference<ucbhelper::PropertyValueSet> xRow =
     359             : //                      new ucbhelper::PropertyValueSet(m_xSMgr);
     360             : //                  Sequence<Property> Properties;
     361             : //                  aCommand.Argument >>= Properties;
     362             : //                  for(int i = 0; i < Properties.getLength(); ++i)
     363             : //                      xRow->appendVoid(Properties[i]);
     364             : //                  aRet <<= Reference<XRow>(xRow.get());
     365             : //                  return aRet;
     366             : //              }
     367             : 
     368           2 :             switch (action)
     369             :             {
     370             :             case NOACTION:
     371           1 :                 break;
     372             : 
     373             :             case THROWAUTHENTICATIONREQUEST:
     374             :                 ucbhelper::cancelCommandExecution(
     375             :                     aRet,
     376           0 :                     Reference<XCommandEnvironment>(0));
     377           0 :                 break;
     378             : 
     379             :             case THROWACCESSDENIED:
     380             :                 {
     381           0 :                     Sequence<Any> seq(1);
     382           0 :                     PropertyValue value;
     383           0 :                     value.Name = "Uri";
     384           0 :                     value.Handle = -1;
     385           0 :                     value.Value <<= m_aFTPURL.ident(false,false);
     386           0 :                     value.State = PropertyState_DIRECT_VALUE;
     387           0 :                     seq[0] <<= value;
     388             :                     ucbhelper::cancelCommandExecution(
     389             :                         IOErrorCode_ACCESS_DENIED,
     390             :                         seq,
     391           0 :                         Environment);
     392           0 :                     break;
     393             :                 }
     394             :             case THROWINTERACTIVECONNECT:
     395             :                 {
     396           0 :                     InteractiveNetworkConnectException excep;
     397           0 :                     excep.Server = m_aFTPURL.host();
     398           0 :                     aRet <<= excep;
     399             :                     ucbhelper::cancelCommandExecution(
     400             :                         aRet,
     401           0 :                         Environment);
     402           0 :                     break;
     403             :                 }
     404             :             case THROWRESOLVENAME:
     405             :                 {
     406           1 :                     InteractiveNetworkResolveNameException excep;
     407           1 :                     excep.Server = m_aFTPURL.host();
     408           1 :                     aRet <<= excep;
     409             :                     ucbhelper::cancelCommandExecution(
     410             :                         aRet,
     411           1 :                         Environment);
     412           1 :                     break;
     413             :                 }
     414             :             case THROWNOFILE:
     415             :                 {
     416           0 :                     Sequence<Any> seq(1);
     417           0 :                     PropertyValue value;
     418           0 :                     value.Name = "Uri";
     419           0 :                     value.Handle = -1;
     420           0 :                     value.Value <<= m_aFTPURL.ident(false,false);
     421           0 :                     value.State = PropertyState_DIRECT_VALUE;
     422           0 :                     seq[0] <<= value;
     423             :                     ucbhelper::cancelCommandExecution(
     424             :                         IOErrorCode_NO_FILE,
     425             :                         seq,
     426           0 :                         Environment);
     427           0 :                     break;
     428             :                 }
     429             :             case THROWQUOTE:
     430             :             case THROWGENERAL:
     431             :                 ucbhelper::cancelCommandExecution(
     432             :                     IOErrorCode_GENERAL,
     433             :                     Sequence<Any>(0),
     434           0 :                     Environment);
     435           0 :                 break;
     436             :             }
     437             : 
     438           1 :             if(aCommand.Name == "getPropertyValues") {
     439           0 :                 Sequence<Property> Properties;
     440           0 :                 if(!(aCommand.Argument >>= Properties))
     441             :                 {
     442           0 :                     aRet <<= IllegalArgumentException(
     443             :                                 OUString( "Wrong argument type!" ),
     444             :                                 static_cast< cppu::OWeakObject * >(this),
     445           0 :                                 -1);
     446           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     447             :                 }
     448             : 
     449           0 :                 aRet <<= getPropertyValues(Properties,Environment);
     450             :             }
     451           1 :             else if(aCommand.Name == "setPropertyValues")
     452             :             {
     453           0 :                 Sequence<PropertyValue> propertyValues;
     454             : 
     455           0 :                 if( ! ( aCommand.Argument >>= propertyValues ) ) {
     456           0 :                     aRet <<= IllegalArgumentException(
     457             :                                 OUString( "Wrong argument type!" ),
     458             :                                 static_cast< cppu::OWeakObject * >(this),
     459           0 :                                 -1);
     460           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     461             :                 }
     462             : 
     463           0 :                 aRet <<= setPropertyValues(propertyValues);
     464             :             }
     465           1 :             else if(aCommand.Name == "getCommandInfo") {
     466             :                 // Note: Implemented by base class.
     467           0 :                 aRet <<= getCommandInfo(Environment);
     468             :             }
     469           1 :             else if(aCommand.Name == "getPropertySetInfo") {
     470             :                 // Note: Implemented by base class.
     471           0 :                 aRet <<= getPropertySetInfo(Environment);
     472             :             }
     473           1 :             else if(aCommand.Name == "insert")
     474             :             {
     475           0 :                 InsertCommandArgument aInsertArgument;
     476           0 :                 if ( ! ( aCommand.Argument >>= aInsertArgument ) ) {
     477           0 :                     aRet <<= IllegalArgumentException(
     478             :                                 OUString( "Wrong argument type!" ),
     479             :                                 static_cast< cppu::OWeakObject * >(this),
     480           0 :                                 -1);
     481           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     482             :                 }
     483           0 :                 insert(aInsertArgument,Environment);
     484             :             }
     485           1 :             else if(aCommand.Name == "delete") {
     486           0 :                 m_aFTPURL.del();
     487           0 :                 deleted();
     488             :             }
     489           1 :             else if(aCommand.Name == "open") {
     490           1 :                 OpenCommandArgument2 aOpenCommand;
     491           1 :                 if ( !( aCommand.Argument >>= aOpenCommand ) ) {
     492           0 :                     aRet <<= IllegalArgumentException(
     493             :                                 OUString( "Wrong argument type!" ),
     494             :                                 static_cast< cppu::OWeakObject * >(this),
     495           0 :                                 -1);
     496             : 
     497           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     498             :                 }
     499             : 
     500           1 :                 if(aOpenCommand.Mode == OpenMode::DOCUMENT) {
     501             :                     // Open as a document
     502             :                     Reference<XActiveDataSink>
     503           0 :                         xActiveDataSink(aOpenCommand.Sink,UNO_QUERY);
     504             :                     Reference< XOutputStream >
     505           0 :                         xOutputStream(aOpenCommand.Sink,UNO_QUERY);
     506             : 
     507           0 :                     if(xActiveDataSink.is()) {
     508           0 :                         xActiveDataSink->setInputStream(
     509           0 :                             new ucbhelper::FdInputStream(m_aFTPURL.open()));
     510             :                     }
     511           0 :                     else if(xOutputStream.is()) {
     512             :                         Reference<XInputStream> xStream(
     513           0 :                             new ucbhelper::FdInputStream(m_aFTPURL.open()));
     514           0 :                         Sequence<sal_Int8> byte_seq(4096);
     515           0 :                         sal_Int32 n = 1000; // value does not matter here
     516             :                         for (;;) {
     517           0 :                             n = xStream->readBytes(byte_seq,4096);
     518           0 :                             if (n == 0) {
     519           0 :                                 break;
     520             :                             }
     521             :                             try {
     522           0 :                                 if(byte_seq.getLength() != n)
     523           0 :                                     byte_seq.realloc(n);
     524           0 :                                 xOutputStream->writeBytes(byte_seq);
     525           0 :                             } catch(const NotConnectedException&) {
     526             : 
     527           0 :                             } catch(const BufferSizeExceededException&) {
     528             : 
     529           0 :                             } catch(const IOException&) {
     530             : 
     531             :                             }
     532           0 :                         }
     533           0 :                         if(n) {
     534           0 :                             Sequence<Any> seq(1);
     535           0 :                             PropertyValue value;
     536           0 :                             value.Name = "Uri";
     537           0 :                             value.Handle = -1;
     538           0 :                             value.Value <<= m_aFTPURL.ident(false,false);
     539           0 :                             value.State = PropertyState_DIRECT_VALUE;
     540           0 :                             seq[0] <<= value;
     541             :                             ucbhelper::cancelCommandExecution(
     542             :                                 IOErrorCode_UNKNOWN,
     543             :                                 seq,
     544           0 :                                 Environment);
     545           0 :                         }
     546             :                     }
     547             :                     else {
     548           0 :                         aRet <<= UnsupportedDataSinkException(
     549             :                             OUString(),
     550             :                             static_cast< cppu::OWeakObject * >(this),
     551           0 :                             aOpenCommand.Sink);
     552           0 :                         ucbhelper::cancelCommandExecution(aRet,Environment);
     553           0 :                     }
     554             :                 }
     555           1 :                 else if(aOpenCommand.Mode == OpenMode::ALL ||
     556           0 :                         aOpenCommand.Mode == OpenMode::DOCUMENTS ||
     557           0 :                         aOpenCommand.Mode == OpenMode::FOLDERS ) {
     558             :                     std::vector<FTPDirentry> resvec =
     559           1 :                         m_aFTPURL.list(sal_Int16(aOpenCommand.Mode));
     560             :                     Reference< XDynamicResultSet > xSet
     561             :                         = new DynamicResultSet(
     562             :                             m_xContext,
     563             :                             this,
     564             :                             aOpenCommand,
     565             :                             Environment,
     566             :                             new ResultSetFactoryI(m_xContext,
     567           0 :                                                   m_xProvider.get(),
     568             :                                                   aOpenCommand.Mode,
     569             :                                                   aOpenCommand.Properties,
     570             :                                                   aOpenCommand.SortingInfo,
     571           0 :                                                   resvec));
     572           0 :                     aRet <<= xSet;
     573             :                 }
     574           0 :                 else if(aOpenCommand.Mode ==
     575           0 :                         OpenMode::DOCUMENT_SHARE_DENY_NONE ||
     576           0 :                         aOpenCommand.Mode ==
     577             :                         OpenMode::DOCUMENT_SHARE_DENY_WRITE) {
     578             :                     // Unsupported OpenMode
     579           0 :                     aRet <<= UnsupportedOpenModeException(
     580             :                         OUString(),
     581             :                         static_cast< cppu::OWeakObject * >(this),
     582           0 :                         static_cast< sal_Int16 >(aOpenCommand.Mode));
     583           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     584             :                 }
     585             :                 else {
     586           0 :                     aRet <<= IllegalArgumentException(
     587             :                                 OUString( "Unexpected OpenMode!" ),
     588             :                                 static_cast< cppu::OWeakObject * >(this),
     589           0 :                                 -1);
     590             : 
     591           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     592           1 :                 }
     593           0 :             } else if(aCommand.Name == "createNewContent") {
     594           0 :                 ContentInfo aArg;
     595           0 :                 if (!(aCommand.Argument >>= aArg)) {
     596             :                     ucbhelper::cancelCommandExecution(
     597             :                         makeAny(
     598             :                             IllegalArgumentException(
     599             :                                 OUString( "Wrong argument type!" ),
     600             :                                 static_cast< cppu::OWeakObject * >(this),
     601             :                                 -1)),
     602           0 :                         Environment);
     603             :                     // Unreachable
     604             :                 }
     605           0 :                 aRet <<= createNewContent(aArg);
     606             :             } else {
     607           0 :                 aRet <<= UnsupportedCommandException(
     608             :                     aCommand.Name,
     609           0 :                     static_cast< cppu::OWeakObject * >(this));
     610           0 :                 ucbhelper::cancelCommandExecution(aRet,Environment);
     611             :             }
     612             : 
     613           0 :             return aRet;
     614             :         }
     615           2 :         catch(const curl_exception& e)
     616             :         {
     617           1 :             if(e.code() == CURLE_COULDNT_CONNECT)
     618           0 :                 action = THROWINTERACTIVECONNECT;
     619           1 :             else if(e.code() == CURLE_COULDNT_RESOLVE_HOST )
     620           1 :                 action = THROWRESOLVENAME;
     621           0 :             else if(e.code() == CURLE_FTP_USER_PASSWORD_INCORRECT ||
     622           0 :                     e.code() == CURLE_LOGIN_DENIED ||
     623           0 :                     e.code() == CURLE_BAD_PASSWORD_ENTERED ||
     624           0 :                     e.code() == CURLE_FTP_WEIRD_PASS_REPLY)
     625           0 :                 action = THROWAUTHENTICATIONREQUEST;
     626           0 :             else if(e.code() == CURLE_FTP_ACCESS_DENIED)
     627           0 :                 action = THROWACCESSDENIED;
     628           0 :             else if(e.code() == CURLE_FTP_QUOTE_ERROR)
     629           0 :                 action = THROWQUOTE;
     630           0 :             else if(e.code() == CURLE_FTP_COULDNT_RETR_FILE)
     631           0 :                 action = THROWNOFILE;
     632             :             else
     633             :                 // nothing known about the cause of the error
     634           0 :                 action = THROWGENERAL;
     635             :         }
     636             :     }
     637             : }
     638             : 
     639             : #define FTP_FILE "application/vnd.sun.staroffice.ftp-file"
     640             : 
     641             : #define FTP_FOLDER "application/vnd.sun.staroffice.ftp-folder"
     642             : 
     643             : Sequence<ContentInfo > SAL_CALL
     644           0 : FTPContent::queryCreatableContentsInfo(  )
     645             :     throw (RuntimeException, std::exception)
     646             : {
     647           0 :     return queryCreatableContentsInfo_Static();
     648             : }
     649             : 
     650             : // static
     651             : Sequence<ContentInfo >
     652           0 : FTPContent::queryCreatableContentsInfo_Static(  )
     653             :     throw (RuntimeException)
     654             : {
     655           0 :     Sequence< ContentInfo > seq(2);
     656             : 
     657           0 :     seq[0].Type = FTP_FILE;
     658           0 :     seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
     659           0 :         | ContentInfoAttribute::KIND_DOCUMENT;
     660           0 :     Sequence< Property > props( 1 );
     661           0 :     props[0] = Property(
     662             :         OUString("Title"),
     663             :         -1,
     664           0 :         cppu::UnoType<OUString>::get(),
     665             :         PropertyAttribute::MAYBEVOID
     666           0 :         | PropertyAttribute::BOUND );
     667           0 :     seq[0].Properties = props;
     668             : 
     669             :     // folder
     670           0 :     seq[1].Type       = FTP_FOLDER;
     671           0 :     seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
     672           0 :     seq[1].Properties = props;
     673             : 
     674           0 :     return seq;
     675             : }
     676             : 
     677             : Reference<XContent > SAL_CALL
     678           0 : FTPContent::createNewContent( const ContentInfo& Info )
     679             :     throw (RuntimeException, std::exception)
     680             : {
     681           0 :     if( Info.Type =="application/vnd.sun.staroffice.ftp-file" || Info.Type == "application/vnd.sun.staroffice.ftp-folder" )
     682             :         return new FTPContent(m_xContext,
     683             :                               m_pFCP,
     684           0 :                               m_xIdentifier,Info);
     685             :     else
     686           0 :         return Reference<XContent>(0);
     687             : }
     688             : 
     689             : 
     690             : 
     691             : 
     692             : Reference<XInterface > SAL_CALL
     693           0 : FTPContent::getParent(  )
     694             :     throw (RuntimeException, std::exception)
     695             : {
     696             :     Reference<XContentIdentifier>
     697           0 :         xIdent(new FTPContentIdentifier(m_aFTPURL.parent(false)));
     698           0 :     return Reference<XInterface>( m_xProvider->queryContent(xIdent), UNO_QUERY );
     699             : }
     700             : 
     701             : 
     702             : void SAL_CALL
     703           0 : FTPContent::setParent(const Reference<XInterface >& /*Parent*/ )
     704             :     throw (NoSupportException,
     705             :            RuntimeException, std::exception)
     706             : {
     707           0 :     throw NoSupportException();
     708             : }
     709             : 
     710             : 
     711             : 
     712           0 : OUString FTPContent::getParentURL()
     713             : {
     714           0 :     return m_aFTPURL.parent();
     715             : }
     716             : 
     717             : 
     718             : class InsertData
     719             :     : public CurlInput {
     720             : 
     721             : public:
     722             : 
     723           0 :     explicit InsertData(const Reference<XInputStream>& xInputStream)
     724           0 :         : m_xInputStream(xInputStream) { }
     725           0 :     virtual ~InsertData() {}
     726             : 
     727             :     // returns the number of bytes actually read
     728             :     virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested) SAL_OVERRIDE;
     729             : 
     730             : private:
     731             : 
     732             :     Reference<XInputStream> m_xInputStream;
     733             : };
     734             : 
     735             : 
     736             : 
     737           0 : sal_Int32 InsertData::read(sal_Int8 *dest,sal_Int32 nBytesRequested)
     738             : {
     739           0 :     sal_Int32 m = 0;
     740             : 
     741           0 :     if(m_xInputStream.is()) {
     742           0 :             Sequence<sal_Int8> seq(nBytesRequested);
     743           0 :         m = m_xInputStream->readBytes(seq,nBytesRequested);
     744           0 :         memcpy(dest,seq.getConstArray(),m);
     745             :     }
     746           0 :     return m;
     747             : }
     748             : 
     749             : 
     750           0 : void FTPContent::insert(const InsertCommandArgument& aInsertCommand,
     751             :                         const Reference<XCommandEnvironment>& Env)
     752             : {
     753           0 :     osl::MutexGuard aGuard(m_aMutex);
     754             : 
     755           0 :     if(m_bInserted && !m_bTitleSet) {
     756           0 :         MissingPropertiesException excep;
     757           0 :         excep.Properties.realloc(1);
     758           0 :         excep.Properties[0] = "Title";
     759           0 :         Any aAny; aAny <<= excep;
     760           0 :         ucbhelper::cancelCommandExecution(aAny,Env);
     761             :     }
     762             : 
     763           0 :     if(m_bInserted &&
     764           0 :        m_aInfo.Type == FTP_FILE &&
     765           0 :        !aInsertCommand.Data.is())
     766             :     {
     767           0 :         MissingInputStreamException excep;
     768           0 :         Any aAny; aAny <<= excep;
     769           0 :         ucbhelper::cancelCommandExecution(aAny,Env);
     770             :     }
     771             : 
     772           0 :     bool bReplace(aInsertCommand.ReplaceExisting);
     773             : 
     774             :  retry:
     775             :     try {
     776           0 :         if(m_aInfo.Type == FTP_FILE) {
     777           0 :             InsertData data(aInsertCommand.Data);
     778           0 :             m_aFTPURL.insert(bReplace,&data);
     779           0 :         } else if(m_aInfo.Type == FTP_FOLDER)
     780           0 :             m_aFTPURL.mkdir(bReplace);
     781           0 :     } catch(const curl_exception& e) {
     782           0 :         if(e.code() == FILE_EXIST_DURING_INSERT ||
     783           0 :            e.code() == FOLDER_EXIST_DURING_INSERT) {
     784             :             // Deprecated, not used anymore:
     785           0 :             NameClashException excep;
     786           0 :             excep.Name = m_aFTPURL.child();
     787           0 :             Any aAny;
     788           0 :             aAny <<= excep;
     789           0 :             ucbhelper::cancelCommandExecution(aAny,Env);
     790           0 :         } else if(e.code() == FOLDER_MIGHT_EXIST_DURING_INSERT ||
     791           0 :                   e.code() == FILE_MIGHT_EXIST_DURING_INSERT) {
     792             :             // Interact
     793           0 :             Reference<XInteractionHandler> xInt;
     794           0 :             if(Env.is())
     795           0 :                 xInt = Env->getInteractionHandler();
     796             : 
     797           0 :             UnsupportedNameClashException excep;
     798           0 :             excep.NameClash = 0; //NameClash::ERROR;
     799             : 
     800           0 :             if(!xInt.is()) {
     801           0 :                 Any aAny;
     802           0 :                 aAny <<= excep;
     803           0 :                 ucbhelper::cancelCommandExecution(aAny,Env);
     804             :             }
     805             : 
     806           0 :             XInteractionRequestImpl* p = new XInteractionRequestImpl;
     807           0 :             Reference<XInteractionRequest> req(p);
     808           0 :             xInt->handle(req);
     809           0 :             if(p->approved()) {
     810           0 :                 bReplace = true;
     811           0 :                 goto retry;
     812             :             }
     813             :             else
     814           0 :                 throw excep;
     815             :         }
     816             :         else
     817           0 :             throw;
     818           0 :     }
     819             : 
     820             :     // May not be reached, because both mkdir and insert can throw curl-
     821             :     // exceptions
     822           0 :     m_bInserted = false;
     823           0 :     inserted();
     824           0 : }
     825             : 
     826             : 
     827             : 
     828           0 : Reference< XRow > FTPContent::getPropertyValues(
     829             :     const Sequence< Property >& seqProp,
     830             :     const Reference<XCommandEnvironment>& /*environment*/
     831             : )
     832             : {
     833             :     rtl::Reference<ucbhelper::PropertyValueSet> xRow =
     834           0 :         new ucbhelper::PropertyValueSet(m_xContext);
     835             : 
     836           0 :     FTPDirentry aDirEntry = m_aFTPURL.direntry();
     837             : 
     838           0 :     for(sal_Int32 i = 0; i < seqProp.getLength(); ++i) {
     839           0 :         const OUString& Name = seqProp[i].Name;
     840           0 :         if(Name == "Title")
     841           0 :             xRow->appendString(seqProp[i],aDirEntry.m_aName);
     842           0 :         else if(Name == "CreatableContentsInfo")
     843           0 :             xRow->appendObject(seqProp[i],
     844           0 :                                makeAny(queryCreatableContentsInfo()));
     845           0 :         else if(aDirEntry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN) {
     846           0 :             if(Name == "ContentType")
     847           0 :                 xRow->appendString(seqProp[i],
     848           0 :                                    aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR
     849             :                                    ? OUString(FTP_FOLDER)
     850           0 :                                    : OUString(FTP_FILE) );
     851           0 :             else if(Name == "IsReadOnly")
     852           0 :                 xRow->appendBoolean(seqProp[i],
     853             :                                     (aDirEntry.m_nMode
     854           0 :                                      & INETCOREFTP_FILEMODE_WRITE) == 0 );
     855           0 :             else if(Name == "IsDocument")
     856           0 :                 xRow->appendBoolean(seqProp[i],
     857           0 :                                     (aDirEntry.m_nMode &
     858           0 :                                                INETCOREFTP_FILEMODE_ISDIR) != INETCOREFTP_FILEMODE_ISDIR);
     859           0 :             else if(Name == "IsFolder")
     860           0 :                 xRow->appendBoolean(seqProp[i],
     861           0 :                                     (aDirEntry.m_nMode &
     862           0 :                                              INETCOREFTP_FILEMODE_ISDIR) == INETCOREFTP_FILEMODE_ISDIR);
     863           0 :             else if(Name == "Size")
     864           0 :                 xRow->appendLong(seqProp[i],
     865           0 :                                  aDirEntry.m_nSize);
     866           0 :             else if(Name == "DateCreated")
     867           0 :                 xRow->appendTimestamp(seqProp[i],
     868           0 :                                       aDirEntry.m_aDate);
     869             :             else
     870           0 :                 xRow->appendVoid(seqProp[i]);
     871             :         } else
     872           0 :             xRow->appendVoid(seqProp[i]);
     873             :     }
     874             : 
     875           0 :     return Reference<XRow>(xRow.get());
     876             : }
     877             : 
     878             : 
     879             : 
     880           0 : Sequence<Any> FTPContent::setPropertyValues(
     881             :     const Sequence<PropertyValue>& seqPropVal)
     882             : {
     883           0 :     Sequence<Any> ret(seqPropVal.getLength());
     884           0 :     Sequence<PropertyChangeEvent > evt;
     885             : 
     886           0 :     osl::MutexGuard aGuard(m_aMutex);
     887           0 :     for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
     888           0 :         if ( seqPropVal[i].Name == "Title" ) {
     889           0 :             OUString Title;
     890           0 :             if(!(seqPropVal[i].Value >>= Title)) {
     891           0 :                 ret[i] <<= IllegalTypeException();
     892           0 :                 continue;
     893           0 :             } else if(Title.isEmpty()) {
     894           0 :                 ret[i] <<= IllegalArgumentException();
     895           0 :                 continue;
     896             :             }
     897             : 
     898           0 :             if(m_bInserted) {
     899           0 :                 m_aFTPURL.child(Title);
     900           0 :                 m_xIdentifier =
     901           0 :                     new FTPContentIdentifier(m_aFTPURL.ident(false,false));
     902           0 :                 m_bTitleSet = true;
     903             :             } else
     904             :                 try {
     905           0 :                     OUString OldTitle = m_aFTPURL.ren(Title);
     906           0 :                     evt.realloc(1);
     907           0 :                     evt[0].PropertyName = "Title";
     908           0 :                     evt[0].Further = false;
     909           0 :                     evt[0].PropertyHandle = -1;
     910           0 :                     evt[0].OldValue <<= OldTitle;
     911           0 :                     evt[0].NewValue <<= Title;
     912           0 :                 } catch(const curl_exception&) {
     913           0 :                     InteractiveIOException excep;
     914             :                     // any better possibility here?
     915             :                     // ( the error code is always CURLE_FTP_QUOTE_ERROR )
     916           0 :                     excep.Code = IOErrorCode_ACCESS_DENIED;
     917           0 :                     ret[i] <<= excep;
     918           0 :                 }
     919             :         } else {
     920             :             Sequence<Property> props =
     921           0 :                 getProperties(Reference<XCommandEnvironment>(0));
     922             : 
     923             :             // either unknown or read-only
     924           0 :             ret[i] <<= UnknownPropertyException();
     925           0 :             for(sal_Int32 j = 0; j < props.getLength(); ++j)
     926           0 :                 if(props[j].Name == seqPropVal[i].Name) {
     927           0 :                     ret[i] <<= IllegalAccessException(
     928             :                         OUString( "Property is read-only!"),
     929             :                             //props[j].Attributes & PropertyAttribute::READONLY
     930             :                             //    ? "Property is read-only!"
     931             :                             //    : "Access denied!"),
     932           0 :                         static_cast< cppu::OWeakObject * >( this ));
     933           0 :                     break;
     934           0 :                 }
     935             :         }
     936             :     }
     937             : 
     938           0 :     if(evt.getLength()) {
     939             :         // title has changed
     940           0 :         notifyPropertiesChange(evt);
     941           0 :         (void)exchange(new FTPContentIdentifier(m_aFTPURL.ident(false,false)));
     942             :     }
     943             : 
     944           0 :     return ret;
     945             : }
     946             : 
     947             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11