LCOV - code coverage report
Current view: top level - ucb/source/core - ucbcmds.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 262 606 43.2 %
Date: 2014-11-03 Functions: 19 33 57.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 <osl/diagnose.h>
      27             : #include <comphelper/processfactory.hxx>
      28             : #include <cppuhelper/implbase1.hxx>
      29             : #include <cppuhelper/exc_hlp.hxx>
      30             : #include <rtl/ustring.h>
      31             : #include <rtl/ustring.hxx>
      32             : #include <com/sun/star/uno/XInterface.hpp>
      33             : #include <com/sun/star/beans/PropertyState.hpp>
      34             : #include <com/sun/star/beans/PropertyValue.hpp>
      35             : #include <com/sun/star/container/XChild.hpp>
      36             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      37             : #include <com/sun/star/io/Pipe.hpp>
      38             : #include <com/sun/star/io/XActiveDataSink.hpp>
      39             : #include <com/sun/star/io/XOutputStream.hpp>
      40             : #include <com/sun/star/io/XSeekable.hpp>
      41             : #include <com/sun/star/sdbc/XRow.hpp>
      42             : #include <com/sun/star/task/XInteractionHandler.hpp>
      43             : #include <com/sun/star/ucb/CommandEnvironment.hpp>
      44             : #include <com/sun/star/ucb/CommandFailedException.hpp>
      45             : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
      46             : #include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
      47             : #include <com/sun/star/ucb/InsertCommandArgument2.hpp>
      48             : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
      49             : #include <com/sun/star/ucb/NameClash.hpp>
      50             : #include <com/sun/star/ucb/NameClashException.hpp>
      51             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      52             : #include <com/sun/star/ucb/OpenMode.hpp>
      53             : #include <com/sun/star/ucb/TransferInfo2.hpp>
      54             : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      55             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      56             : #include <com/sun/star/ucb/XContentAccess.hpp>
      57             : #include <com/sun/star/ucb/XContentCreator.hpp>
      58             : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
      59             : #include <com/sun/star/ucb/XInteractionSupplyName.hpp>
      60             : #include <com/sun/star/uno/Any.hxx>
      61             : #include <com/sun/star/uno/Sequence.hxx>
      62             : #include <ucbhelper/cancelcommandexecution.hxx>
      63             : #include <ucbhelper/simplenameclashresolverequest.hxx>
      64             : #include "ucbcmds.hxx"
      65             : #include "ucb.hxx"
      66             : 
      67             : using namespace com::sun::star;
      68             : 
      69             : namespace
      70             : {
      71             : 
      72             : 
      73             : 
      74             : // struct TransferCommandContext.
      75             : 
      76             : 
      77             : 
      78          12 : struct TransferCommandContext
      79             : {
      80             :     uno::Reference< uno::XComponentContext >     m_xContext;
      81             :     uno::Reference< ucb::XCommandProcessor >     xProcessor;
      82             :     uno::Reference< ucb::XCommandEnvironment >   xEnv;
      83             :     uno::Reference< ucb::XCommandEnvironment >   xOrigEnv;
      84             :     ucb::GlobalTransferCommandArgument2          aArg;
      85             : 
      86          12 :     TransferCommandContext(
      87             :         const uno::Reference< uno::XComponentContext > & xContext,
      88             :         const uno::Reference< ucb::XCommandProcessor > & rxProcessor,
      89             :         const uno::Reference< ucb::XCommandEnvironment > & rxEnv,
      90             :         const uno::Reference< ucb::XCommandEnvironment > & rxOrigEnv,
      91             :         const ucb::GlobalTransferCommandArgument2 & rArg )
      92             :     : m_xContext( xContext ), xProcessor( rxProcessor ), xEnv( rxEnv ),
      93          12 :       xOrigEnv( rxOrigEnv ), aArg( rArg ) {}
      94             : };
      95             : 
      96             : 
      97             : 
      98             : // class InteractionHandlerProxy.
      99             : 
     100             : 
     101             : 
     102          12 : class InteractionHandlerProxy :
     103             :     public cppu::WeakImplHelper1< task::XInteractionHandler >
     104             : {
     105             :     uno::Reference< task::XInteractionHandler > m_xOrig;
     106             : 
     107             : public:
     108           6 :     InteractionHandlerProxy(
     109             :         const uno::Reference< task::XInteractionHandler > & xOrig )
     110           6 :     : m_xOrig( xOrig ) {}
     111             : 
     112             :     // XInteractionHandler methods.
     113             :     virtual void SAL_CALL handle(
     114             :             const uno::Reference< task::XInteractionRequest >& Request )
     115             :         throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     116             : };
     117             : 
     118             : 
     119             : // virtual
     120           4 : void SAL_CALL InteractionHandlerProxy::handle(
     121             :             const uno::Reference< task::XInteractionRequest >& Request )
     122             :     throw ( uno::RuntimeException, std::exception )
     123             : {
     124           4 :     if ( !m_xOrig.is() )
     125           6 :         return;
     126             : 
     127             :     // Filter unwanted requests by just not handling them.
     128           2 :     uno::Any aRequest = Request->getRequest();
     129             : 
     130             :     // "transfer"
     131           2 :     ucb::InteractiveBadTransferURLException aBadTransferURLEx;
     132           2 :     if ( aRequest >>= aBadTransferURLEx )
     133             :     {
     134           2 :         return;
     135             :     }
     136             :     else
     137             :     {
     138             :         // "transfer"
     139           0 :         ucb::UnsupportedNameClashException aUnsupportedNameClashEx;
     140           0 :         if ( aRequest >>= aUnsupportedNameClashEx )
     141             :         {
     142           0 :             if ( aUnsupportedNameClashEx.NameClash
     143           0 :                     != ucb::NameClash::ERROR )
     144           0 :                 return;
     145             :         }
     146             :         else
     147             :         {
     148             :             // "insert"
     149           0 :             ucb::NameClashException aNameClashEx;
     150           0 :             if ( aRequest >>= aNameClashEx )
     151             :             {
     152           0 :                 return;
     153             :             }
     154             :             else
     155             :             {
     156             :                 // "transfer"
     157           0 :                 ucb::UnsupportedCommandException aUnsupportedCommandEx;
     158           0 :                 if ( aRequest >>= aUnsupportedCommandEx )
     159             :                 {
     160           0 :                     return;
     161           0 :                 }
     162           0 :             }
     163           0 :         }
     164             :     }
     165             : 
     166             :     // not filtered; let the original handler do the work.
     167           0 :     m_xOrig->handle( Request );
     168             : }
     169             : 
     170             : 
     171             : 
     172             : // class ActiveDataSink.
     173             : 
     174             : 
     175             : 
     176          36 : class ActiveDataSink : public cppu::WeakImplHelper1< io::XActiveDataSink >
     177             : {
     178             :     uno::Reference< io::XInputStream > m_xStream;
     179             : 
     180             : public:
     181             :     // XActiveDataSink methods.
     182             :     virtual void SAL_CALL setInputStream(
     183             :                         const uno::Reference< io::XInputStream >& aStream )
     184             :         throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     185             :     virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
     186             :         throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     187             : };
     188             : 
     189             : 
     190             : // virtual
     191          12 : void SAL_CALL ActiveDataSink::setInputStream(
     192             :                         const uno::Reference< io::XInputStream >& aStream )
     193             :     throw( uno::RuntimeException, std::exception )
     194             : {
     195          12 :     m_xStream = aStream;
     196          12 : }
     197             : 
     198             : 
     199             : // virtual
     200          12 : uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream()
     201             :     throw( uno::RuntimeException, std::exception )
     202             : {
     203          12 :     return m_xStream;
     204             : }
     205             : 
     206             : 
     207             : 
     208             : // class CommandProcessorInfo.
     209             : 
     210             : 
     211             : 
     212             : class CommandProcessorInfo :
     213             :     public cppu::WeakImplHelper1< ucb::XCommandInfo >
     214             : {
     215             :     uno::Sequence< ucb::CommandInfo > * m_pInfo;
     216             : 
     217             : public:
     218             :     CommandProcessorInfo();
     219             :     virtual ~CommandProcessorInfo();
     220             : 
     221             :     // XCommandInfo methods
     222             :     virtual uno::Sequence< ucb::CommandInfo > SAL_CALL getCommands()
     223             :         throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     224             :     virtual ucb::CommandInfo SAL_CALL
     225             :     getCommandInfoByName( const OUString& Name )
     226             :         throw( ucb::UnsupportedCommandException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     227             :     virtual ucb::CommandInfo SAL_CALL
     228             :     getCommandInfoByHandle( sal_Int32 Handle )
     229             :         throw( ucb::UnsupportedCommandException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     230             :     virtual sal_Bool SAL_CALL hasCommandByName( const OUString& Name )
     231             :         throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     232             :     virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle )
     233             :         throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     234             : };
     235             : 
     236             : 
     237           0 : CommandProcessorInfo::CommandProcessorInfo()
     238             : {
     239           0 :     m_pInfo = new uno::Sequence< ucb::CommandInfo >( 2 );
     240             : 
     241           0 :     (*m_pInfo)[ 0 ]
     242           0 :         = ucb::CommandInfo(
     243             :             OUString( GETCOMMANDINFO_NAME ), // Name
     244             :             GETCOMMANDINFO_HANDLE, // Handle
     245           0 :             getCppuVoidType() ); // ArgType
     246           0 :     (*m_pInfo)[ 1 ]
     247           0 :         = ucb::CommandInfo(
     248             :             OUString( GLOBALTRANSFER_NAME ), // Name
     249             :             GLOBALTRANSFER_HANDLE, // Handle
     250           0 :             cppu::UnoType<ucb::GlobalTransferCommandArgument>::get() ); // ArgType
     251           0 :     (*m_pInfo)[ 2 ]
     252           0 :         = ucb::CommandInfo(
     253             :             OUString( CHECKIN_NAME ), // Name
     254             :             CHECKIN_HANDLE, // Handle
     255           0 :             cppu::UnoType<ucb::CheckinArgument>::get() ); // ArgType
     256           0 : }
     257             : 
     258             : 
     259             : // virtual
     260           0 : CommandProcessorInfo::~CommandProcessorInfo()
     261             : {
     262           0 :     delete m_pInfo;
     263           0 : }
     264             : 
     265             : 
     266             : // virtual
     267             : uno::Sequence< ucb::CommandInfo > SAL_CALL
     268           0 : CommandProcessorInfo::getCommands()
     269             :     throw( uno::RuntimeException, std::exception )
     270             : {
     271           0 :     return uno::Sequence< ucb::CommandInfo >( *m_pInfo );
     272             : }
     273             : 
     274             : 
     275             : // virtual
     276             : ucb::CommandInfo SAL_CALL
     277           0 : CommandProcessorInfo::getCommandInfoByName( const OUString& Name )
     278             :     throw( ucb::UnsupportedCommandException, uno::RuntimeException, std::exception )
     279             : {
     280           0 :     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
     281             :     {
     282           0 :         if ( (*m_pInfo)[ n ].Name == Name )
     283           0 :             return ucb::CommandInfo( (*m_pInfo)[ n ] );
     284             :     }
     285             : 
     286           0 :     throw ucb::UnsupportedCommandException();
     287             : }
     288             : 
     289             : 
     290             : // virtual
     291             : ucb::CommandInfo SAL_CALL
     292           0 : CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle )
     293             :     throw( ucb::UnsupportedCommandException, uno::RuntimeException, std::exception )
     294             : {
     295           0 :     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
     296             :     {
     297           0 :         if ( (*m_pInfo)[ n ].Handle == Handle )
     298           0 :             return ucb::CommandInfo( (*m_pInfo)[ n ] );
     299             :     }
     300             : 
     301           0 :     throw ucb::UnsupportedCommandException();
     302             : }
     303             : 
     304             : 
     305             : // virtual
     306           0 : sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName(
     307             :                                                 const OUString& Name )
     308             :     throw( uno::RuntimeException, std::exception )
     309             : {
     310           0 :     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
     311             :     {
     312           0 :         if ( (*m_pInfo)[ n ].Name == Name )
     313           0 :             return sal_True;
     314             :     }
     315             : 
     316           0 :     return sal_False;
     317             : }
     318             : 
     319             : 
     320             : // virtual
     321           0 : sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle )
     322             :     throw( uno::RuntimeException, std::exception )
     323             : {
     324           0 :     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
     325             :     {
     326           0 :         if ( (*m_pInfo)[ n ].Handle == Handle )
     327           0 :             return sal_True;
     328             :     }
     329             : 
     330           0 :     return sal_False;
     331             : }
     332             : 
     333             : 
     334             : 
     335             : 
     336             : 
     337          20 : OUString createDesiredName(
     338             :     const OUString & rSourceURL, const OUString & rNewTitle )
     339             : {
     340          20 :     OUString aName( rNewTitle );
     341          20 :     if ( aName.isEmpty() )
     342             :     {
     343             :         // calculate name using source URL
     344             : 
     345             :         // @@@ It's not guaranteed that slashes contained in the URL are
     346             :         // actually path separators. This depends on the fact whether the
     347             :         // URL is hierarchical. Only then the slashes are path separators.
     348             :         // Therefore this algorithm is not guaranteed to work! But, ATM
     349             :         // I don't know a better solution. It would have been better to
     350             :         // have a member for the clashing name in
     351             :         // UnsupportedNameClashException...
     352             : 
     353          16 :         sal_Int32 nLastSlash = rSourceURL.lastIndexOf( '/' );
     354          16 :         bool bTrailingSlash = false;
     355          16 :         if ( nLastSlash == rSourceURL.getLength() - 1 )
     356             :         {
     357           0 :             nLastSlash = rSourceURL.lastIndexOf( '/', nLastSlash );
     358           0 :             bTrailingSlash = true;
     359             :         }
     360             : 
     361          16 :         if ( nLastSlash != -1 )
     362             :         {
     363          16 :             if ( bTrailingSlash )
     364           0 :                 aName = rSourceURL.copy(
     365             :                             nLastSlash + 1,
     366           0 :                             rSourceURL.getLength() - nLastSlash - 2 );
     367             :             else
     368          16 :                 aName = rSourceURL.copy( nLastSlash + 1 );
     369             :         }
     370             :         else
     371             :         {
     372           0 :             aName = rSourceURL;
     373             :         }
     374             : 
     375             :         // query, fragment present?
     376          16 :     sal_Int32  nPos = aName.indexOf( '?' );
     377          16 :     if ( nPos == -1 )
     378          16 :       nPos = aName.indexOf( '#' );
     379             : 
     380          16 :     if ( nPos != -1 )
     381           0 :       aName = aName.copy( 0, nPos );
     382             :     }
     383          20 :     return OUString( aName );
     384             : }
     385             : 
     386          20 : OUString createDesiredName(
     387             :     const ucb::GlobalTransferCommandArgument & rArg )
     388             : {
     389          20 :     return createDesiredName( rArg.SourceURL, rArg.NewTitle );
     390             : }
     391             : 
     392           0 : OUString createDesiredName(
     393             :     const ucb::TransferInfo & rArg )
     394             : {
     395           0 :     return createDesiredName( rArg.SourceURL, rArg.NewTitle );
     396             : }
     397             : 
     398             : 
     399             : enum NameClashContinuation { NOT_HANDLED, ABORT, OVERWRITE, NEW_NAME, UNKNOWN };
     400             : 
     401           0 : NameClashContinuation interactiveNameClashResolve(
     402             :     const uno::Reference< ucb::XCommandEnvironment > & xEnv,
     403             :     const OUString & rTargetURL,
     404             :     const OUString & rClashingName,
     405             :     /* [out] */ uno::Any & rException,
     406             :     /* [out] */ OUString & rNewName )
     407             : {
     408             :     rtl::Reference< ucbhelper::SimpleNameClashResolveRequest > xRequest(
     409             :         new ucbhelper::SimpleNameClashResolveRequest(
     410             :             rTargetURL,  // target folder URL
     411             :             rClashingName,   // clashing name
     412             :             OUString(), // no proposal for new name
     413           0 :             true /* bSupportsOverwriteData */ ) );
     414             : 
     415           0 :     rException = xRequest->getRequest();
     416           0 :     if ( xEnv.is() )
     417             :     {
     418             :         uno::Reference< task::XInteractionHandler > xIH
     419           0 :             = xEnv->getInteractionHandler();
     420           0 :         if ( xIH.is() )
     421             :         {
     422             : 
     423           0 :             xIH->handle( xRequest.get() );
     424             : 
     425             :             rtl::Reference< ucbhelper::InteractionContinuation >
     426           0 :                 xSelection( xRequest->getSelection() );
     427             : 
     428           0 :             if ( xSelection.is() )
     429             :             {
     430             :                 // Handler handled the request.
     431             :                 uno::Reference< task::XInteractionAbort > xAbort(
     432           0 :                     xSelection.get(), uno::UNO_QUERY );
     433           0 :                 if ( xAbort.is() )
     434             :                 {
     435             :                     // Abort.
     436           0 :                     return ABORT;
     437             :                 }
     438             :                 else
     439             :                 {
     440             :                     uno::Reference<
     441             :                         ucb::XInteractionReplaceExistingData >
     442             :                             xReplace(
     443           0 :                                 xSelection.get(), uno::UNO_QUERY );
     444           0 :                     if ( xReplace.is() )
     445             :                     {
     446             :                         // Try again: Replace existing data.
     447           0 :                         return OVERWRITE;
     448             :                     }
     449             :                     else
     450             :                     {
     451             :                         uno::Reference<
     452             :                             ucb::XInteractionSupplyName >
     453             :                                 xSupplyName(
     454           0 :                                     xSelection.get(), uno::UNO_QUERY );
     455           0 :                         if ( xSupplyName.is() )
     456             :                         {
     457             :                             // Try again: Use new name.
     458           0 :                             rNewName = xRequest->getNewName();
     459           0 :                             return NEW_NAME;
     460             :                         }
     461             :                         else
     462             :                         {
     463             :                             OSL_FAIL( "Unknown interaction continuation!" );
     464           0 :                             return UNKNOWN;
     465           0 :                         }
     466           0 :                     }
     467           0 :                 }
     468           0 :             }
     469           0 :         }
     470             :     }
     471           0 :     return NOT_HANDLED;
     472             : }
     473             : 
     474             : 
     475           0 : bool setTitle(
     476             :         const uno::Reference< ucb::XCommandProcessor > & xCommandProcessor,
     477             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv,
     478             :         const OUString & rNewTitle )
     479             :     throw( uno::RuntimeException )
     480             : {
     481             :     try
     482             :     {
     483           0 :         uno::Sequence< beans::PropertyValue > aPropValues( 1 );
     484           0 :         aPropValues[ 0 ].Name = "Title";
     485           0 :         aPropValues[ 0 ].Handle = -1;
     486           0 :         aPropValues[ 0 ].Value  = uno::makeAny( rNewTitle );
     487             : 
     488             :         ucb::Command aSetPropsCommand(
     489             :             OUString(  "setPropertyValues"  ),
     490             :             -1,
     491           0 :             uno::makeAny( aPropValues ) );
     492             : 
     493             :         uno::Any aResult
     494           0 :             = xCommandProcessor->execute( aSetPropsCommand, 0, xEnv );
     495             : 
     496           0 :         uno::Sequence< uno::Any > aErrors;
     497           0 :         aResult >>= aErrors;
     498             : 
     499             :         OSL_ENSURE( aErrors.getLength() == 1,
     500             :                     "getPropertyValues return value invalid!" );
     501             : 
     502           0 :         if ( aErrors[ 0 ].hasValue() )
     503             :         {
     504             :             // error occurred.
     505             :             OSL_FAIL( "error setting Title property!" );
     506           0 :             return false;
     507           0 :         }
     508             :     }
     509           0 :     catch ( uno::RuntimeException const & )
     510             :     {
     511           0 :         throw;
     512             :     }
     513           0 :     catch ( uno::Exception const & )
     514             :     {
     515           0 :         return false;
     516             :     }
     517             : 
     518           0 :     return true;
     519             : }
     520             : 
     521             : 
     522          20 : uno::Reference< ucb::XContent > createNew(
     523             :                     const TransferCommandContext & rContext,
     524             :                     const uno::Reference< ucb::XContent > & xTarget,
     525             :                     bool bSourceIsFolder,
     526             :                     bool bSourceIsDocument,
     527             :                     bool bSourceIsLink )
     528             :     throw( uno::Exception )
     529             : {
     530             : 
     531             : 
     532             :     // (1) Obtain creatable types from target.
     533             : 
     534             : 
     535             : 
     536             :     // First, try it using "CreatabeleContentsInfo" property and
     537             :     // "createNewContent" command -> the "new" way.
     538             : 
     539             :     uno::Reference< ucb::XCommandProcessor > xCommandProcessorT(
     540          20 :                                                     xTarget, uno::UNO_QUERY );
     541          20 :     if ( !xCommandProcessorT.is() )
     542             :     {
     543             :         uno::Any aProps
     544             :             = uno::makeAny(beans::PropertyValue(
     545             :                                   OUString( "Folder"),
     546             :                                   -1,
     547             :                                   uno::makeAny(rContext.aArg.TargetURL),
     548           0 :                                   beans::PropertyState_DIRECT_VALUE));
     549             :         ucbhelper::cancelCommandExecution(
     550             :             ucb::IOErrorCode_CANT_CREATE,
     551             :             uno::Sequence< uno::Any >(&aProps, 1),
     552             :             rContext.xOrigEnv,
     553             :             OUString("Target is no XCommandProcessor!"),
     554           0 :             rContext.xProcessor );
     555             :         // Unreachable
     556             :     }
     557             : 
     558          40 :     uno::Sequence< beans::Property > aPropsToObtain( 1 );
     559          20 :     aPropsToObtain[ 0 ].Name = "CreatableContentsInfo";
     560          20 :     aPropsToObtain[ 0 ].Handle = -1;
     561             : 
     562             :     ucb::Command aGetPropsCommand(
     563             :             OUString("getPropertyValues"),
     564             :             -1,
     565          40 :             uno::makeAny( aPropsToObtain ) );
     566             : 
     567          40 :     uno::Reference< sdbc::XRow > xRow;
     568          20 :     xCommandProcessorT->execute( aGetPropsCommand, 0, rContext.xEnv )  >>= xRow;
     569             : 
     570          40 :     uno::Sequence< ucb::ContentInfo > aTypesInfo;
     571          20 :     bool bGotTypesInfo = false;
     572             : 
     573          20 :     if ( xRow.is() )
     574             :     {
     575          20 :         uno::Any  aValue = xRow->getObject(
     576          20 :             1, uno::Reference< container::XNameAccess >() );
     577          20 :         if ( aValue.hasValue() && ( aValue >>= aTypesInfo ) )
     578             :         {
     579          20 :             bGotTypesInfo = true;
     580          20 :         }
     581             :     }
     582             : 
     583          40 :     uno::Reference< ucb::XContentCreator > xCreator;
     584             : 
     585          20 :     if ( !bGotTypesInfo )
     586             :     {
     587             :         // Second, try it using XContentCreator interface -> the "old" way (not
     588             :         // providing the chance to supply an XCommandEnvironment.
     589             : 
     590           0 :         xCreator.set( xTarget, uno::UNO_QUERY );
     591             : 
     592           0 :         if ( !xCreator.is() )
     593             :         {
     594             :             uno::Any aProps
     595             :                 = uno::makeAny(beans::PropertyValue(
     596             :                                   OUString( "Folder"),
     597             :                                   -1,
     598             :                                   uno::makeAny(rContext.aArg.TargetURL),
     599           0 :                                   beans::PropertyState_DIRECT_VALUE));
     600             :             ucbhelper::cancelCommandExecution(
     601             :                 ucb::IOErrorCode_CANT_CREATE,
     602             :                 uno::Sequence< uno::Any >(&aProps, 1),
     603             :                 rContext.xOrigEnv,
     604             :                 OUString("Target is no XContentCreator!"),
     605           0 :                 rContext.xProcessor );
     606             :             // Unreachable
     607             :         }
     608             : 
     609           0 :         aTypesInfo  = xCreator->queryCreatableContentsInfo();
     610             :     }
     611             : 
     612          20 :     sal_Int32 nCount = aTypesInfo.getLength();
     613          20 :     if ( !nCount )
     614             :     {
     615             :         uno::Any aProps
     616             :             = uno::makeAny(beans::PropertyValue(
     617             :                               OUString("Folder"),
     618             :                               -1,
     619             :                               uno::makeAny(rContext.aArg.TargetURL),
     620           0 :                               beans::PropertyState_DIRECT_VALUE));
     621             :         ucbhelper::cancelCommandExecution(
     622             :             ucb::IOErrorCode_CANT_CREATE,
     623             :             uno::Sequence< uno::Any >(&aProps, 1),
     624             :             rContext.xOrigEnv,
     625             :             OUString("No types creatable!"),
     626           0 :             rContext.xProcessor );
     627             :         // Unreachable
     628             :     }
     629             : 
     630             : 
     631             : 
     632             :     // (2) Try to find a matching target type for the source object.
     633             : 
     634             : 
     635             : 
     636          20 :     uno::Reference< ucb::XContent > xNew;
     637          28 :     for ( sal_Int32 n = 0; n < nCount; ++n )
     638             :     {
     639          28 :         sal_Int32 nAttribs = aTypesInfo[ n ].Attributes;
     640          28 :         bool  bMatch   = false;
     641             : 
     642          28 :         if ( rContext.aArg.Operation == ucb::TransferCommandOperation_LINK )
     643             :         {
     644             :             // Create link
     645             : 
     646           0 :             if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
     647             :             {
     648             :                 // Match!
     649           0 :                 bMatch = true;
     650             :             }
     651             :         }
     652          28 :         else if ( ( rContext.aArg.Operation
     653          28 :                         == ucb::TransferCommandOperation_COPY ) ||
     654             :                   ( rContext.aArg.Operation
     655           0 :                         == ucb::TransferCommandOperation_MOVE ) )
     656             :         {
     657             :             // Copy / Move
     658             : 
     659             :             // Is source a link? Create link in target folder then.
     660          56 :             if ( bSourceIsLink )
     661             :             {
     662           0 :                 if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
     663             :                 {
     664             :                     // Match!
     665           0 :                     bMatch = true;
     666             :                 }
     667             :             }
     668             :             else
     669             :             {
     670             :                 // (not a and not b) or (a and b)
     671             :                 // not( a or b) or (a and b)
     672             : 
     673          56 :                 if ( ( !!bSourceIsFolder ==
     674             :                         !!( nAttribs
     675          28 :                             & ucb::ContentInfoAttribute::KIND_FOLDER ) )
     676          20 :                      &&
     677          20 :                      ( !!bSourceIsDocument ==
     678             :                         !!( nAttribs
     679          20 :                             & ucb::ContentInfoAttribute::KIND_DOCUMENT ) )
     680             :                    )
     681             :                 {
     682             :                     // Match!
     683          20 :                     bMatch = true;
     684             :                 }
     685             :             }
     686             :         }
     687             :         else
     688             :         {
     689             :             ucbhelper::cancelCommandExecution(
     690             :                 uno::makeAny( lang::IllegalArgumentException(
     691             :                                         OUString( "Unknown transfer operation!" ),
     692             :                                         rContext.xProcessor,
     693           0 :                                         -1 ) ),
     694           0 :                               rContext.xOrigEnv );
     695             :             // Unreachable
     696             :         }
     697             : 
     698          28 :         if ( bMatch )
     699             :         {
     700             : 
     701             : 
     702             :             // (3) Create a new, empty object of matched type.
     703             : 
     704             : 
     705             : 
     706          20 :             if ( !xCreator.is() )
     707             :             {
     708             :                 // First, try it using "CreatabeleContentsInfo" property and
     709             :                 // "createNewContent" command -> the "new" way.
     710             :                 ucb::Command aCreateNewCommand(
     711             :                    OUString("createNewContent"),
     712             :                    -1,
     713          20 :                    uno::makeAny( aTypesInfo[ n ] ) );
     714             : 
     715          20 :                 xCommandProcessorT->execute( aCreateNewCommand, 0, rContext.xEnv )
     716          20 :                     >>= xNew;
     717             :             }
     718             :             else
     719             :             {
     720             :                 // Second, try it using XContentCreator interface -> the "old"
     721             :                 // way (not providing the chance to supply an XCommandEnvironment.
     722             : 
     723           0 :                 xNew = xCreator->createNewContent( aTypesInfo[ n ] );
     724             :             }
     725             : 
     726          20 :             if ( !xNew.is() )
     727             :             {
     728             :                 uno::Any aProps
     729             :                     = uno::makeAny(
     730             :                              beans::PropertyValue(
     731             :                                  OUString( "Folder"),
     732             :                                  -1,
     733             :                                  uno::makeAny(rContext.aArg.TargetURL),
     734           0 :                                  beans::PropertyState_DIRECT_VALUE));
     735             :                 ucbhelper::cancelCommandExecution(
     736             :                     ucb::IOErrorCode_CANT_CREATE,
     737             :                     uno::Sequence< uno::Any >(&aProps, 1),
     738             :                     rContext.xOrigEnv,
     739             :                     OUString( "createNewContent failed!" ),
     740           0 :                     rContext.xProcessor );
     741             :                 // Unreachable
     742             :             }
     743          20 :             break; // escape from 'for' loop
     744             :         }
     745             :     } // for
     746             : 
     747          40 :     return xNew;
     748             : }
     749             : 
     750             : 
     751          20 : void transferProperties(
     752             :     const TransferCommandContext & rContext,
     753             :     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS,
     754             :     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorN )
     755             :         throw( uno::Exception )
     756             : {
     757             :     ucb::Command aGetPropertySetInfoCommand(
     758             :                 OUString("getPropertySetInfo"),
     759             :                 -1,
     760          20 :                 uno::Any() );
     761             : 
     762          40 :     uno::Reference< beans::XPropertySetInfo > xInfo;
     763          20 :     xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv )
     764          20 :         >>= xInfo;
     765             : 
     766          20 :     if ( !xInfo.is() )
     767             :     {
     768             :         uno::Any aProps
     769             :             = uno::makeAny(beans::PropertyValue(
     770             :                                   OUString( "Uri"),
     771             :                                   -1,
     772             :                                   uno::makeAny(rContext.aArg.SourceURL),
     773           0 :                                   beans::PropertyState_DIRECT_VALUE));
     774             :         ucbhelper::cancelCommandExecution(
     775             :             ucb::IOErrorCode_CANT_READ,
     776             :             uno::Sequence< uno::Any >(&aProps, 1),
     777             :             rContext.xOrigEnv,
     778             :             OUString( "Unable to get propertyset info from source object!" ),
     779           0 :             rContext.xProcessor );
     780             :         // Unreachable
     781             :     }
     782             : 
     783          40 :     uno::Sequence< beans::Property > aAllProps = xInfo->getProperties();
     784             : 
     785             :     ucb::Command aGetPropsCommand1(
     786             :                 OUString("getPropertyValues"),
     787             :                 -1,
     788          40 :                 uno::makeAny( aAllProps ) );
     789             : 
     790          40 :     uno::Reference< sdbc::XRow > xRow1;
     791          20 :     xCommandProcessorS->execute(
     792          20 :         aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1;
     793             : 
     794          20 :     if ( !xRow1.is() )
     795             :     {
     796             :         uno::Any aProps
     797             :             = uno::makeAny(beans::PropertyValue(
     798             :                                   OUString( "Uri"),
     799             :                                   -1,
     800             :                                   uno::makeAny(rContext.aArg.SourceURL),
     801           0 :                                   beans::PropertyState_DIRECT_VALUE));
     802             :         ucbhelper::cancelCommandExecution(
     803             :             ucb::IOErrorCode_CANT_READ,
     804             :             uno::Sequence< uno::Any >(&aProps, 1),
     805             :             rContext.xOrigEnv,
     806             :             OUString( "Unable to get properties from source object!" ),
     807           0 :             rContext.xProcessor );
     808             :         // Unreachable
     809             :     }
     810             : 
     811             :     // Assemble data structure for setPropertyValues command.
     812             : 
     813             :     // Note: Make room for additional Title and TargetURL too. -> + 2
     814             :     uno::Sequence< beans::PropertyValue > aPropValues(
     815          40 :                                                 aAllProps.getLength() + 2 );
     816             : 
     817          20 :     bool bHasTitle = rContext.aArg.NewTitle.isEmpty();
     818             :     bool bHasTargetURL = ( rContext.aArg.Operation
     819          20 :                                 != ucb::TransferCommandOperation_LINK );
     820             : 
     821          20 :     sal_Int32 nWritePos = 0;
     822         180 :     for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m )
     823             :     {
     824         160 :         const beans::Property & rCurrProp = aAllProps[ m ];
     825         160 :         beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ];
     826             : 
     827         160 :         uno::Any aValue;
     828             : 
     829         160 :         if ( rCurrProp.Name.equalsAscii( "Title" ) )
     830             :         {
     831             :             // Supply new title, if given.
     832          20 :             if ( !bHasTitle )
     833             :             {
     834           4 :                 bHasTitle = true;
     835           4 :                 aValue <<= rContext.aArg.NewTitle;
     836             :             }
     837             :         }
     838         140 :         else if ( rCurrProp.Name.equalsAscii( "TargetURL" ) )
     839             :         {
     840             :             // Supply source URL as link target for the new link to create.
     841           0 :             if ( !bHasTargetURL )
     842             :             {
     843           0 :                 bHasTargetURL = true;
     844           0 :                 aValue <<= rContext.aArg.SourceURL;
     845             :             }
     846             :         }
     847             : 
     848         160 :         if ( !aValue.hasValue() )
     849             :         {
     850             :             try
     851             :             {
     852         468 :                 aValue = xRow1->getObject(
     853         312 :                             m + 1, uno::Reference< container::XNameAccess >() );
     854             :             }
     855           0 :             catch ( sdbc::SQLException const & )
     856             :             {
     857             :                 // Argh! But try to bring things to an end. Perhaps the
     858             :                 // mad property is not really important...
     859             :             }
     860             :         }
     861             : 
     862         160 :         if ( aValue.hasValue() )
     863             :         {
     864         160 :             rCurrValue.Name   = rCurrProp.Name;
     865         160 :             rCurrValue.Handle = rCurrProp.Handle;
     866         160 :             rCurrValue.Value  = aValue;
     867             : //          rCurrValue.State  =
     868             : 
     869         160 :             nWritePos++;
     870             :         }
     871         160 :     }
     872             : 
     873             :     // Title needed, but not set yet?
     874          20 :     if ( !bHasTitle && !rContext.aArg.NewTitle.isEmpty() )
     875             :     {
     876           0 :         aPropValues[ nWritePos ].Name = "Title";
     877           0 :         aPropValues[ nWritePos ].Handle = -1;
     878           0 :         aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle;
     879             : 
     880           0 :         nWritePos++;
     881             :     }
     882             : 
     883             :     // TargetURL needed, but not set yet?
     884          20 :     if ( !bHasTargetURL && ( rContext.aArg.Operation
     885           0 :                                 == ucb::TransferCommandOperation_LINK ) )
     886             :     {
     887           0 :         aPropValues[ nWritePos ].Name = "TargetURL";
     888           0 :         aPropValues[ nWritePos ].Handle = -1;
     889           0 :         aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL;
     890             : 
     891           0 :         nWritePos++;
     892             :     }
     893             : 
     894          20 :     aPropValues.realloc( nWritePos );
     895             : 
     896             :     // Set properties at new object.
     897             : 
     898             :     ucb::Command aSetPropsCommand(
     899             :                 OUString("setPropertyValues"),
     900             :                 -1,
     901          40 :                 uno::makeAny( aPropValues ) );
     902             : 
     903          40 :     xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv );
     904             : 
     905             :     // @@@ What to do with source props that are not supported by the
     906             :     //     new object? addProperty ???
     907          20 : }
     908             : 
     909             : 
     910          12 : uno::Reference< io::XInputStream > getInputStream(
     911             :     const TransferCommandContext & rContext,
     912             :     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
     913             :         throw( uno::Exception )
     914             : {
     915          12 :     uno::Reference< io::XInputStream > xInputStream;
     916             : 
     917             : 
     918             : 
     919             :     // (1) Try to get data as XInputStream via XActiveDataSink.
     920             : 
     921             : 
     922             : 
     923             :     try
     924             :     {
     925          12 :         uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink;
     926             : 
     927          24 :         ucb::OpenCommandArgument2 aArg;
     928          12 :         aArg.Mode       = ucb::OpenMode::DOCUMENT;
     929          12 :         aArg.Priority   = 0; // unused
     930          12 :         aArg.Sink       = xSink;
     931          12 :         aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused
     932             : 
     933             :         ucb::Command aOpenCommand(
     934             :                                 OUString("open"),
     935             :                                 -1,
     936          24 :                                 uno::makeAny( aArg ) );
     937             : 
     938          12 :         xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
     939          24 :         xInputStream = xSink->getInputStream();
     940             :     }
     941           0 :     catch ( uno::RuntimeException const & )
     942             :     {
     943           0 :         throw;
     944             :     }
     945           0 :     catch ( uno::Exception const & )
     946             :     {
     947             :         // will be handled below.
     948             :     }
     949             : 
     950          12 :     if ( !xInputStream.is() )
     951             :     {
     952             : 
     953             : 
     954             :         // (2) Try to get data via XOutputStream.
     955             : 
     956             : 
     957             : 
     958             :         try
     959             :         {
     960           0 :             uno::Reference< io::XOutputStream > xOutputStream( io::Pipe::create(rContext.m_xContext), uno::UNO_QUERY_THROW );
     961             : 
     962           0 :             ucb::OpenCommandArgument2 aArg;
     963           0 :             aArg.Mode       = ucb::OpenMode::DOCUMENT;
     964           0 :             aArg.Priority   = 0; // unused
     965           0 :             aArg.Sink       = xOutputStream;
     966           0 :             aArg.Properties = uno::Sequence< beans::Property >( 0 );
     967             : 
     968             :             ucb::Command aOpenCommand(
     969             :                                 OUString("open"),
     970             :                                 -1,
     971           0 :                                 uno::makeAny( aArg ) );
     972             : 
     973           0 :             xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
     974             : 
     975           0 :             xInputStream = uno::Reference< io::XInputStream >(
     976           0 :                                     xOutputStream, uno::UNO_QUERY );
     977             :         }
     978           0 :         catch ( uno::RuntimeException const & )
     979             :         {
     980           0 :             throw;
     981             :         }
     982           0 :         catch ( uno::Exception const & )
     983             :         {
     984             :             OSL_FAIL( "unable to get input stream from document!" );
     985             :         }
     986             :     }
     987             : 
     988          12 :     return xInputStream;
     989             : }
     990             : 
     991             : 
     992           8 : uno::Reference< sdbc::XResultSet > getResultSet(
     993             :     const TransferCommandContext & rContext,
     994             :     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
     995             :         throw( uno::Exception )
     996             : {
     997           8 :     uno::Reference< sdbc::XResultSet > xResultSet;
     998             : 
     999          16 :     uno::Sequence< beans::Property > aProps( 3 );
    1000             : 
    1001           8 :     aProps[ 0 ].Name   = "IsFolder";
    1002           8 :     aProps[ 0 ].Handle = -1; /* unknown */
    1003           8 :     aProps[ 1 ].Name   = "IsDocument";
    1004           8 :     aProps[ 1 ].Handle = -1; /* unknown */
    1005           8 :     aProps[ 2 ].Name   = "TargetURL";
    1006           8 :     aProps[ 2 ].Handle = -1; /* unknown */
    1007             : 
    1008          16 :     ucb::OpenCommandArgument2 aArg;
    1009           8 :     aArg.Mode       = ucb::OpenMode::ALL;
    1010           8 :     aArg.Priority   = 0; // unused
    1011           8 :     aArg.Sink       = 0;
    1012           8 :     aArg.Properties = aProps;
    1013             : 
    1014             :     ucb::Command aOpenCommand( OUString("open"),
    1015             :                                      -1,
    1016          16 :                                      uno::makeAny( aArg ) );
    1017             :     try
    1018             :     {
    1019           8 :         uno::Reference< ucb::XDynamicResultSet > xSet;
    1020           8 :         xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet;
    1021             : 
    1022           8 :         if ( xSet.is() )
    1023           8 :             xResultSet = xSet->getStaticResultSet();
    1024             :     }
    1025           0 :     catch ( uno::RuntimeException const & )
    1026             :     {
    1027           0 :         throw;
    1028             :     }
    1029           0 :     catch ( uno::Exception const & )
    1030             :     {
    1031             :          OSL_FAIL( "unable to get result set from folder!" );
    1032             :     }
    1033             : 
    1034          16 :     return xResultSet;
    1035             : }
    1036             : 
    1037             : 
    1038           0 : void handleNameClashRename(
    1039             :         const TransferCommandContext & rContext,
    1040             :         const uno::Reference< ucb::XContent > & xNew,
    1041             :         const uno::Reference<
    1042             :             ucb::XCommandProcessor > & xCommandProcessorN,
    1043             :         const uno::Reference<
    1044             :             ucb::XCommandProcessor > & xCommandProcessorS,
    1045             :         /* [inout] */ uno::Reference< io::XInputStream > & xInputStream )
    1046             :     throw( uno::Exception )
    1047             : {
    1048           0 :     sal_Int32 nTry = 0;
    1049             : 
    1050             :     // Obtain old title.
    1051           0 :     uno::Sequence< beans::Property > aProps( 1 );
    1052           0 :     aProps[ 0 ].Name   = "Title";
    1053           0 :     aProps[ 0 ].Handle = -1;
    1054             : 
    1055             :     ucb::Command aGetPropsCommand(
    1056             :             OUString("getPropertyValues"),
    1057             :             -1,
    1058           0 :             uno::makeAny( aProps ) );
    1059             : 
    1060           0 :     uno::Reference< sdbc::XRow > xRow;
    1061           0 :     xCommandProcessorN->execute( aGetPropsCommand, 0, rContext.xEnv )  >>= xRow;
    1062             : 
    1063           0 :     if ( !xRow.is() )
    1064             :     {
    1065             :         uno::Any aProps2
    1066             :             = uno::makeAny(
    1067             :                      beans::PropertyValue(
    1068             :                          OUString(  "Uri"  ),
    1069             :                          -1,
    1070             :                          uno::makeAny(
    1071           0 :                              xNew->getIdentifier()->getContentIdentifier() ),
    1072           0 :                          beans::PropertyState_DIRECT_VALUE ) );
    1073             :         ucbhelper::cancelCommandExecution(
    1074             :             ucb::IOErrorCode_CANT_READ,
    1075             :             uno::Sequence< uno::Any >( &aProps2, 1 ),
    1076             :             rContext.xOrigEnv,
    1077             :             OUString( "Unable to get properties from new object!" ),
    1078           0 :             rContext.xProcessor );
    1079             :         // Unreachable
    1080             :     }
    1081             : 
    1082           0 :     OUString aOldTitle = xRow->getString( 1 );
    1083           0 :     if ( aOldTitle.isEmpty() )
    1084             :     {
    1085             :         ucbhelper::cancelCommandExecution(
    1086             :             uno::makeAny( beans::UnknownPropertyException(
    1087             :                             OUString( "Unable to get property 'Title' from new object!" ),
    1088           0 :                             rContext.xProcessor ) ),
    1089           0 :             rContext.xOrigEnv );
    1090             :         // Unreachable
    1091             :     }
    1092             : 
    1093             :     // Some pseudo-intelligence for not destroying file extensions.
    1094           0 :     OUString aOldTitlePre;
    1095           0 :     OUString aOldTitlePost;
    1096           0 :     sal_Int32 nPos = aOldTitle.lastIndexOf( '.' );
    1097           0 :     if ( nPos != -1 )
    1098             :     {
    1099           0 :         aOldTitlePre = aOldTitle.copy( 0, nPos );
    1100           0 :         aOldTitlePost = aOldTitle.copy( nPos );
    1101             :     }
    1102             :     else
    1103           0 :         aOldTitlePre = aOldTitle;
    1104             : 
    1105           0 :     if ( nPos > 0 )
    1106           0 :         aOldTitlePre += "_";
    1107             : 
    1108           0 :     bool bContinue = true;
    1109           0 :     do
    1110             :     {
    1111           0 :         nTry++;
    1112             : 
    1113           0 :         OUString aNewTitle = aOldTitlePre;
    1114           0 :         aNewTitle += OUString::number( nTry );
    1115           0 :         aNewTitle += aOldTitlePost;
    1116             : 
    1117             :         // Set new title
    1118           0 :         setTitle( xCommandProcessorN, rContext.xEnv, aNewTitle );
    1119             : 
    1120             :         // Retry inserting the content.
    1121             :         try
    1122             :         {
    1123             :             // Previous try may have read from stream. Seek to begin (if
    1124             :             // optional interface XSeekable is supported) or get a new stream.
    1125           0 :             if ( xInputStream.is() )
    1126             :             {
    1127             :                 uno::Reference< io::XSeekable > xSeekable(
    1128           0 :                     xInputStream, uno::UNO_QUERY );
    1129           0 :                 if ( xSeekable.is() )
    1130             :                 {
    1131             :                     try
    1132             :                     {
    1133           0 :                         xSeekable->seek( 0 );
    1134             :                     }
    1135           0 :                     catch ( lang::IllegalArgumentException const & )
    1136             :                     {
    1137           0 :                         xInputStream.clear();
    1138             :                     }
    1139           0 :                     catch ( io::IOException const & )
    1140             :                     {
    1141           0 :                         xInputStream.clear();
    1142             :                     }
    1143             :                 }
    1144             :                 else
    1145           0 :                     xInputStream.clear();
    1146             : 
    1147           0 :                 if ( !xInputStream.is() )
    1148             :                 {
    1149             :                     xInputStream
    1150           0 :                         = getInputStream( rContext, xCommandProcessorS );
    1151           0 :                     if ( !xInputStream.is() )
    1152             :                     {
    1153             :                         uno::Any aProps2
    1154             :                             = uno::makeAny(
    1155             :                                 beans::PropertyValue(
    1156             :                                     OUString( "Uri"  ),
    1157             :                                     -1,
    1158             :                                     uno::makeAny(
    1159           0 :                                         xNew->getIdentifier()->
    1160           0 :                                             getContentIdentifier() ),
    1161           0 :                                     beans::PropertyState_DIRECT_VALUE ) );
    1162             :                         ucbhelper::cancelCommandExecution(
    1163             :                             ucb::IOErrorCode_CANT_READ,
    1164             :                             uno::Sequence< uno::Any >( &aProps2, 1 ),
    1165             :                             rContext.xOrigEnv,
    1166             :                             OUString( "Got no data stream from source!" ),
    1167           0 :                             rContext.xProcessor );
    1168             :                         // Unreachable
    1169             :                     }
    1170           0 :                 }
    1171             :             }
    1172             : 
    1173           0 :             ucb::InsertCommandArgument2 aArg;
    1174           0 :             aArg.Data = xInputStream;
    1175           0 :             aArg.ReplaceExisting = sal_False;
    1176             : 
    1177             :             ucb::Command aInsertCommand(
    1178             :                         OUString("insert"),
    1179             :                         -1,
    1180           0 :                         uno::makeAny( aArg ) );
    1181             : 
    1182           0 :             xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
    1183             : 
    1184             :             // Success!
    1185           0 :             bContinue = false;
    1186             :         }
    1187           0 :         catch ( uno::RuntimeException const & )
    1188             :         {
    1189           0 :             throw;
    1190             :         }
    1191           0 :         catch ( uno::Exception const & )
    1192             :         {
    1193           0 :         }
    1194             :     }
    1195           0 :     while ( bContinue && ( nTry < 50 ) );
    1196             : 
    1197           0 :     if ( nTry == 50 )
    1198             :     {
    1199             :         ucbhelper::cancelCommandExecution(
    1200             :             uno::makeAny(
    1201             :                 ucb::UnsupportedNameClashException(
    1202             :                     OUString( "Unable to resolve name clash!" ),
    1203             :                     rContext.xProcessor,
    1204           0 :                     ucb::NameClash::RENAME ) ),
    1205           0 :             rContext.xOrigEnv );
    1206             :         // Unreachable
    1207           0 :     }
    1208           0 : }
    1209             : 
    1210             : 
    1211          20 : void globalTransfer_(
    1212             :         const TransferCommandContext & rContext,
    1213             :         const uno::Reference< ucb::XContent > & xSource,
    1214             :         const uno::Reference< ucb::XContent > & xTarget,
    1215             :         const uno::Reference< sdbc::XRow > & xSourceProps )
    1216             :     throw( uno::Exception )
    1217             : {
    1218             :     // IsFolder: property is required.
    1219          20 :     bool bSourceIsFolder = xSourceProps->getBoolean( 1 );
    1220          20 :     if ( !bSourceIsFolder && xSourceProps->wasNull() )
    1221             :     {
    1222             :         ucbhelper::cancelCommandExecution(
    1223             :             uno::makeAny( beans::UnknownPropertyException(
    1224             :                             OUString( "Unable to get property 'IsFolder' "
    1225             :                                 "from source object!" ),
    1226           0 :                             rContext.xProcessor ) ),
    1227           0 :             rContext.xOrigEnv );
    1228             :         // Unreachable
    1229             :     }
    1230             : 
    1231             :     // IsDocument: property is required.
    1232          20 :     bool bSourceIsDocument = xSourceProps->getBoolean( 2 );
    1233          20 :     if ( !bSourceIsDocument && xSourceProps->wasNull() )
    1234             :     {
    1235             :         ucbhelper::cancelCommandExecution(
    1236             :             uno::makeAny( beans::UnknownPropertyException(
    1237             :                             OUString( "Unable to get property 'IsDocument' "
    1238             :                                 "from source object!" ),
    1239           0 :                             rContext.xProcessor ) ),
    1240           0 :             rContext.xOrigEnv );
    1241             :         // Unreachable
    1242             :     }
    1243             : 
    1244             :     // TargetURL: property is optional.
    1245          20 :     bool bSourceIsLink = !xSourceProps->getString( 3 ).isEmpty();
    1246             : 
    1247             : 
    1248             : 
    1249             :     // (1) Try to find a matching target type for the source object and
    1250             :     //     create a new, empty object of that type.
    1251             : 
    1252             : 
    1253             : 
    1254             :     uno::Reference< ucb::XContent > xNew = createNew( rContext,
    1255             :                                                       xTarget,
    1256             :                                                       bSourceIsFolder,
    1257             :                                                       bSourceIsDocument,
    1258          20 :                                                       bSourceIsLink );
    1259          20 :     if ( !xNew.is() )
    1260             :     {
    1261             :         uno::Any aProps
    1262             :             = uno::makeAny(beans::PropertyValue(
    1263             :                                   OUString( "Folder"),
    1264             :                                   -1,
    1265             :                                   uno::makeAny(rContext.aArg.TargetURL),
    1266           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1267             :         ucbhelper::cancelCommandExecution(
    1268             :             ucb::IOErrorCode_CANT_CREATE,
    1269             :             uno::Sequence< uno::Any >(&aProps, 1),
    1270             :             rContext.xOrigEnv,
    1271             :             OUString( "No matching content type at target!" ),
    1272           0 :             rContext.xProcessor );
    1273             :         // Unreachable
    1274             :     }
    1275             : 
    1276             : 
    1277             : 
    1278             :     // (2) Transfer property values from source to new object.
    1279             : 
    1280             : 
    1281             : 
    1282             :     uno::Reference< ucb::XCommandProcessor > xCommandProcessorN(
    1283          40 :                                                     xNew, uno::UNO_QUERY );
    1284          20 :     if ( !xCommandProcessorN.is() )
    1285             :     {
    1286             :         uno::Any aProps
    1287             :             = uno::makeAny(beans::PropertyValue(
    1288             :                                   OUString( "Uri"),
    1289             :                                   -1,
    1290             :                                   uno::makeAny(
    1291           0 :                                       xNew->getIdentifier()->
    1292           0 :                                                 getContentIdentifier()),
    1293           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1294             :         ucbhelper::cancelCommandExecution(
    1295             :             ucb::IOErrorCode_CANT_WRITE,
    1296             :             uno::Sequence< uno::Any >(&aProps, 1),
    1297             :             rContext.xOrigEnv,
    1298             :             OUString( "New content is not a XCommandProcessor!" ),
    1299           0 :             rContext.xProcessor );
    1300             :         // Unreachable
    1301             :     }
    1302             : 
    1303             :     // Obtain all properties from source.
    1304             : 
    1305             :     uno::Reference< ucb::XCommandProcessor > xCommandProcessorS(
    1306          40 :                                                     xSource, uno::UNO_QUERY );
    1307          20 :     if ( !xCommandProcessorS.is() )
    1308             :     {
    1309             :         uno::Any aProps
    1310             :             = uno::makeAny(beans::PropertyValue(
    1311             :                                   OUString( "Uri"),
    1312             :                                   -1,
    1313             :                                   uno::makeAny(rContext.aArg.SourceURL),
    1314           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1315             :         ucbhelper::cancelCommandExecution(
    1316             :             ucb::IOErrorCode_CANT_READ,
    1317             :             uno::Sequence< uno::Any >(&aProps, 1),
    1318             :             rContext.xOrigEnv,
    1319             :             OUString( "Source content is not a XCommandProcessor!" ),
    1320           0 :             rContext.xProcessor );
    1321             :         // Unreachable
    1322             :     }
    1323             : 
    1324          20 :     transferProperties( rContext, xCommandProcessorS, xCommandProcessorN );
    1325             : 
    1326             : 
    1327             : 
    1328             :     // (3) Try to obtain a data stream from source.
    1329             : 
    1330             : 
    1331             : 
    1332          40 :     uno::Reference< io::XInputStream > xInputStream;
    1333             : 
    1334          32 :     if ( bSourceIsDocument && ( rContext.aArg.Operation
    1335          12 :                                 != ucb::TransferCommandOperation_LINK ) )
    1336          12 :         xInputStream = getInputStream( rContext, xCommandProcessorS );
    1337             : 
    1338             : 
    1339             : 
    1340             :     // (4) Try to obtain a resultset (children) from source.
    1341             : 
    1342             : 
    1343             : 
    1344          40 :     uno::Reference< sdbc::XResultSet > xResultSet;
    1345             : 
    1346          28 :     if ( bSourceIsFolder && ( rContext.aArg.Operation
    1347           8 :                                 != ucb::TransferCommandOperation_LINK ) )
    1348           8 :         xResultSet = getResultSet( rContext, xCommandProcessorS );
    1349             : 
    1350             : 
    1351             : 
    1352             :     // (5) Insert (store) new content.
    1353             : 
    1354             : 
    1355             : 
    1356          40 :     ucb::InsertCommandArgument2 aArg;
    1357          20 :     aArg.Data = xInputStream;
    1358          20 :     aArg.MimeType = rContext.aArg.MimeType;
    1359          20 :     aArg.DocumentId = rContext.aArg.DocumentId;
    1360             : 
    1361          20 :     switch ( rContext.aArg.NameClash )
    1362             :     {
    1363             :         case ucb::NameClash::OVERWRITE:
    1364          20 :             aArg.ReplaceExisting = sal_True;
    1365          20 :             break;
    1366             : 
    1367             :         case ucb::NameClash::ERROR:
    1368             :         case ucb::NameClash::RENAME:
    1369             :         case ucb::NameClash::KEEP: // deprecated
    1370             :         case ucb::NameClash::ASK:
    1371           0 :             aArg.ReplaceExisting = sal_False;
    1372           0 :             break;
    1373             : 
    1374             :         default:
    1375           0 :             aArg.ReplaceExisting = sal_False;
    1376             :             OSL_FAIL( "Unknown nameclash directive!" );
    1377           0 :             break;
    1378             :     }
    1379             : 
    1380          20 :     OUString aDesiredName = createDesiredName( rContext.aArg );
    1381             : 
    1382             :     bool bRetry;
    1383          20 :     do
    1384             :     {
    1385          20 :         bRetry = false;
    1386             : 
    1387             :         try
    1388             :         {
    1389             :             ucb::Command aInsertCommand(
    1390             :                                     OUString("insert"),
    1391             :                                     -1,
    1392          20 :                                     uno::makeAny( aArg ) );
    1393             : 
    1394          20 :             xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
    1395             :         }
    1396           0 :         catch ( ucb::UnsupportedNameClashException const & exc )
    1397             :         {
    1398             :             OSL_ENSURE( !aArg.ReplaceExisting,
    1399             :                         "BUG: UnsupportedNameClashException not allowed here!" );
    1400             : 
    1401           0 :             if (exc.NameClash != ucb::NameClash::ERROR) {
    1402             :                 OSL_FAIL( "BUG: NameClash::ERROR expected!" );
    1403             :             }
    1404             : 
    1405             :             // No chance to solve name clashes, because I'm not able to detect
    1406             :             // whether there is one.
    1407             :             throw ucb::UnsupportedNameClashException(
    1408             :                     OUString(
    1409             :                         "Unable to resolve name clashes, no chance to detect "
    1410             :                         "that there is one!" ),
    1411             :                     rContext.xProcessor,
    1412           0 :                     rContext.aArg.NameClash );
    1413             :         }
    1414           0 :         catch ( ucb::NameClashException const & )
    1415             :         {
    1416             :             // The 'insert' command throws a NameClashException if the parameter
    1417             :             // ReplaceExisting of the command's argument was set to false and
    1418             :             // there exists a resource with a clashing name in the target folder
    1419             :             // of the operation.
    1420             : 
    1421             :             // 'insert' command has no direct support for name clashes other
    1422             :             // than ERROR ( ReplaceExisting == false ) and OVERWRITE
    1423             :             // ( ReplaceExisting == true ). So we have to implement the
    1424             :             // other name clash handling directives on top of the content.
    1425             : 
    1426             :             // @@@ 'insert' command should be extended that it accepts a
    1427             :             //     name clash handling directive, exactly like 'transfer' command.
    1428             : 
    1429           0 :             switch ( rContext.aArg.NameClash )
    1430             :             {
    1431             :                 case ucb::NameClash::OVERWRITE:
    1432             :                 {
    1433             :                     ucbhelper::cancelCommandExecution(
    1434             :                         uno::makeAny(
    1435             :                             ucb::UnsupportedNameClashException(
    1436             :                                 OUString(
    1437             :                                     "BUG: insert + replace == true MUST NOT "
    1438             :                                     "throw NameClashException." ),
    1439             :                                 rContext.xProcessor,
    1440           0 :                                 rContext.aArg.NameClash ) ),
    1441           0 :                         rContext.xOrigEnv );
    1442             :                     // Unreachable
    1443             :                 }
    1444             : 
    1445             :                 case ucb::NameClash::ERROR:
    1446           0 :                     throw;
    1447             : 
    1448             :                 case ucb::NameClash::RENAME:
    1449             :                 {
    1450             :                     // "invent" a new valid title.
    1451             :                     handleNameClashRename( rContext,
    1452             :                                            xNew,
    1453             :                                            xCommandProcessorN,
    1454             :                                            xCommandProcessorS,
    1455           0 :                                            xInputStream );
    1456           0 :                     break;
    1457             :                 }
    1458             : 
    1459             :                 case ucb::NameClash::ASK:
    1460             :                     {
    1461           0 :                         uno::Any aExc;
    1462           0 :                         OUString aNewTitle;
    1463             :                         NameClashContinuation eCont
    1464             :                             = interactiveNameClashResolve(
    1465             :                                 rContext.xOrigEnv, // always use original environment!
    1466             :                                 rContext.aArg.TargetURL, // target folder URL
    1467             :                                 aDesiredName,
    1468             :                                 aExc,
    1469           0 :                                 aNewTitle );
    1470             : 
    1471           0 :                         switch ( eCont )
    1472             :                         {
    1473             :                             case NOT_HANDLED:
    1474             :                                 // Not handled.
    1475           0 :                                 cppu::throwException( aExc );
    1476             :     //                            break;
    1477             : 
    1478             :                             case UNKNOWN:
    1479             :                                 // Handled, but not clear, how...
    1480             :                                 // fall-thru intended.
    1481             : 
    1482             :                             case ABORT:
    1483             :                                 throw ucb::CommandFailedException(
    1484             :                                     OUString(
    1485             :                                             "abort requested via interaction "
    1486             :                                             "handler"  ),
    1487             :                                     uno::Reference< uno::XInterface >(),
    1488           0 :                                     aExc );
    1489             :     //                            break;
    1490             : 
    1491             :                             case OVERWRITE:
    1492             :                                 OSL_ENSURE( aArg.ReplaceExisting == sal_False,
    1493             :                                             "Hu? ReplaceExisting already true?"
    1494             :                                           );
    1495           0 :                                 aArg.ReplaceExisting = sal_True;
    1496           0 :                                 bRetry = true;
    1497           0 :                                 break;
    1498             : 
    1499             :                             case NEW_NAME:
    1500             :                             {
    1501             :                                 // set new name -> set "Title" property...
    1502           0 :                                 if ( setTitle( xCommandProcessorN,
    1503             :                                                rContext.xEnv,
    1504           0 :                                                aNewTitle ) )
    1505             :                                 {
    1506             :                                     // remember suggested title...
    1507           0 :                                     aDesiredName = aNewTitle;
    1508             : 
    1509             :                                     // ... and try again.
    1510           0 :                                     bRetry = true;
    1511             :                                 }
    1512             :                                 else
    1513             :                                 {
    1514             :                                     // error setting title. Abort.
    1515             :                                     throw ucb::CommandFailedException(
    1516             :                                         OUString( "error setting Title property!" ),
    1517             :                                         uno::Reference< uno::XInterface >(),
    1518           0 :                                         aExc );
    1519             :                                 }
    1520           0 :                                 break;
    1521             :                             }
    1522             :                         }
    1523             : 
    1524           0 :                         OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
    1525             :                     }
    1526           0 :                     break;
    1527             : 
    1528             :                 case ucb::NameClash::KEEP: // deprecated
    1529             :                 default:
    1530             :                 {
    1531             :                     ucbhelper::cancelCommandExecution(
    1532             :                         uno::makeAny(
    1533             :                             ucb::UnsupportedNameClashException(
    1534             :                                 OUString(
    1535             :                                         "default action, don't know how to "
    1536             :                                         "handle name clash"  ),
    1537             :                                 rContext.xProcessor,
    1538           0 :                                 rContext.aArg.NameClash ) ),
    1539           0 :                         rContext.xOrigEnv );
    1540             :                     // Unreachable
    1541             :                 }
    1542             :             }
    1543             :         }
    1544             :     }
    1545             :     while ( bRetry );
    1546             : 
    1547             : 
    1548             : 
    1549             :     // (6) Process children of source.
    1550             : 
    1551             : 
    1552             : 
    1553          20 :     if ( xResultSet.is() )
    1554             :     {
    1555             :         try
    1556             :         {
    1557             :             // Iterate over children...
    1558             : 
    1559             :             uno::Reference< sdbc::XRow > xChildRow(
    1560           8 :                                             xResultSet, uno::UNO_QUERY );
    1561             : 
    1562           8 :             if ( !xChildRow.is() )
    1563             :             {
    1564             :                 uno::Any aProps
    1565             :                     = uno::makeAny(
    1566             :                              beans::PropertyValue(
    1567             :                                  OUString( "Uri"),
    1568             :                                  -1,
    1569             :                                  uno::makeAny(rContext.aArg.SourceURL),
    1570           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1571             :                 ucbhelper::cancelCommandExecution(
    1572             :                     ucb::IOErrorCode_CANT_READ,
    1573             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1574             :                     rContext.xOrigEnv,
    1575             :                     OUString( "Unable to get properties from children of source!" ),
    1576           0 :                     rContext.xProcessor );
    1577             :                 // Unreachable
    1578             :             }
    1579             : 
    1580             :             uno::Reference< ucb::XContentAccess > xChildAccess(
    1581          16 :                                                 xResultSet, uno::UNO_QUERY );
    1582             : 
    1583           8 :             if ( !xChildAccess.is() )
    1584             :             {
    1585             :                 uno::Any aProps
    1586             :                     = uno::makeAny(
    1587             :                              beans::PropertyValue(
    1588             :                                  OUString( "Uri"),
    1589             :                                  -1,
    1590             :                                  uno::makeAny(rContext.aArg.SourceURL),
    1591           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1592             :                 ucbhelper::cancelCommandExecution(
    1593             :                     ucb::IOErrorCode_CANT_READ,
    1594             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1595             :                     rContext.xOrigEnv,
    1596             :                     OUString( "Unable to get children of source!" ),
    1597           0 :                     rContext.xProcessor );
    1598             :                 // Unreachable
    1599             :             }
    1600             : 
    1601           8 :             if ( xResultSet->first() )
    1602             :             {
    1603             :                 ucb::GlobalTransferCommandArgument2 aTransArg(
    1604             :                         rContext.aArg.Operation,
    1605             :                         OUString(),              // SourceURL; filled later
    1606           8 :                         xNew->getIdentifier()
    1607          16 :                             ->getContentIdentifier(), // TargetURL
    1608             :                         OUString(),              // NewTitle;
    1609             :                         rContext.aArg.NameClash,
    1610             :                         rContext.aArg.MimeType,
    1611          24 :                         rContext.aArg.DocumentId);
    1612             : 
    1613             :                 TransferCommandContext aSubCtx(
    1614             :                         rContext.m_xContext,
    1615             :                         rContext.xProcessor,
    1616             :                         rContext.xEnv,
    1617             :                         rContext.xOrigEnv,
    1618          16 :                         aTransArg );
    1619          16 :                 do
    1620             :                 {
    1621             :                     uno::Reference< ucb::XContent > xChild
    1622          16 :                                         = xChildAccess->queryContent();
    1623          16 :                     if ( xChild.is() )
    1624             :                     {
    1625             :                         // Recursion!
    1626             : 
    1627             :                         aSubCtx.aArg.SourceURL
    1628          16 :                             = xChild->getIdentifier()->getContentIdentifier();
    1629             : 
    1630             :                         globalTransfer_( aSubCtx,
    1631             :                                          xChild,
    1632             :                                          xNew,
    1633          16 :                                          xChildRow );
    1634          16 :                     }
    1635             :                 }
    1636          24 :                 while ( xResultSet->next() );
    1637           8 :             }
    1638             :         }
    1639           0 :         catch ( sdbc::SQLException const & )
    1640             :         {
    1641             :         }
    1642             :     }
    1643             : 
    1644             :     try {
    1645             :         uno::Reference< ucb::XCommandProcessor > xcp(
    1646          20 :             xTarget, uno::UNO_QUERY );
    1647             : 
    1648          40 :         uno::Any aAny;
    1649          40 :         uno::Reference< ucb::XCommandInfo > xci;
    1650          20 :         if(xcp.is())
    1651          40 :             aAny =
    1652          20 :                 xcp->execute(
    1653             :                     ucb::Command(
    1654             :                         OUString("getCommandInfo"),
    1655             :                         -1,
    1656             :                         uno::Any()),
    1657             :                     0,
    1658          40 :                     rContext.xEnv );
    1659             : 
    1660          40 :         const OUString cmdName("flush");
    1661          20 :         if((aAny >>= xci) && xci->hasCommandByName(cmdName))
    1662           0 :             xcp->execute(
    1663             :                 ucb::Command(
    1664             :                     cmdName,
    1665             :                     -1,
    1666             :                     uno::Any()) ,
    1667             :                 0,
    1668          20 :                 rContext.xEnv );
    1669             :     }
    1670           0 :     catch( uno::Exception const & )
    1671             :     {
    1672          40 :     }
    1673          20 : }
    1674             : 
    1675             : } /* namescpace */
    1676             : 
    1677             : 
    1678             : 
    1679             : // UniversalContentBroker implementation ( XCommandProcessor commands ).
    1680             : 
    1681             : 
    1682             : 
    1683             : uno::Reference< ucb::XCommandInfo >
    1684           0 : UniversalContentBroker::getCommandInfo()
    1685             : {
    1686           0 :     return uno::Reference< ucb::XCommandInfo >( new CommandProcessorInfo() );
    1687             : }
    1688             : 
    1689             : 
    1690        5589 : void UniversalContentBroker::globalTransfer(
    1691             :             const ucb::GlobalTransferCommandArgument2 & rArg,
    1692             :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1693             :     throw( uno::Exception )
    1694             : {
    1695             :     // Use own command environment with own interaction handler intercepting
    1696             :     // some interaction requests that shall not be handled by the user-supplied
    1697             :     // interaction handler.
    1698        5589 :     uno::Reference< ucb::XCommandEnvironment > xLocalEnv;
    1699        5589 :     if (xEnv.is())
    1700             :     {
    1701             :         xLocalEnv.set( ucb::CommandEnvironment::create(
    1702             :                m_xContext,
    1703          12 :                new InteractionHandlerProxy( xEnv->getInteractionHandler() ),
    1704          18 :                xEnv->getProgressHandler() ) );
    1705             :     }
    1706             : 
    1707             : 
    1708             : 
    1709             :     // (1) Try to transfer the content using 'transfer' command.
    1710             : 
    1711             : 
    1712             : 
    1713        5598 :     uno::Reference< ucb::XContent > xTarget;
    1714             :     uno::Reference< ucb::XContentIdentifier > xId
    1715        5598 :             = createContentIdentifier( rArg.TargetURL );
    1716        5589 :     if ( xId.is() )
    1717             :     {
    1718             :         try
    1719             :         {
    1720        5589 :             xTarget = queryContent( xId );
    1721             :         }
    1722           0 :         catch ( ucb::IllegalIdentifierException const & )
    1723             :         {
    1724             :         }
    1725             :     }
    1726             : 
    1727        5589 :     if ( !xTarget.is() )
    1728             :     {
    1729             :         uno::Any aProps
    1730             :             = uno::makeAny(beans::PropertyValue(
    1731             :                                   OUString( "Uri"),
    1732             :                                   -1,
    1733             :                                   uno::makeAny(rArg.TargetURL),
    1734           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1735             :         ucbhelper::cancelCommandExecution(
    1736             :             ucb::IOErrorCode_CANT_READ,
    1737             :             uno::Sequence< uno::Any >(&aProps, 1),
    1738             :             xEnv,
    1739             :             OUString( "Can't instanciate target object!" ),
    1740           0 :             this );
    1741             :         // Unreachable
    1742             :     }
    1743             : 
    1744        5590 :     if ( ( rArg.Operation == ucb::TransferCommandOperation_COPY ) ||
    1745           1 :          ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) )
    1746             :     {
    1747             :         uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
    1748        5589 :                                                     xTarget, uno::UNO_QUERY );
    1749        5589 :         if ( !xCommandProcessor.is() )
    1750             :         {
    1751             :             uno::Any aProps
    1752             :                 = uno::makeAny(
    1753             :                          beans::PropertyValue(
    1754             :                              OUString( "Uri"),
    1755             :                              -1,
    1756             :                              uno::makeAny(rArg.TargetURL),
    1757           0 :                              beans::PropertyState_DIRECT_VALUE));
    1758             :             ucbhelper::cancelCommandExecution(
    1759             :                 ucb::IOErrorCode_CANT_READ,
    1760             :                 uno::Sequence< uno::Any >(&aProps, 1),
    1761             :                 xEnv,
    1762             :                 OUString( "Target content is not a XCommandProcessor!" ),
    1763           0 :                 this );
    1764             :             // Unreachable
    1765             :         }
    1766             : 
    1767             :         ucb::TransferInfo2 aTransferArg(
    1768             :             ( rArg.Operation
    1769        5589 :                 == ucb::TransferCommandOperation_MOVE ), // MoveData
    1770             :             rArg.SourceURL,
    1771             :             rArg.NewTitle,
    1772             :             rArg.NameClash,
    1773       11187 :             rArg.MimeType );
    1774             : 
    1775             :         bool bRetry;
    1776           4 :         do
    1777             :         {
    1778        5589 :             bRetry = false;
    1779             : 
    1780             :             try
    1781             :             {
    1782             :                 ucb::Command aCommand(
    1783             :                     OUString( "transfer" ), // Name
    1784             :                     -1,                                           // Handle
    1785        5589 :                     uno::makeAny( aTransferArg ) );               // Argument
    1786             : 
    1787        5589 :                 xCommandProcessor->execute( aCommand, 0, xLocalEnv );
    1788             : 
    1789             :                 // Command succeeded. We're done.
    1790        5589 :                 return;
    1791             :             }
    1792           4 :             catch ( ucb::InteractiveBadTransferURLException const & )
    1793             :             {
    1794             :                 // Source URL is not supported by target. Try to transfer
    1795             :                 // the content "manually".
    1796             :             }
    1797           0 :             catch ( ucb::UnsupportedCommandException const & )
    1798             :             {
    1799             :                 // 'transfer' command is not supported by commandprocessor.
    1800             :                 // Try to transfer manually.
    1801             :             }
    1802           0 :             catch ( ucb::UnsupportedNameClashException const & exc )
    1803             :             {
    1804             :                 OSL_ENSURE( aTransferArg.NameClash == exc.NameClash,
    1805             :                             "nameclash mismatch!" );
    1806           0 :                 if ( exc.NameClash == ucb::NameClash::ASK )
    1807             :                 {
    1808             :                     // Try to detect a name clash by invoking "transfer" with
    1809             :                     // NameClash::ERROR.
    1810             :                     try
    1811             :                     {
    1812             :                         ucb::TransferInfo2 aTransferArg1(
    1813             :                             aTransferArg.MoveData,
    1814             :                             aTransferArg.SourceURL,
    1815             :                             aTransferArg.NewTitle,
    1816             :                             ucb::NameClash::ERROR,
    1817           0 :                             aTransferArg.MimeType );
    1818             : 
    1819             :                         ucb::Command aCommand1(
    1820             :                             OUString("transfer"),
    1821             :                             -1,
    1822           0 :                             uno::makeAny( aTransferArg1 ) );
    1823             : 
    1824           0 :                         xCommandProcessor->execute( aCommand1, 0, xLocalEnv );
    1825             : 
    1826             :                         // Command succeeded. We're done.
    1827           0 :                         return;
    1828             :                     }
    1829           0 :                     catch ( ucb::UnsupportedNameClashException const & )
    1830             :                     {
    1831             :                         // No chance to solve name clashes, because I'm not
    1832             :                         // able to detect whether there is one.
    1833           0 :                         throw exc; // Not just 'throw;'!
    1834             :                     }
    1835           0 :                     catch ( ucb::NameClashException const & )
    1836             :                     {
    1837             :                         // There's a clash. Use interaction handler to solve it.
    1838             : 
    1839           0 :                         uno::Any aExc;
    1840           0 :                         OUString aNewTitle;
    1841             :                         NameClashContinuation eCont
    1842             :                             = interactiveNameClashResolve(
    1843             :                                 xEnv, // always use original environment!
    1844             :                                 rArg.TargetURL,  // target folder URL
    1845             :                                 createDesiredName(
    1846             :                                   aTransferArg ),   // clashing name
    1847             :                                 aExc,
    1848           0 :                                 aNewTitle );
    1849             : 
    1850           0 :                         switch ( eCont )
    1851             :                         {
    1852             :                             case NOT_HANDLED:
    1853             :                                 // Not handled.
    1854           0 :                                 cppu::throwException( aExc );
    1855             : //                                break;
    1856             : 
    1857             :                             case UNKNOWN:
    1858             :                                 // Handled, but not clear, how...
    1859             :                                 // fall-thru intended.
    1860             : 
    1861             :                             case ABORT:
    1862             :                                 throw ucb::CommandFailedException(
    1863             :                                     OUString(
    1864             :                                             "abort requested via interaction "
    1865             :                                             "handler"  ),
    1866             :                                     uno::Reference< uno::XInterface >(),
    1867           0 :                                     aExc );
    1868             : //                                break;
    1869             : 
    1870             :                             case OVERWRITE:
    1871             :                                 aTransferArg.NameClash
    1872           0 :                                     = ucb::NameClash::OVERWRITE;
    1873           0 :                                 bRetry = true;
    1874           0 :                                 break;
    1875             : 
    1876             :                             case NEW_NAME:
    1877           0 :                                 aTransferArg.NewTitle = aNewTitle;
    1878           0 :                                 bRetry = true;
    1879           0 :                                 break;
    1880             :                         }
    1881             : 
    1882           0 :                         OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
    1883             :                     }
    1884             :                 }
    1885             :                 else
    1886             :                 {
    1887           0 :                     throw;
    1888             :                 }
    1889           0 :             }
    1890             :         }
    1891           9 :         while ( bRetry );
    1892             :     }
    1893             : 
    1894             : 
    1895             : 
    1896             :     // (2) Try to transfer the content "manually".
    1897             : 
    1898             : 
    1899             : 
    1900           4 :     uno::Reference< ucb::XContent > xSource;
    1901             :     try
    1902             :     {
    1903             :         uno::Reference< ucb::XContentIdentifier > xId2
    1904           4 :             = createContentIdentifier( rArg.SourceURL );
    1905           4 :         if ( xId2.is() )
    1906           4 :             xSource = queryContent( xId2 );
    1907             :     }
    1908           0 :     catch ( ucb::IllegalIdentifierException const & )
    1909             :     {
    1910             :         // Error handling via "if ( !xSource.is() )" below.
    1911             :     }
    1912             : 
    1913           4 :     if ( !xSource.is() )
    1914             :     {
    1915             :         uno::Any aProps
    1916             :             = uno::makeAny(beans::PropertyValue(
    1917             :                                   OUString( "Uri"),
    1918             :                                   -1,
    1919             :                                   uno::makeAny(rArg.SourceURL),
    1920           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1921             :         ucbhelper::cancelCommandExecution(
    1922             :             ucb::IOErrorCode_CANT_READ,
    1923             :             uno::Sequence< uno::Any >(&aProps, 1),
    1924             :             xEnv,
    1925             :             OUString( "Can't instanciate source object!" ),
    1926           0 :             this );
    1927             :         // Unreachable
    1928             :     }
    1929             : 
    1930             :     uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
    1931           8 :                                                 xSource, uno::UNO_QUERY );
    1932           4 :     if ( !xCommandProcessor.is() )
    1933             :     {
    1934             :         uno::Any aProps
    1935             :             = uno::makeAny(beans::PropertyValue(
    1936             :                                   OUString( "Uri"),
    1937             :                                   -1,
    1938             :                                   uno::makeAny(rArg.SourceURL),
    1939           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1940             :         ucbhelper::cancelCommandExecution(
    1941             :             ucb::IOErrorCode_CANT_READ,
    1942             :             uno::Sequence< uno::Any >(&aProps, 1),
    1943             :             xEnv,
    1944             :             OUString( "Source content is not a XCommandProcessor!" ),
    1945           0 :             this );
    1946             :         // Unreachable
    1947             :     }
    1948             : 
    1949             :     // Obtain interesting property values from source...
    1950             : 
    1951           8 :     uno::Sequence< beans::Property > aProps( 4 );
    1952             : 
    1953           4 :     aProps[ 0 ].Name   = "IsFolder";
    1954           4 :     aProps[ 0 ].Handle = -1; /* unknown */
    1955           4 :     aProps[ 1 ].Name   = "IsDocument";
    1956           4 :     aProps[ 1 ].Handle = -1; /* unknown */
    1957           4 :     aProps[ 2 ].Name   = "TargetURL";
    1958           4 :     aProps[ 2 ].Handle = -1; /* unknown */
    1959           4 :     aProps[ 3 ].Name   = "BaseURI";
    1960           4 :     aProps[ 3 ].Handle = -1; /* unknown */
    1961             : 
    1962             :     ucb::Command aGetPropsCommand(
    1963             :                 OUString("getPropertyValues"),
    1964             :                 -1,
    1965           8 :                 uno::makeAny( aProps ) );
    1966             : 
    1967           8 :     uno::Reference< sdbc::XRow > xRow;
    1968           4 :     xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow;
    1969             : 
    1970           4 :     if ( !xRow.is() )
    1971             :     {
    1972             :         uno::Any aProps2
    1973             :             = uno::makeAny(beans::PropertyValue(
    1974             :                                OUString( "Uri"),
    1975             :                                   -1,
    1976             :                                   uno::makeAny(rArg.SourceURL),
    1977           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1978             :         ucbhelper::cancelCommandExecution(
    1979             :             ucb::IOErrorCode_CANT_READ,
    1980             :             uno::Sequence< uno::Any >(&aProps2, 1),
    1981             :             xEnv,
    1982             :             OUString( "Unable to get properties from source object!" ),
    1983           0 :             this );
    1984             :         // Unreachable
    1985             :     }
    1986             : 
    1987             :     TransferCommandContext aTransferCtx(
    1988           8 :         m_xContext, this, xLocalEnv, xEnv, rArg );
    1989             : 
    1990           4 :     if ( rArg.NewTitle.isEmpty() )
    1991             :     {
    1992             :         // BaseURI: property is optional.
    1993           0 :         OUString aBaseURI( xRow->getString( 4 ) );
    1994           0 :         if ( !aBaseURI.isEmpty() )
    1995             :         {
    1996             :             aTransferCtx.aArg.NewTitle
    1997           0 :                 = createDesiredName( aBaseURI, OUString() );
    1998           0 :         }
    1999             :     }
    2000             : 
    2001             :     // Do it!
    2002           4 :     globalTransfer_( aTransferCtx, xSource, xTarget, xRow );
    2003             : 
    2004             : 
    2005             : 
    2006             :     // (3) Delete source, if operation is MOVE.
    2007             : 
    2008             : 
    2009             : 
    2010           4 :     if ( rArg.Operation == ucb::TransferCommandOperation_MOVE )
    2011             :     {
    2012             :         try
    2013             :         {
    2014             :             ucb::Command aCommand(
    2015             :                 OUString("delete"), // Name
    2016             :                 -1,                                         // Handle
    2017           0 :                 uno::makeAny( true ) );     // Argument
    2018             : 
    2019           0 :             xCommandProcessor->execute( aCommand, 0, xLocalEnv );
    2020             :         }
    2021           0 :         catch ( uno::Exception const & )
    2022             :         {
    2023             :             OSL_FAIL( "Cannot delete source object!" );
    2024           0 :             throw;
    2025             :         }
    2026          13 :     }
    2027             : }
    2028             : 
    2029           0 : uno::Any UniversalContentBroker::checkIn( const ucb::CheckinArgument& rArg,
    2030             :             const uno::Reference< ucb::XCommandEnvironment >& xEnv ) throw ( uno::Exception )
    2031             : {
    2032           0 :     uno::Any aRet;
    2033             :     // Use own command environment with own interaction handler intercepting
    2034             :     // some interaction requests that shall not be handled by the user-supplied
    2035             :     // interaction handler.
    2036           0 :     uno::Reference< ucb::XCommandEnvironment > xLocalEnv;
    2037           0 :     if (xEnv.is())
    2038             :     {
    2039             :         xLocalEnv.set( ucb::CommandEnvironment::create(
    2040             :                m_xContext,
    2041           0 :                new InteractionHandlerProxy( xEnv->getInteractionHandler() ),
    2042           0 :                xEnv->getProgressHandler() ) );
    2043             :     }
    2044             : 
    2045           0 :     uno::Reference< ucb::XContent > xTarget;
    2046             :     uno::Reference< ucb::XContentIdentifier > xId
    2047           0 :             = createContentIdentifier( rArg.TargetURL );
    2048           0 :     if ( xId.is() )
    2049             :     {
    2050             :         try
    2051             :         {
    2052           0 :             xTarget = queryContent( xId );
    2053             :         }
    2054           0 :         catch ( ucb::IllegalIdentifierException const & )
    2055             :         {
    2056             :         }
    2057             :     }
    2058             : 
    2059           0 :     if ( !xTarget.is() )
    2060             :     {
    2061             :         uno::Any aProps
    2062             :             = uno::makeAny(beans::PropertyValue(
    2063             :                                   OUString( "Uri" ), -1,
    2064             :                                   uno::makeAny( rArg.TargetURL ),
    2065           0 :                                   beans::PropertyState_DIRECT_VALUE ) );
    2066             :         ucbhelper::cancelCommandExecution(
    2067             :             ucb::IOErrorCode_CANT_READ,
    2068             :             uno::Sequence< uno::Any >( &aProps, 1 ),
    2069             :             xEnv,
    2070             :             OUString( "Can't instanciate target object!" ),
    2071           0 :             this );
    2072             :         // Unreachable
    2073             :     }
    2074             : 
    2075             :     uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
    2076           0 :                                                 xTarget, uno::UNO_QUERY );
    2077           0 :     if ( !xCommandProcessor.is() )
    2078             :     {
    2079             :         uno::Any aProps
    2080             :             = uno::makeAny(
    2081             :                      beans::PropertyValue(
    2082             :                          OUString( "Uri" ), -1,
    2083             :                          uno::makeAny( rArg.TargetURL ),
    2084           0 :                          beans::PropertyState_DIRECT_VALUE ) );
    2085             :         ucbhelper::cancelCommandExecution(
    2086             :             ucb::IOErrorCode_CANT_READ,
    2087             :             uno::Sequence< uno::Any >( &aProps, 1 ),
    2088             :             xEnv,
    2089             :             OUString( "Target content is not a XCommandProcessor!" ),
    2090           0 :             this );
    2091             :         // Unreachable
    2092             :     }
    2093             : 
    2094             :     try
    2095             :     {
    2096             :         ucb::Command aCommand(
    2097             :             OUString( "checkin" ), -1,
    2098           0 :             uno::makeAny( rArg ) );
    2099             : 
    2100           0 :         aRet = xCommandProcessor->execute( aCommand, 0, xLocalEnv );
    2101             :     }
    2102           0 :     catch ( ucb::UnsupportedCommandException const & )
    2103             :     {
    2104             :         // 'checkin' command is not supported by commandprocessor:
    2105             :         // ignore.
    2106             :     }
    2107           0 :     return aRet;
    2108             : }
    2109             : 
    2110             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10