Files
libreoffice/ucb/source/core/ucbcmds.cxx

1636 lines
60 KiB
C++
Raw Normal View History

2001-02-02 07:18:49 +00:00
/*************************************************************************
*
* $RCSfile: ucbcmds.cxx,v $
*
* $Revision: 1.10 $
2001-02-02 07:18:49 +00:00
*
* last change: $Author: hr $ $Date: 2003-03-27 17:26:39 $
2001-02-02 07:18:49 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): Kai Sommerfeld ( kso@sun.com )
*
*
************************************************************************/
/**************************************************************************
TODO
**************************************************************************
*************************************************************************/
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef _RTL_USTRING_H_
#include <rtl/ustring.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif
2001-04-20 14:40:03 +00:00
#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
#include <com/sun/star/io/XSeekable.hpp>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_CONTENTINFOATTRIBUTE_HPP_
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_GLOBALTRANSFERCOMMANDARGUMENT_HPP_
#include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
#endif
2001-04-20 14:40:03 +00:00
#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
#include <com/sun/star/ucb/NameClash.hpp>
#endif
2001-06-25 07:51:54 +00:00
#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
#include <com/sun/star/ucb/NameClashException.hpp>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
#include <com/sun/star/ucb/OpenMode.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_TRANSFERINFO_HPP_
#include <com/sun/star/ucb/TransferInfo.hpp>
#endif
2001-06-25 07:51:54 +00:00
#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDNAMECLASHEXCEPTION_HPP_
#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _COM_SUN_STAR_UCB_XCOMMANDINFO_HPP_
#include <com/sun/star/ucb/XCommandInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_
#include <com/sun/star/ucb/XContentAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XDYNAMICRESULTSET_HPP_
#include <com/sun/star/ucb/XDynamicResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _UCBHELPER_COMMANDENVIRONMENTPROXY_HXX
#include <ucbhelper/commandenvironmentproxy.hxx>
#endif
2001-06-25 07:51:54 +00:00
#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
#include <ucbhelper/cancelcommandexecution.hxx>
#endif
2001-02-02 07:18:49 +00:00
#ifndef _UCBCMDS_HXX
#include "ucbcmds.hxx"
#endif
#ifndef _UCB_HXX
#include "ucb.hxx"
#endif
2001-06-25 07:51:54 +00:00
using namespace com::sun;
2001-02-02 07:18:49 +00:00
using namespace com::sun::star;
namespace ucb_commands
{
2001-06-25 07:51:54 +00:00
//=========================================================================
//
// struct TransferCommandContext.
//
//=========================================================================
struct TransferCommandContext
{
uno::Reference< lang::XMultiServiceFactory > xSMgr;
uno::Reference< star::ucb::XCommandProcessor > xProcessor;
uno::Reference< star::ucb::XCommandEnvironment > xEnv;
star::ucb::GlobalTransferCommandArgument aArg;
TransferCommandContext(
const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
const uno::Reference< star::ucb::XCommandProcessor > & rxProcessor,
const uno::Reference< star::ucb::XCommandEnvironment > & rxEnv,
const star::ucb::GlobalTransferCommandArgument & rArg )
: xSMgr( rxSMgr ), xProcessor( rxProcessor ), xEnv( rxEnv ), aArg( rArg ) {}
};
2001-02-02 07:18:49 +00:00
//=========================================================================
//
// class ActiveDataSink.
//
//=========================================================================
class ActiveDataSink : public cppu::OWeakObject, public io::XActiveDataSink
{
uno::Reference< io::XInputStream > m_xStream;
public:
// XInterface methods
virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
throw( uno::RuntimeException );
virtual void SAL_CALL acquire()
throw();
virtual void SAL_CALL release()
throw();
2001-02-02 07:18:49 +00:00
// XActiveDataSink methods.
virtual void SAL_CALL setInputStream(
const uno::Reference< io::XInputStream >& aStream )
throw( uno::RuntimeException );
virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
throw( uno::RuntimeException );
};
//=========================================================================
// virtual
uno::Any SAL_CALL ActiveDataSink::queryInterface( const uno::Type & rType )
throw( uno::RuntimeException )
{
uno::Any aRet = cppu::queryInterface(
rType,
static_cast< io::XActiveDataSink * >( this ) );
return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}
//=========================================================================
// virtual
void SAL_CALL ActiveDataSink::acquire()
throw()
2001-02-02 07:18:49 +00:00
{
OWeakObject::acquire();
}
//=========================================================================
// virtual
void SAL_CALL ActiveDataSink::release()
throw()
2001-02-02 07:18:49 +00:00
{
OWeakObject::release();
}
//=========================================================================
// virtual
void SAL_CALL ActiveDataSink::setInputStream(
const uno::Reference< io::XInputStream >& aStream )
throw( uno::RuntimeException )
{
m_xStream = aStream;
}
//=========================================================================
// virtual
uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream()
throw( uno::RuntimeException )
{
return m_xStream;
}
//=========================================================================
//
// class CommandProcessorInfo.
//
//=========================================================================
2001-06-25 07:51:54 +00:00
class CommandProcessorInfo : public cppu::OWeakObject,
public star::ucb::XCommandInfo
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
uno::Sequence< star::ucb::CommandInfo > * m_pInfo;
2001-02-02 07:18:49 +00:00
public:
CommandProcessorInfo();
virtual ~CommandProcessorInfo();
// XInterface methods
virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
throw( uno::RuntimeException );
virtual void SAL_CALL acquire()
throw();
virtual void SAL_CALL release()
throw();
2001-02-02 07:18:49 +00:00
// XCommandInfo methods
2001-06-25 07:51:54 +00:00
virtual uno::Sequence< star::ucb::CommandInfo > SAL_CALL getCommands()
2001-02-02 07:18:49 +00:00
throw( uno::RuntimeException );
2001-06-25 07:51:54 +00:00
virtual star::ucb::CommandInfo SAL_CALL
2001-02-02 07:18:49 +00:00
getCommandInfoByName( const rtl::OUString& Name )
2001-06-25 07:51:54 +00:00
throw( star::ucb::UnsupportedCommandException, uno::RuntimeException );
virtual star::ucb::CommandInfo SAL_CALL
2001-02-02 07:18:49 +00:00
getCommandInfoByHandle( sal_Int32 Handle )
2001-06-25 07:51:54 +00:00
throw( star::ucb::UnsupportedCommandException, uno::RuntimeException );
2001-02-02 07:18:49 +00:00
virtual sal_Bool SAL_CALL hasCommandByName( const rtl::OUString& Name )
throw( uno::RuntimeException );
virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle )
throw( uno::RuntimeException );
};
//=========================================================================
CommandProcessorInfo::CommandProcessorInfo()
{
2001-06-25 07:51:54 +00:00
m_pInfo = new uno::Sequence< star::ucb::CommandInfo >( 2 );
2001-02-02 07:18:49 +00:00
(*m_pInfo)[ 0 ]
2001-06-25 07:51:54 +00:00
= star::ucb::CommandInfo(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( GETCOMMANDINFO_NAME ), // Name
GETCOMMANDINFO_HANDLE, // Handle
getCppuVoidType() ); // ArgType
(*m_pInfo)[ 1 ]
2001-06-25 07:51:54 +00:00
= star::ucb::CommandInfo(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( GLOBALTRANSFER_NAME ), // Name
GLOBALTRANSFER_HANDLE, // Handle
2001-06-25 07:51:54 +00:00
getCppuType(
static_cast<
star::ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType
2001-02-02 07:18:49 +00:00
}
//=========================================================================
// virtual
CommandProcessorInfo::~CommandProcessorInfo()
{
delete m_pInfo;
}
//=========================================================================
// virtual
uno::Any SAL_CALL CommandProcessorInfo::queryInterface(
const uno::Type & rType )
throw( uno::RuntimeException )
{
uno::Any aRet = cppu::queryInterface(
rType,
2001-06-25 07:51:54 +00:00
static_cast< star::ucb::XCommandInfo * >( this ) );
2001-02-02 07:18:49 +00:00
return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}
//=========================================================================
// virtual
void SAL_CALL CommandProcessorInfo::acquire()
throw()
2001-02-02 07:18:49 +00:00
{
OWeakObject::acquire();
}
//=========================================================================
// virtual
void SAL_CALL CommandProcessorInfo::release()
throw()
2001-02-02 07:18:49 +00:00
{
OWeakObject::release();
}
//=========================================================================
// virtual
2001-06-25 07:51:54 +00:00
uno::Sequence< star::ucb::CommandInfo > SAL_CALL
CommandProcessorInfo::getCommands()
2001-02-02 07:18:49 +00:00
throw( uno::RuntimeException )
{
2001-06-25 07:51:54 +00:00
return uno::Sequence< star::ucb::CommandInfo >( *m_pInfo );
2001-02-02 07:18:49 +00:00
}
//=========================================================================
// virtual
2001-06-25 07:51:54 +00:00
star::ucb::CommandInfo SAL_CALL
CommandProcessorInfo::getCommandInfoByName( const rtl::OUString& Name )
throw( star::ucb::UnsupportedCommandException, uno::RuntimeException )
2001-02-02 07:18:49 +00:00
{
for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
{
if ( (*m_pInfo)[ n ].Name == Name )
2001-06-25 07:51:54 +00:00
return star::ucb::CommandInfo( (*m_pInfo)[ n ] );
2001-02-02 07:18:49 +00:00
}
2001-06-25 07:51:54 +00:00
throw star::ucb::UnsupportedCommandException();
2001-02-02 07:18:49 +00:00
}
//=========================================================================
// virtual
2001-06-25 07:51:54 +00:00
star::ucb::CommandInfo SAL_CALL
CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle )
throw( star::ucb::UnsupportedCommandException, uno::RuntimeException )
2001-02-02 07:18:49 +00:00
{
for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
{
if ( (*m_pInfo)[ n ].Handle == Handle )
2001-06-25 07:51:54 +00:00
return star::ucb::CommandInfo( (*m_pInfo)[ n ] );
2001-02-02 07:18:49 +00:00
}
2001-06-25 07:51:54 +00:00
throw star::ucb::UnsupportedCommandException();
2001-02-02 07:18:49 +00:00
}
//=========================================================================
// virtual
sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName(
const rtl::OUString& Name )
throw( uno::RuntimeException )
{
for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
{
if ( (*m_pInfo)[ n ].Name == Name )
return sal_True;
}
return sal_False;
}
//=========================================================================
// virtual
sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle )
throw( uno::RuntimeException )
{
for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
{
if ( (*m_pInfo)[ n ].Handle == Handle )
return sal_True;
}
return sal_False;
}
//=========================================================================
//=========================================================================
//=========================================================================
2001-06-25 07:51:54 +00:00
static uno::Reference< star::ucb::XContent > createNew(
const TransferCommandContext & rContext,
const uno::Reference< star::ucb::XContent > & xTarget,
sal_Bool bSourceIsFolder,
sal_Bool bSourceIsDocument,
sal_Bool bSourceIsLink )
2001-02-02 07:18:49 +00:00
throw( uno::Exception )
{
//////////////////////////////////////////////////////////////////////
//
// (1) Obtain creatable types from target.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContentCreator > xCreator(
xTarget, uno::UNO_QUERY );
2001-02-02 07:18:49 +00:00
if ( !xCreator.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Folder")),
-1,
uno::makeAny(rContext.aArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_CREATE,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii( "Target is no XContentCreator!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
uno::Sequence< star::ucb::ContentInfo > aTypesInfo
2001-02-02 07:18:49 +00:00
= xCreator->queryCreatableContentsInfo();
sal_Int32 nCount = aTypesInfo.getLength();
if ( !nCount )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Folder")),
-1,
uno::makeAny(rContext.aArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_CREATE,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii( "No types creatable!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (2) Try to find a matching target type for the source object.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContent > xNew;
2001-02-02 07:18:49 +00:00
for ( sal_Int32 n = 0; n < nCount; ++n )
{
sal_Int32 nAttribs = aTypesInfo[ n ].Attributes;
sal_Bool bMatch = sal_False;
2001-06-25 07:51:54 +00:00
if ( rContext.aArg.Operation
== star::ucb::TransferCommandOperation_LINK )
2001-02-02 07:18:49 +00:00
{
// Create link
2001-06-25 07:51:54 +00:00
if ( nAttribs & star::ucb::ContentInfoAttribute::KIND_LINK )
2001-02-02 07:18:49 +00:00
{
// Match!
bMatch = sal_True;
}
}
2001-06-25 07:51:54 +00:00
else if ( ( rContext.aArg.Operation
== star::ucb::TransferCommandOperation_COPY ) ||
( rContext.aArg.Operation
== star::ucb::TransferCommandOperation_MOVE ) )
2001-02-02 07:18:49 +00:00
{
// Copy / Move
// Is source a link? Create link in target folder then.
if ( bSourceIsLink )
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
if ( nAttribs & star::ucb::ContentInfoAttribute::KIND_LINK )
{
// Match!
bMatch = sal_True;
}
2001-02-02 07:18:49 +00:00
}
else
{
if ( ( bSourceIsFolder ==
2001-06-25 07:51:54 +00:00
!!( nAttribs
& star::ucb::ContentInfoAttribute::KIND_FOLDER ) )
&&
2001-02-02 07:18:49 +00:00
( bSourceIsDocument ==
2001-06-25 07:51:54 +00:00
!!( nAttribs
& star::ucb::ContentInfoAttribute::KIND_DOCUMENT ) )
)
2001-02-02 07:18:49 +00:00
{
// Match!
bMatch = sal_True;
}
}
}
else
{
2001-06-25 07:51:54 +00:00
ucbhelper::cancelCommandExecution(
uno::makeAny( lang::IllegalArgumentException(
rtl::OUString::createFromAscii(
"Unknown transfer operation!" ),
rContext.xProcessor,
-1 ) ),
rContext.xEnv );
// Unreachable
2001-02-02 07:18:49 +00:00
}
if ( bMatch )
{
//////////////////////////////////////////////////////////////
//
// (3) Create a new, empty object of matched type.
//
//////////////////////////////////////////////////////////////
xNew = xCreator->createNewContent( aTypesInfo[ n ] );
if ( !xNew.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Folder")),
-1,
uno::makeAny(rContext.aArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_CREATE,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"createNewContent failed!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
break;
}
}
return xNew;
}
//=========================================================================
static void transferProperties(
2001-06-25 07:51:54 +00:00
const TransferCommandContext & rContext,
const uno::Reference< star::ucb::XCommandProcessor > & xCommandProcessorS,
const uno::Reference< star::ucb::XCommandProcessor > & xCommandProcessorN )
throw( uno::Exception )
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
star::ucb::Command aGetPropertySetInfoCommand(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "getPropertySetInfo" ),
-1,
uno::Any() );
uno::Reference< beans::XPropertySetInfo > xInfo;
2001-06-25 07:51:54 +00:00
xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv )
2001-02-02 07:18:49 +00:00
>>= xInfo;
if ( !xInfo.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rContext.aArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"Unable to get propertyset info from source object!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
uno::Sequence< beans::Property > aAllProps = xInfo->getProperties();
2001-06-25 07:51:54 +00:00
star::ucb::Command aGetPropsCommand1(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "getPropertyValues" ),
-1,
uno::makeAny( aAllProps ) );
uno::Reference< sdbc::XRow > xRow1;
2001-06-25 07:51:54 +00:00
xCommandProcessorS->execute(
aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1;
2001-02-02 07:18:49 +00:00
if ( !xRow1.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rContext.aArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"Unable to get properties from source object!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
// Assemble data structure for setPropertyValues command.
// Note: Make room for additional Title and TargetURL too. -> + 2
uno::Sequence< beans::PropertyValue > aPropValues(
aAllProps.getLength() + 2 );
2001-06-25 07:51:54 +00:00
sal_Bool bHasTitle = ( rContext.aArg.NewTitle.getLength() == 0 );
sal_Bool bHasTargetURL = ( rContext.aArg.Operation
!= star::ucb::TransferCommandOperation_LINK );
2001-02-02 07:18:49 +00:00
sal_Int32 nWritePos = 0;
for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m )
{
const beans::Property & rCurrProp = aAllProps[ m ];
beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ];
uno::Any aValue;
if ( rCurrProp.Name.compareToAscii( "Title" ) == 0 )
{
// Supply new title, if given.
if ( !bHasTitle )
{
bHasTitle = sal_True;
2001-06-25 07:51:54 +00:00
aValue <<= rContext.aArg.NewTitle;
2001-02-02 07:18:49 +00:00
}
}
else if ( rCurrProp.Name.compareToAscii( "TargetURL" ) == 0 )
{
// Supply source URL as link target for the new link to create.
if ( !bHasTargetURL )
{
bHasTargetURL = sal_True;
2001-06-25 07:51:54 +00:00
aValue <<= rContext.aArg.SourceURL;
2001-02-02 07:18:49 +00:00
}
}
if ( !aValue.hasValue() )
{
try
{
aValue = xRow1->getObject(
m + 1, uno::Reference< container::XNameAccess >() );
}
catch ( sdbc::SQLException const & )
{
// Argh! But try to bring things to an end. Perhaps the
// mad property is not really important...
}
}
if ( aValue.hasValue() )
{
rCurrValue.Name = rCurrProp.Name;
rCurrValue.Handle = rCurrProp.Handle;
rCurrValue.Value = aValue;
// rCurrValue.State =
nWritePos++;
}
}
// Title needed, but not set yet?
2001-06-25 07:51:54 +00:00
if ( !bHasTitle && ( rContext.aArg.NewTitle.getLength() > 0 ) )
2001-02-02 07:18:49 +00:00
{
aPropValues[ nWritePos ].Name
= rtl::OUString::createFromAscii( "Title" );
aPropValues[ nWritePos ].Handle = -1;
2001-06-25 07:51:54 +00:00
aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle;
2001-02-02 07:18:49 +00:00
nWritePos++;
}
// TargetURL needed, but not set yet?
2001-06-25 07:51:54 +00:00
if ( !bHasTargetURL && ( rContext.aArg.Operation
== star::ucb::TransferCommandOperation_LINK ) )
2001-02-02 07:18:49 +00:00
{
aPropValues[ nWritePos ].Name
= rtl::OUString::createFromAscii( "TargetURL" );
aPropValues[ nWritePos ].Handle = -1;
2001-06-25 07:51:54 +00:00
aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL;
2001-02-02 07:18:49 +00:00
nWritePos++;
}
aPropValues.realloc( nWritePos );
// Set properties at new object.
2001-06-25 07:51:54 +00:00
star::ucb::Command aSetPropsCommand(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "setPropertyValues" ),
-1,
uno::makeAny( aPropValues ) );
2001-06-25 07:51:54 +00:00
xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv );
2001-02-02 07:18:49 +00:00
// @@@ What to do with source props that are not supported by the
// new object? addProperty ???
}
//=========================================================================
static uno::Reference< io::XInputStream > getInputStream(
2001-06-25 07:51:54 +00:00
const TransferCommandContext & rContext,
const uno::Reference< star::ucb::XCommandProcessor > & xCommandProcessorS )
throw( uno::Exception )
2001-02-02 07:18:49 +00:00
{
uno::Reference< io::XInputStream > xInputStream;
//////////////////////////////////////////////////////////////////////
//
// (1) Try to get data as XInputStream via XActiveDataSink.
//
//////////////////////////////////////////////////////////////////////
try
{
uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink;
2001-06-25 07:51:54 +00:00
star::ucb::OpenCommandArgument2 aArg;
aArg.Mode = star::ucb::OpenMode::DOCUMENT;
2001-02-02 07:18:49 +00:00
aArg.Priority = 0; // unused
aArg.Sink = xSink;
aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused
2001-06-25 07:51:54 +00:00
star::ucb::Command aOpenCommand(
rtl::OUString::createFromAscii( "open" ),
-1,
uno::makeAny( aArg ) );
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
2001-02-02 07:18:49 +00:00
xInputStream = xSink->getInputStream();
}
catch ( uno::Exception const & )
{
}
if ( !xInputStream.is() )
{
//////////////////////////////////////////////////////////////////
//
// (2) Try to get data via XOutputStream.
//
//////////////////////////////////////////////////////////////////
try
{
uno::Reference< io::XOutputStream > xOutputStream(
2001-06-25 07:51:54 +00:00
rContext.xSMgr->createInstance(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "com.sun.star.io.Pipe" ) ),
uno::UNO_QUERY );
if ( xOutputStream.is() )
{
2001-06-25 07:51:54 +00:00
star::ucb::OpenCommandArgument2 aArg;
aArg.Mode = star::ucb::OpenMode::DOCUMENT;
2001-02-02 07:18:49 +00:00
aArg.Priority = 0; // unused
aArg.Sink = xOutputStream;
aArg.Properties = uno::Sequence< beans::Property >( 0 );
2001-06-25 07:51:54 +00:00
star::ucb::Command aOpenCommand(
rtl::OUString::createFromAscii( "open" ),
-1,
uno::makeAny( aArg ) );
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
2001-02-02 07:18:49 +00:00
xInputStream = uno::Reference< io::XInputStream >(
xOutputStream, uno::UNO_QUERY );
}
}
catch ( uno::Exception const & )
{
}
}
return xInputStream;
}
//=========================================================================
static uno::Reference< sdbc::XResultSet > getResultSet(
2001-06-25 07:51:54 +00:00
const TransferCommandContext & rContext,
const uno::Reference< star::ucb::XCommandProcessor > & xCommandProcessorS )
throw( uno::Exception )
2001-02-02 07:18:49 +00:00
{
uno::Reference< sdbc::XResultSet > xResultSet;
uno::Sequence< beans::Property > aProps( 3 );
aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" );
aProps[ 0 ].Handle = -1; /* unknown */
aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" );
aProps[ 1 ].Handle = -1; /* unknown */
aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" );
aProps[ 2 ].Handle = -1; /* unknown */
2001-06-25 07:51:54 +00:00
star::ucb::OpenCommandArgument2 aArg;
aArg.Mode = star::ucb::OpenMode::ALL;
2001-02-02 07:18:49 +00:00
aArg.Priority = 0; // unused
aArg.Sink = 0;
aArg.Properties = aProps;
2001-06-25 07:51:54 +00:00
star::ucb::Command aOpenCommand( rtl::OUString::createFromAscii( "open" ),
-1,
uno::makeAny( aArg ) );
2001-02-02 07:18:49 +00:00
try
{
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XDynamicResultSet > xSet;
xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet;
2001-02-02 07:18:49 +00:00
if ( xSet.is() )
xResultSet = xSet->getStaticResultSet();
}
catch ( uno::Exception const & )
{
}
return xResultSet;
}
//=========================================================================
2001-06-25 07:51:54 +00:00
static void globalTransfer(
const TransferCommandContext & rContext,
const uno::Reference< star::ucb::XContent > & xSource,
const uno::Reference< star::ucb::XContent > & xTarget,
const uno::Reference< sdbc::XRow > & xSourceProps )
2001-02-02 07:18:49 +00:00
throw( uno::Exception )
{
// IsFolder: property is required.
sal_Bool bSourceIsFolder = xSourceProps->getBoolean( 1 );
if ( !bSourceIsFolder && xSourceProps->wasNull() )
2001-06-25 07:51:54 +00:00
{
ucbhelper::cancelCommandExecution(
uno::makeAny( beans::UnknownPropertyException(
rtl::OUString::createFromAscii(
"Unable to get property 'IsFolder' "
"from source object!" ),
rContext.xProcessor ) ),
rContext.xEnv );
// Unreachable
}
2001-02-02 07:18:49 +00:00
// IsDocument: property is required.
sal_Bool bSourceIsDocument = xSourceProps->getBoolean( 2 );
if ( !bSourceIsDocument && xSourceProps->wasNull() )
2001-06-25 07:51:54 +00:00
{
ucbhelper::cancelCommandExecution(
uno::makeAny( beans::UnknownPropertyException(
rtl::OUString::createFromAscii(
"Unable to get property 'IsDocument' "
"from source object!" ),
rContext.xProcessor ) ),
rContext.xEnv );
// Unreachable
}
2001-02-02 07:18:49 +00:00
// TargetURL: property is optional.
sal_Bool bSourceIsLink = ( xSourceProps->getString( 3 ).getLength() > 0 );
//////////////////////////////////////////////////////////////////////
//
// (1) Try to find a matching target type for the source object and
// create a new, empty object of that type.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContent > xNew = createNew( rContext,
xTarget,
bSourceIsFolder,
bSourceIsDocument,
bSourceIsLink );
2001-02-02 07:18:49 +00:00
if ( !xNew.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Folder")),
-1,
uno::makeAny(rContext.aArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_CREATE,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"No matching content type at target!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (2) Transfer property values from source to new object.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandProcessor > xCommandProcessorN(
xNew, uno::UNO_QUERY );
2001-02-02 07:18:49 +00:00
if ( !xCommandProcessorN.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(
xNew->getIdentifier()->
getContentIdentifier()),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_WRITE,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"New content is not a XCommandProcessor!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
// Obtain all properties from source.
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandProcessor > xCommandProcessorS(
xSource, uno::UNO_QUERY );
2001-02-02 07:18:49 +00:00
if ( !xCommandProcessorS.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rContext.aArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"Source content is not a XCommandProcessor!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
transferProperties( rContext, xCommandProcessorS, xCommandProcessorN );
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (3) Try to obtain a data stream from source.
//
//////////////////////////////////////////////////////////////////////
uno::Reference< io::XInputStream > xInputStream;
2001-06-25 07:51:54 +00:00
if ( bSourceIsDocument && ( rContext.aArg.Operation
!= star::ucb::TransferCommandOperation_LINK ) )
xInputStream = getInputStream( rContext, xCommandProcessorS );
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (4) Try to obtain a resultset (children) from source.
//
//////////////////////////////////////////////////////////////////////
uno::Reference< sdbc::XResultSet > xResultSet;
2001-06-25 07:51:54 +00:00
if ( bSourceIsFolder && ( rContext.aArg.Operation
!= star::ucb::TransferCommandOperation_LINK ) )
xResultSet = getResultSet( rContext, xCommandProcessorS );
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (5) Insert (store) new content.
//
//////////////////////////////////////////////////////////////////////
try
{
2001-06-25 07:51:54 +00:00
star::ucb::InsertCommandArgument aArg;
2001-04-20 14:40:03 +00:00
aArg.Data = xInputStream;
2001-06-25 07:51:54 +00:00
switch ( rContext.aArg.NameClash )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::OVERWRITE:
2001-04-20 14:40:03 +00:00
aArg.ReplaceExisting = sal_True;
break;
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::ERROR:
case star::ucb::NameClash::RENAME:
case star::ucb::NameClash::KEEP: // deprecated
case star::ucb::NameClash::ASK:
2001-04-20 14:40:03 +00:00
aArg.ReplaceExisting = sal_False;
break;
default:
aArg.ReplaceExisting = sal_False;
2001-06-25 07:51:54 +00:00
OSL_ENSURE( sal_False, "Unknown nameclash directive!" );
2001-04-20 14:40:03 +00:00
break;
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
star::ucb::Command aInsertCommand(
rtl::OUString::createFromAscii( "insert" ),
2001-02-02 07:18:49 +00:00
-1,
uno::makeAny( aArg ) );
2001-06-25 07:51:54 +00:00
xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
2001-02-02 07:18:49 +00:00
}
2001-06-25 07:51:54 +00:00
catch ( star::ucb::NameClashException const & )
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
// The 'insert' command throws a NameClashException if the parameter
// ReplaceExisting of the command's argument was set to false and
// there exists a resource with a clashing name in the target folder
// of the operation.
// 'insert' command has no direct support for name clashes other
// than ERROR ( ReplaceExisting == false ) and OVERWRITE
// ( ReplaceExisting == true ). So we have to implement the
// other name clash handling directives on top of the content.
// @@@ 'insert' command should be extended that it accepts a
// name clash handling directive, exactly like 'transfer' command.
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
switch ( rContext.aArg.NameClash )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::OVERWRITE:
{
ucbhelper::cancelCommandExecution(
uno::makeAny(
star::ucb::UnsupportedNameClashException(
rtl::OUString::createFromAscii(
"BUG: insert + replace == true MUST NOT "
"throw NameClashException." ),
rContext.xProcessor,
rContext.aArg.NameClash ) ),
rContext.xEnv );
// Unreachable
}
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::ERROR:
throw;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::RENAME:
{
// "invent" a new valid title.
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
sal_Int32 nTry = 0;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
// Obtain old title.
uno::Sequence< beans::Property > aProps( 1 );
aProps[ 0 ].Name = rtl::OUString::createFromAscii( "Title" );
aProps[ 0 ].Handle = -1;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
star::ucb::Command aGetPropsCommand(
rtl::OUString::createFromAscii( "getPropertyValues" ),
-1,
uno::makeAny( aProps ) );
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
uno::Reference< sdbc::XRow > xRow;
xCommandProcessorN->execute(
aGetPropsCommand, 0, rContext.xEnv ) >>= xRow;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
if ( !xRow.is() )
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("Uri")),
-1,
uno::makeAny(
xNew->getIdentifier()->
getContentIdentifier()),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
rContext.xEnv,
rtl::OUString::createFromAscii(
"Unable to get properties from new object!" ),
rContext.xProcessor );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
rtl::OUString aOldTitle = xRow->getString( 1 );
if ( !aOldTitle.getLength() )
{
ucbhelper::cancelCommandExecution(
uno::makeAny( beans::UnknownPropertyException(
rtl::OUString::createFromAscii(
"Unable to get property 'Title' "
"from new object!" ),
rContext.xProcessor ) ),
rContext.xEnv );
// Unreachable
}
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
// Some pseudo-intelligence for not destroying file extensions.
rtl::OUString aOldTitlePre;
rtl::OUString aOldTitlePost;
sal_Int32 nPos = aOldTitle.lastIndexOf( '.' );
if ( nPos != -1 )
{
aOldTitlePre = aOldTitle.copy( 0, nPos );
aOldTitlePost = aOldTitle.copy( nPos );
}
else
aOldTitlePre = aOldTitle;
if ( nPos > 0 )
aOldTitlePre += rtl::OUString::createFromAscii( "_" );
sal_Bool bContinue = sal_True;
do
{
nTry++;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
rtl::OUString aNewTitle = aOldTitlePre;
aNewTitle += rtl::OUString::valueOf( nTry );
aNewTitle += aOldTitlePost;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
uno::Sequence< beans::PropertyValue > aValues( 1 );
aValues[ 0 ].Name
= rtl::OUString::createFromAscii( "Title" );
aValues[ 0 ].Handle = -1;
aValues[ 0 ].Value <<= aNewTitle;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
star::ucb::Command aSetPropsCommand(
2001-04-20 14:40:03 +00:00
rtl::OUString::createFromAscii( "setPropertyValues" ),
-1,
uno::makeAny( aValues ) );
2001-06-25 07:51:54 +00:00
// Set new title
xCommandProcessorN->execute(
aSetPropsCommand, 0, rContext.xEnv );
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
// Retry inserting the content.
try
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
// Previous try may have read from stream. Seek to
// begin (if optional interface XSeekable is supported)
// or get a new stream.
if ( xInputStream.is() )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
uno::Reference< io::XSeekable > xSeekable(
xInputStream, uno::UNO_QUERY );
if ( xSeekable.is() )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
try
{
xSeekable->seek( 0 );
}
catch ( lang::IllegalArgumentException const & )
{
xInputStream = 0;
}
catch ( io::IOException const & )
{
xInputStream = 0;
}
2001-04-20 14:40:03 +00:00
}
2001-06-25 07:51:54 +00:00
else
2001-04-20 14:40:03 +00:00
xInputStream = 0;
2001-06-25 07:51:54 +00:00
if ( !xInputStream.is() )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
xInputStream = getInputStream(
rContext, xCommandProcessorS );
if ( !xInputStream.is() )
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(
xNew->
getIdentifier()->
getContentIdentifier()),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
2001-06-25 07:51:54 +00:00
rContext.xEnv,
rtl::OUString::createFromAscii(
"Got no data stream from source!" ),
rContext.xProcessor );
// Unreachable
}
2001-04-20 14:40:03 +00:00
}
}
2001-06-25 07:51:54 +00:00
star::ucb::InsertCommandArgument aArg;
aArg.Data = xInputStream;
aArg.ReplaceExisting = sal_False;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
star::ucb::Command aInsertCommand(
rtl::OUString::createFromAscii( "insert" ),
-1,
uno::makeAny( aArg ) );
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
xCommandProcessorN->execute(
aInsertCommand, 0, rContext.xEnv );
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
// Success!
bContinue = sal_False;
}
catch ( uno::Exception const & )
{
}
2001-04-20 14:40:03 +00:00
}
2001-06-25 07:51:54 +00:00
while ( bContinue && ( nTry < 50 ) );
if ( nTry == 50 )
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
ucbhelper::cancelCommandExecution(
uno::makeAny(
star::ucb::UnsupportedNameClashException(
rtl::OUString::createFromAscii(
"Unable to resolve name clash!" ),
rContext.xProcessor,
star::ucb::NameClash::RENAME ) ),
rContext.xEnv );
// Unreachable
2001-04-20 14:40:03 +00:00
}
}
2001-06-25 07:51:54 +00:00
break;
2001-04-20 14:40:03 +00:00
2001-06-25 07:51:54 +00:00
case star::ucb::NameClash::KEEP: // deprecated
case star::ucb::NameClash::ASK:
default:
2001-04-20 14:40:03 +00:00
{
2001-06-25 07:51:54 +00:00
ucbhelper::cancelCommandExecution(
uno::makeAny(
star::ucb::UnsupportedNameClashException(
rtl::OUString(),
rContext.xProcessor,
rContext.aArg.NameClash ) ),
rContext.xEnv );
// Unreachable
2001-04-20 14:40:03 +00:00
}
}
2001-02-02 07:18:49 +00:00
}
2001-04-20 14:40:03 +00:00
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (6) Process children of source.
//
//////////////////////////////////////////////////////////////////////
if ( xResultSet.is() )
{
try
{
// Iterate over children...
uno::Reference< sdbc::XRow > xChildRow(
xResultSet, uno::UNO_QUERY );
if ( !xChildRow.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rContext.aArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
2001-06-25 07:51:54 +00:00
rContext.xEnv,
rtl::OUString::createFromAscii(
"Unable to get properties from children of source!" ),
rContext.xProcessor );
// Unreachable
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContentAccess > xChildAccess(
xResultSet, uno::UNO_QUERY );
2001-02-02 07:18:49 +00:00
if ( !xChildAccess.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rContext.aArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
2001-06-25 07:51:54 +00:00
rContext.xEnv,
rtl::OUString::createFromAscii(
"Unable to get children of source!" ),
rContext.xProcessor );
// Unreachable
}
2001-02-02 07:18:49 +00:00
if ( xResultSet->first() )
{
do
{
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContent > xChild
2001-02-02 07:18:49 +00:00
= xChildAccess->queryContent();
if ( xChild.is() )
{
// Recursion!
2001-06-25 07:51:54 +00:00
star::ucb::GlobalTransferCommandArgument aTransArg(
rContext.aArg.Operation, // Operation
2001-02-02 07:18:49 +00:00
xChild->getIdentifier()
->getContentIdentifier(), // SourceURL
xNew->getIdentifier()
->getContentIdentifier(), // TargetURL
rtl::OUString(), // NewTitle;
2001-06-25 07:51:54 +00:00
rContext.aArg.NameClash ); // NameClash
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
ucb_commands::globalTransfer( rContext,
xChild,
xNew,
xChildRow );
2001-02-02 07:18:49 +00:00
}
}
while ( xResultSet->next() );
}
}
catch ( sdbc::SQLException const & )
{
}
}
}
} /* namescpace ucb_commands */
//=========================================================================
//
// UniversalContentBroker implementation ( XCommandProcessor commands ).
//
//=========================================================================
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandInfo >
UniversalContentBroker::getCommandInfo()
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
return uno::Reference< star::ucb::XCommandInfo >(
2001-02-02 07:18:49 +00:00
new ucb_commands::CommandProcessorInfo() );
}
//=========================================================================
void UniversalContentBroker::globalTransfer(
2001-06-25 07:51:54 +00:00
const star::ucb::GlobalTransferCommandArgument & rArg,
const uno::Reference< star::ucb::XCommandEnvironment > & xEnv )
2001-02-02 07:18:49 +00:00
throw( uno::Exception )
{
// Remote optimization: Supply own task environment, which caches (remote)
// interfaces (progress handler, interaction handler, ...) locally.
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandEnvironment > xLocalEnv(
new ::ucb::CommandEnvironmentProxy( xEnv ) );
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (1) Try to transfer the content using 'transfer' command.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContent > xTarget;
uno::Reference< star::ucb::XContentIdentifier > xId
2001-02-02 07:18:49 +00:00
= createContentIdentifier( rArg.TargetURL );
2001-06-25 07:51:54 +00:00
if ( xId.is() )
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
try
{
xTarget = queryContent( xId );
}
catch ( star::ucb::IllegalIdentifierException const & )
{
}
2001-02-02 07:18:49 +00:00
}
if ( !xTarget.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
xEnv,
rtl::OUString::createFromAscii(
"Can't instanciate target object!" ),
this );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
if ( ( rArg.Operation == star::ucb::TransferCommandOperation_COPY ) ||
( rArg.Operation == star::ucb::TransferCommandOperation_MOVE ) )
2001-02-02 07:18:49 +00:00
{
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandProcessor > xCommandProcessor(
xTarget, uno::UNO_QUERY );
2001-02-02 07:18:49 +00:00
if ( !xCommandProcessor.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rArg.TargetURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
xEnv,
rtl::OUString::createFromAscii(
"Target content is not a XCommandProcessor!" ),
this );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
try
{
2001-06-25 07:51:54 +00:00
star::ucb::TransferInfo aTransferArg(
( rArg.Operation
== star::ucb::TransferCommandOperation_MOVE ), // MoveData
2001-02-02 07:18:49 +00:00
rArg.SourceURL, // SourceURL
rArg.NewTitle, // NewTitle
rArg.NameClash ); // NameClash
2001-06-25 07:51:54 +00:00
star::ucb::Command aCommand(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "transfer" ), // Name
-1, // Handle
uno::makeAny( aTransferArg ) ); // Argument
xCommandProcessor->execute( aCommand, 0, xLocalEnv );
2001-02-02 07:18:49 +00:00
// Command succeeded. We're done.
return;
}
2001-06-25 07:51:54 +00:00
catch ( star::ucb::InteractiveBadTransferURLException const & )
2001-02-02 07:18:49 +00:00
{
// Source URL is not supported by target. Try to transfer
// the content "manually".
}
catch( star::ucb::UnsupportedCommandException const & )
{
// 'transfer'-command is not supported by commandprocessor.
// Try to transfer manually.
}
2001-02-02 07:18:49 +00:00
/*
catch ( uno::Exception const & )
{
}
*/
}
//////////////////////////////////////////////////////////////////////
//
// (2) Try to transfer the content "manually".
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContent > xSource;
2001-02-02 07:18:49 +00:00
try
{
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XContentIdentifier > xId
2001-02-02 07:18:49 +00:00
= createContentIdentifier( rArg.SourceURL );
if ( xId.is() )
xSource = queryContent( xId );
}
2001-06-25 07:51:54 +00:00
catch ( star::ucb::IllegalIdentifierException const & )
2001-02-02 07:18:49 +00:00
{
}
if ( !xSource.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
xEnv,
rtl::OUString::createFromAscii(
"Can't instanciate source object!" ),
this );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
2001-06-25 07:51:54 +00:00
uno::Reference< star::ucb::XCommandProcessor > xCommandProcessor(
2001-02-02 07:18:49 +00:00
xSource, uno::UNO_QUERY );
if ( !xCommandProcessor.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
xEnv,
rtl::OUString::createFromAscii(
"Source content is not a XCommandProcessor!" ),
this );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
// Obtain interesting property values from source...
uno::Sequence< beans::Property > aProps( 3 );
aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" );
aProps[ 0 ].Handle = -1; /* unknown */
aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" );
aProps[ 1 ].Handle = -1; /* unknown */
aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" );
aProps[ 2 ].Handle = -1; /* unknown */
2001-06-25 07:51:54 +00:00
star::ucb::Command aGetPropsCommand(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "getPropertyValues" ),
-1,
uno::makeAny( aProps ) );
uno::Reference< sdbc::XRow > xRow;
xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow;
2001-02-02 07:18:49 +00:00
if ( !xRow.is() )
2001-06-25 07:51:54 +00:00
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Uri")),
-1,
uno::makeAny(rArg.SourceURL),
beans::PropertyState_DIRECT_VALUE));
ucbhelper::cancelCommandExecution(
star::ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >(&aProps, 1),
xEnv,
rtl::OUString::createFromAscii(
"Unable to get properties from source object!" ),
this );
2001-06-25 07:51:54 +00:00
// Unreachable
}
2001-02-02 07:18:49 +00:00
// Do it!
ucb_commands::globalTransfer(
2001-06-25 07:51:54 +00:00
ucb_commands::TransferCommandContext( m_xSMgr, this, xLocalEnv, rArg ),
xSource, xTarget, xRow );
2001-02-02 07:18:49 +00:00
//////////////////////////////////////////////////////////////////////
//
// (3) Delete source, if operation is MOVE.
//
//////////////////////////////////////////////////////////////////////
2001-06-25 07:51:54 +00:00
if ( rArg.Operation == star::ucb::TransferCommandOperation_MOVE )
2001-02-02 07:18:49 +00:00
{
try
{
2001-06-25 07:51:54 +00:00
star::ucb::Command aCommand(
2001-02-02 07:18:49 +00:00
rtl::OUString::createFromAscii( "delete" ), // Name
-1, // Handle
uno::makeAny( sal_Bool( sal_True ) ) ); // Argument
xCommandProcessor->execute( aCommand, 0, xLocalEnv );
2001-02-02 07:18:49 +00:00
}
catch ( uno::Exception const & )
{
OSL_ENSURE( sal_False, "Cannot delete source object!" );
throw;
}
}
}