blob: da511f03e58e5662e2b9974a4f6cd2d4630dc240 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"
#include <rtl/uri.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/file.hxx>
#include "osl/diagnose.h"
#include <com/sun/star/ucb/OpenMode.hpp>
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#include <com/sun/star/ucb/XProgressHandler.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
#include <com/sun/star/beans/PropertySetInfoChange.hpp>
#include <com/sun/star/ucb/ContentAction.hpp>
#include <com/sun/star/ucb/NameClash.hpp>
#include "filglob.hxx"
#include "filid.hxx"
#include "filrow.hxx"
#include "bc.hxx"
#include "prov.hxx"
#ifndef _FILERROR_HXX_
#include "filerror.hxx"
#endif
#include "filinsreq.hxx"
using namespace fileaccess;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;
// PropertyListeners
typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
PropertyListeners_impl;
class fileaccess::PropertyListeners
: public PropertyListeners_impl
{
public:
PropertyListeners( ::osl::Mutex& aMutex )
: PropertyListeners_impl( aMutex )
{
}
};
/****************************************************************************************/
/* */
/* BaseContent */
/* */
/****************************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Private Constructor for just inserted Contents
BaseContent::BaseContent( shell* pMyShell,
const rtl::OUString& parentName,
sal_Bool bFolder )
: m_pMyShell( pMyShell ),
m_xContentIdentifier( 0 ),
m_aUncPath( parentName ),
m_bFolder( bFolder ),
m_nState( JustInserted ),
m_pDisposeEventListeners( 0 ),
m_pContentEventListeners( 0 ),
m_pPropertySetInfoChangeListeners( 0 ),
m_pPropertyListener( 0 )
{
m_pMyShell->m_pProvider->acquire();
// No registering, since we have no name
}
////////////////////////////////////////////////////////////////////////////////
// Constructor for full featured Contents
BaseContent::BaseContent( shell* pMyShell,
const Reference< XContentIdentifier >& xContentIdentifier,
const rtl::OUString& aUncPath )
: m_pMyShell( pMyShell ),
m_xContentIdentifier( xContentIdentifier ),
m_aUncPath( aUncPath ),
m_bFolder( false ),
m_nState( FullFeatured ),
m_pDisposeEventListeners( 0 ),
m_pContentEventListeners( 0 ),
m_pPropertySetInfoChangeListeners( 0 ),
m_pPropertyListener( 0 )
{
m_pMyShell->m_pProvider->acquire();
m_pMyShell->registerNotifier( m_aUncPath,this );
m_pMyShell->insertDefaultProperties( m_aUncPath );
}
BaseContent::~BaseContent( )
{
if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
{
m_pMyShell->deregisterNotifier( m_aUncPath,this );
}
m_pMyShell->m_pProvider->release();
delete m_pDisposeEventListeners;
delete m_pContentEventListeners;
delete m_pPropertyListener;
delete m_pPropertySetInfoChangeListeners;
}
//////////////////////////////////////////////////////////////////////////
// XInterface
//////////////////////////////////////////////////////////////////////////
void SAL_CALL
BaseContent::acquire( void )
throw()
{
OWeakObject::acquire();
}
void SAL_CALL
BaseContent::release( void )
throw()
{
OWeakObject::release();
}
Any SAL_CALL
BaseContent::queryInterface( const Type& rType )
throw( RuntimeException )
{
Any aRet = cppu::queryInterface( rType,
SAL_STATIC_CAST( lang::XComponent*, this ),
SAL_STATIC_CAST( lang::XTypeProvider*, this ),
SAL_STATIC_CAST( lang::XServiceInfo*, this ),
SAL_STATIC_CAST( XCommandProcessor*, this ),
SAL_STATIC_CAST( container::XChild*, this ),
SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ),
SAL_STATIC_CAST( beans::XPropertyContainer*, this ),
SAL_STATIC_CAST( XContentCreator*,this ),
SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ),
SAL_STATIC_CAST( XContent*,this) );
return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}
//////////////////////////////////////////////////////////////////////////////////////////
// XComponent
////////////////////////////////////////////////////////////////////////////////////////
void SAL_CALL
BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if ( ! m_pDisposeEventListeners )
m_pDisposeEventListeners =
new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
m_pDisposeEventListeners->addInterface( Listener );
}
void SAL_CALL
BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if ( m_pDisposeEventListeners )
m_pDisposeEventListeners->removeInterface( Listener );
}
void SAL_CALL
BaseContent::dispose()
throw( RuntimeException )
{
lang::EventObject aEvt;
cppu::OInterfaceContainerHelper* pDisposeEventListeners;
cppu::OInterfaceContainerHelper* pContentEventListeners;
cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
PropertyListeners* pPropertyListener;
{
osl::MutexGuard aGuard( m_aMutex );
aEvt.Source = static_cast< XContent* >( this );
pDisposeEventListeners =
m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
pContentEventListeners =
m_pContentEventListeners, m_pContentEventListeners = 0;
pPropertySetInfoChangeListeners =
m_pPropertySetInfoChangeListeners,
m_pPropertySetInfoChangeListeners = 0;
pPropertyListener =
m_pPropertyListener, m_pPropertyListener = 0;
}
if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
pDisposeEventListeners->disposeAndClear( aEvt );
if ( pContentEventListeners && pContentEventListeners->getLength() )
pContentEventListeners->disposeAndClear( aEvt );
if( pPropertyListener )
pPropertyListener->disposeAndClear( aEvt );
if( pPropertySetInfoChangeListeners )
pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
delete pDisposeEventListeners;
delete pContentEventListeners;
delete pPropertyListener;
delete pPropertySetInfoChangeListeners;
}
//////////////////////////////////////////////////////////////////////////////////////////
// XServiceInfo
//////////////////////////////////////////////////////////////////////////////////////////
rtl::OUString SAL_CALL
BaseContent::getImplementationName()
throw( RuntimeException)
{
return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" );
}
sal_Bool SAL_CALL
BaseContent::supportsService( const rtl::OUString& ServiceName )
throw( RuntimeException)
{
if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 )
return true;
else
return false;
}
Sequence< rtl::OUString > SAL_CALL
BaseContent::getSupportedServiceNames()
throw( RuntimeException )
{
Sequence< rtl::OUString > ret( 1 );
ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" );
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////
// XTypeProvider
//////////////////////////////////////////////////////////////////////////////////////////
XTYPEPROVIDER_IMPL_10( BaseContent,
lang::XComponent,
lang::XTypeProvider,
lang::XServiceInfo,
XCommandProcessor,
XContentCreator,
XContent,
container::XChild,
beans::XPropertiesChangeNotifier,
beans::XPropertyContainer,
beans::XPropertySetInfoChangeNotifier )
//////////////////////////////////////////////////////////////////////////////////////////
// XCommandProcessor
//////////////////////////////////////////////////////////////////////////////////////////
sal_Int32 SAL_CALL
BaseContent::createCommandIdentifier( void )
throw( RuntimeException )
{
return m_pMyShell->getCommandId();
}
void SAL_CALL
BaseContent::abort( sal_Int32 CommandId )
throw( RuntimeException )
{
m_pMyShell->abort( CommandId );
}
Any SAL_CALL
BaseContent::execute( const Command& aCommand,
sal_Int32 CommandId,
const Reference< XCommandEnvironment >& Environment )
throw( Exception,
CommandAbortedException,
RuntimeException )
{
if( ! CommandId )
// A Command with commandid zero cannot be aborted
CommandId = createCommandIdentifier();
m_pMyShell->startTask( CommandId,
Environment );
Any aAny;
if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) ) // No exceptions
{
aAny <<= getPropertySetInfo( CommandId );
}
else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) ) // no exceptions
{
aAny <<= getCommandInfo();
}
else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) )
{
Sequence< beans::PropertyValue > sPropertyValues;
if( ! ( aCommand.Argument >>= sPropertyValues ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
else
aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
}
else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) )
{
Sequence< beans::Property > ListOfRequestedProperties;
if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
else
aAny <<= getPropertyValues( CommandId,
ListOfRequestedProperties );
}
else if( ! aCommand.Name.compareToAscii( "open" ) )
{
OpenCommandArgument2 aOpenArgument;
if( ! ( aCommand.Argument >>= aOpenArgument ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_OPEN_ARGUMENT );
else
{
Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
if( result.is() )
aAny <<= result;
}
}
else if( ! aCommand.Name.compareToAscii( "delete" ) )
{
if( ! aCommand.Argument.has< sal_Bool >() )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_DELETE_ARGUMENT );
else
deleteContent( CommandId );
}
else if( ! aCommand.Name.compareToAscii( "transfer" ) )
{
TransferInfo aTransferInfo;
if( ! ( aCommand.Argument >>= aTransferInfo ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
else
transfer( CommandId, aTransferInfo );
}
else if( ! aCommand.Name.compareToAscii( "insert" ) )
{
InsertCommandArgument aInsertArgument;
if( ! ( aCommand.Argument >>= aInsertArgument ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_INSERT_ARGUMENT );
else
insert( CommandId,aInsertArgument );
}
else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) )
{
Sequence< beans::Property > seq(1);
seq[0] = beans::Property(
rtl::OUString::createFromAscii("CasePreservingURL"),
-1,
getCppuType( static_cast< sal_Bool* >(0) ),
0 );
Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
rtl::OUString CasePreservingURL = xRow->getString(1);
if(!xRow->wasNull())
aAny <<= CasePreservingURL;
}
else if( ! aCommand.Name.compareToAscii( "createNewContent" ) )
{
ucb::ContentInfo aArg;
if ( !( aCommand.Argument >>= aArg ) )
m_pMyShell->installError( CommandId,
TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
else
aAny <<= createNewContent( aArg );
}
else
m_pMyShell->installError( CommandId,
TASKHANDLER_UNSUPPORTED_COMMAND );
// This is the only function allowed to throw an exception
endTask( CommandId );
return aAny;
}
void SAL_CALL
BaseContent::addPropertiesChangeListener(
const Sequence< rtl::OUString >& PropertyNames,
const Reference< beans::XPropertiesChangeListener >& Listener )
throw( RuntimeException )
{
if( ! Listener.is() )
return;
osl::MutexGuard aGuard( m_aMutex );
if( ! m_pPropertyListener )
m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex );
if( PropertyNames.getLength() == 0 )
m_pPropertyListener->addInterface( rtl::OUString(),Listener );
else
{
Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
if( xProp->hasPropertyByName( PropertyNames[i] ) )
m_pPropertyListener->addInterface( PropertyNames[i],Listener );
}
}
void SAL_CALL
BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames,
const Reference< beans::XPropertiesChangeListener >& Listener )
throw( RuntimeException )
{
if( ! Listener.is() )
return;
osl::MutexGuard aGuard( m_aMutex );
if( ! m_pPropertyListener )
return;
for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
m_pPropertyListener->removeInterface( PropertyNames[i],Listener );
m_pPropertyListener->removeInterface( rtl::OUString(), Listener );
}
/////////////////////////////////////////////////////////////////////////////////////////
// XContent
/////////////////////////////////////////////////////////////////////////////////////////
Reference< ucb::XContentIdentifier > SAL_CALL
BaseContent::getIdentifier()
throw( RuntimeException )
{
return m_xContentIdentifier;
}
rtl::OUString SAL_CALL
BaseContent::getContentType()
throw( RuntimeException )
{
if( !( m_nState & Deleted ) )
{
if( m_nState & JustInserted )
{
if ( m_bFolder )
return m_pMyShell->FolderContentType;
else
return m_pMyShell->FileContentType;
}
else
{
try
{
// Who am I ?
Sequence< beans::Property > seq(1);
seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
-1,
getCppuType( static_cast< sal_Bool* >(0) ),
0 );
Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
sal_Bool IsDocument = xRow->getBoolean( 1 );
if ( !xRow->wasNull() )
{
if ( IsDocument )
return m_pMyShell->FileContentType;
else
return m_pMyShell->FolderContentType;
}
else
{
OSL_ENSURE( false,
"BaseContent::getContentType - Property value was null!" );
}
}
catch ( sdbc::SQLException const & )
{
OSL_ENSURE( false,
"BaseContent::getContentType - Caught SQLException!" );
}
}
}
return rtl::OUString();
}
void SAL_CALL
BaseContent::addContentEventListener(
const Reference< XContentEventListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if ( ! m_pContentEventListeners )
m_pContentEventListeners =
new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
m_pContentEventListeners->addInterface( Listener );
}
void SAL_CALL
BaseContent::removeContentEventListener(
const Reference< XContentEventListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if ( m_pContentEventListeners )
m_pContentEventListeners->removeInterface( Listener );
}
////////////////////////////////////////////////////////////////////////////////
// XPropertyContainer
////////////////////////////////////////////////////////////////////////////////
void SAL_CALL
BaseContent::addProperty(
const rtl::OUString& Name,
sal_Int16 Attributes,
const Any& DefaultValue )
throw( beans::PropertyExistException,
beans::IllegalTypeException,
lang::IllegalArgumentException,
RuntimeException)
{
if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() )
{
throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
}
m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
}
void SAL_CALL
BaseContent::removeProperty(
const rtl::OUString& Name )
throw( beans::UnknownPropertyException,
beans::NotRemoveableException,
RuntimeException)
{
if( m_nState & Deleted )
throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
m_pMyShell->deassociate( m_aUncPath, Name );
}
////////////////////////////////////////////////////////////////////////////////
// XContentCreator
////////////////////////////////////////////////////////////////////////////////
Sequence< ContentInfo > SAL_CALL
BaseContent::queryCreatableContentsInfo(
void )
throw( RuntimeException )
{
return m_pMyShell->queryCreatableContentsInfo();
}
Reference< XContent > SAL_CALL
BaseContent::createNewContent(
const ContentInfo& Info )
throw( RuntimeException )
{
// Check type.
if ( !Info.Type.getLength() )
return Reference< XContent >();
sal_Bool bFolder
= ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
if ( !bFolder )
{
if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
{
// Neither folder nor file to create!
return Reference< XContent >();
}
}
// Who am I ?
sal_Bool IsDocument = false;
try
{
Sequence< beans::Property > seq(1);
seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
-1,
getCppuType( static_cast< sal_Bool* >(0) ),
0 );
Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
IsDocument = xRow->getBoolean( 1 );
if ( xRow->wasNull() )
{
IsDocument = false;
// OSL_ENSURE( false,
// "BaseContent::createNewContent - Property value was null!" );
// return Reference< XContent >();
}
}
catch ( sdbc::SQLException const & )
{
OSL_ENSURE( false,
"BaseContent::createNewContent - Caught SQLException!" );
return Reference< XContent >();
}
rtl::OUString dstUncPath;
if( IsDocument )
{
// KSO: Why is a document a XContentCreator? This is quite unusual.
dstUncPath = getParentName( m_aUncPath );
}
else
dstUncPath = m_aUncPath;
BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
return Reference< XContent >( p );
}
////////////////////////////////////////////////////////////////////////////////
// XPropertySetInfoChangeNotifier
////////////////////////////////////////////////////////////////////////////////
void SAL_CALL
BaseContent::addPropertySetInfoChangeListener(
const Reference< beans::XPropertySetInfoChangeListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if( ! m_pPropertySetInfoChangeListeners )
m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
m_pPropertySetInfoChangeListeners->addInterface( Listener );
}
void SAL_CALL
BaseContent::removePropertySetInfoChangeListener(
const Reference< beans::XPropertySetInfoChangeListener >& Listener )
throw( RuntimeException )
{
osl::MutexGuard aGuard( m_aMutex );
if( m_pPropertySetInfoChangeListeners )
m_pPropertySetInfoChangeListeners->removeInterface( Listener );
}
////////////////////////////////////////////////////////////////////////////////
// XChild
////////////////////////////////////////////////////////////////////////////////
Reference< XInterface > SAL_CALL
BaseContent::getParent(
void )
throw( RuntimeException )
{
rtl::OUString ParentUnq = getParentName( m_aUncPath );
rtl::OUString ParentUrl;
sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
if( err )
return Reference< XInterface >( 0 );
FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
Reference< XContentIdentifier > Identifier( p );
try
{
Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
return Reference<XInterface>(content,UNO_QUERY);
}
catch( IllegalIdentifierException )
{
return Reference< XInterface >();
}
}
void SAL_CALL
BaseContent::setParent(
const Reference< XInterface >& )
throw( lang::NoSupportException,
RuntimeException)
{
throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
}
//////////////////////////////////////////////////////////////////////////////////////////
// Private Methods
//////////////////////////////////////////////////////////////////////////////////////////
Reference< XCommandInfo > SAL_CALL
BaseContent::getCommandInfo()
throw( RuntimeException )
{
if( m_nState & Deleted )
return Reference< XCommandInfo >();
return m_pMyShell->info_c();
}
Reference< beans::XPropertySetInfo > SAL_CALL
BaseContent::getPropertySetInfo(
sal_Int32 )
throw( RuntimeException )
{
if( m_nState & Deleted )
return Reference< beans::XPropertySetInfo >();
return m_pMyShell->info_p( m_aUncPath );
}
Reference< sdbc::XRow > SAL_CALL
BaseContent::getPropertyValues(
sal_Int32 nMyCommandIdentifier,
const Sequence< beans::Property >& PropertySet )
throw( RuntimeException )
{
sal_Int32 nProps = PropertySet.getLength();
if ( !nProps )
return Reference< sdbc::XRow >();
if( m_nState & Deleted )
{
Sequence< Any > aValues( nProps );
return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
}
if( m_nState & JustInserted )
{
Sequence< Any > aValues( nProps );
Any* pValues = aValues.getArray();
const beans::Property* pProps = PropertySet.getConstArray();
for ( sal_Int32 n = 0; n < nProps; ++n )
{
const beans::Property& rProp = pProps[ n ];
Any& rValue = pValues[ n ];
if( rProp.Name.compareToAscii( "ContentType" ) == 0 )
{
rValue <<= m_bFolder ? m_pMyShell->FolderContentType
: m_pMyShell->FileContentType;
}
else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 )
{
rValue <<= m_bFolder;
}
else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 )
{
rValue <<= sal_Bool( !m_bFolder );
}
}
return Reference< sdbc::XRow >(
new XRow_impl( m_pMyShell, aValues ) );
}
return m_pMyShell->getv( nMyCommandIdentifier,
m_aUncPath,
PropertySet );
}
Sequence< Any > SAL_CALL
BaseContent::setPropertyValues(
sal_Int32 nMyCommandIdentifier,
const Sequence< beans::PropertyValue >& Values )
throw()
{
if( m_nState & Deleted )
{ // To do
return Sequence< Any >( Values.getLength() );
}
const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" );
// Special handling for files which have to be inserted
if( m_nState & JustInserted )
{
for( sal_Int32 i = 0; i < Values.getLength(); ++i )
{
if( Values[i].Name == Title )
{
rtl::OUString NewTitle;
if( Values[i].Value >>= NewTitle )
{
if ( m_nState & NameForInsertionSet )
{
// User wants to set another Title before "insert".
// m_aUncPath contains previous own URI.
sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
bool bTrailingSlash = false;
if ( nLastSlash == m_aUncPath.getLength() - 1 )
{
bTrailingSlash = true;
nLastSlash
= m_aUncPath.lastIndexOf( '/', nLastSlash );
}
OSL_ENSURE( nLastSlash != -1,
"BaseContent::setPropertyValues: "
"Invalid URL!" );
rtl::OUStringBuffer aBuf(
m_aUncPath.copy( 0, nLastSlash + 1 ) );
if ( NewTitle.getLength() > 0 )
{
aBuf.append( NewTitle );
if ( bTrailingSlash )
aBuf.append( sal_Unicode( '/' ) );
}
else
{
m_nState &= ~NameForInsertionSet;
}
m_aUncPath = aBuf.makeStringAndClear();
}
else
{
if ( NewTitle.getLength() > 0 )
{
// Initial Title before "insert".
// m_aUncPath contains parent's URI.
if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
m_aUncPath += rtl::OUString::createFromAscii("/");
m_aUncPath += rtl::Uri::encode( NewTitle,
rtl_UriCharClassPchar,
rtl_UriEncodeIgnoreEscapes,
RTL_TEXTENCODING_UTF8 );
m_nState |= NameForInsertionSet;
}
}
}
}
}
return Sequence< Any >( Values.getLength() );
}
else
{
Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
Values );
// Special handling Title: Setting Title is equivalent to a renaming of the underlying file
for( sal_Int32 i = 0; i < Values.getLength(); ++i )
{
if( Values[i].Name != Title )
continue; // handled by setv
rtl::OUString NewTitle;
if( !( Values[i].Value >>= NewTitle ) )
{
ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
break;
}
else if( ! NewTitle.getLength() )
{
ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
break;
}
rtl::OUString aDstName = getParentName( m_aUncPath );
if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
aDstName += rtl::OUString::createFromAscii("/");
aDstName += rtl::Uri::encode( NewTitle,
rtl_UriCharClassPchar,
rtl_UriEncodeIgnoreEscapes,
RTL_TEXTENCODING_UTF8 );
m_pMyShell->move( nMyCommandIdentifier, // move notifies the childs also;
m_aUncPath,
aDstName,
NameClash::KEEP );
try
{
endTask( nMyCommandIdentifier );
}
catch( const Exception& e )
{
ret[i] <<= e;
}
// NameChanges come back trough a ContentEvent
break; // only handling Title
} // end for
return ret;
}
}
Reference< XDynamicResultSet > SAL_CALL
BaseContent::open(
sal_Int32 nMyCommandIdentifier,
const OpenCommandArgument2& aCommandArgument )
throw()
{
Reference< XDynamicResultSet > retValue( 0 );
if( ( m_nState & Deleted ) )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
}
else if( m_nState & JustInserted )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
}
else
{
if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
{
Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
if( outputStream.is() )
{
m_pMyShell->page( nMyCommandIdentifier,
m_aUncPath,
outputStream );
}
sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
if( activeDataSink.is() )
{
activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
m_aUncPath,
bLock ) );
}
Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
if( activeDataStreamer.is() )
{
activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
m_aUncPath,
bLock ) );
}
}
else if ( aCommandArgument.Mode == OpenMode::ALL ||
aCommandArgument.Mode == OpenMode::FOLDERS ||
aCommandArgument.Mode == OpenMode::DOCUMENTS )
{
retValue = m_pMyShell->ls( nMyCommandIdentifier,
m_aUncPath,
aCommandArgument.Mode,
aCommandArgument.Properties,
aCommandArgument.SortingInfo );
}
// else if( aCommandArgument.Mode ==
// OpenMode::DOCUMENT_SHARE_DENY_NONE ||
// aCommandArgument.Mode ==
// OpenMode::DOCUMENT_SHARE_DENY_WRITE )
// m_pMyShell->installError( nMyCommandIdentifier,
// TASKHANDLING_UNSUPPORTED_OPEN_MODE,
// aCommandArgument.Mode);
else
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_UNSUPPORTED_OPEN_MODE,
aCommandArgument.Mode);
}
return retValue;
}
void SAL_CALL
BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
throw()
{
if( m_nState & Deleted )
return;
if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
{
osl::MutexGuard aGuard( m_aMutex );
m_nState |= Deleted;
}
}
void SAL_CALL
BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
const TransferInfo& aTransferInfo )
throw()
{
if( m_nState & Deleted )
return;
if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_TRANSFER_INVALIDSCHEME );
return;
}
rtl::OUString srcUnc;
if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_TRANSFER_INVALIDURL );
return;
}
rtl::OUString srcUncPath = srcUnc;
// Determine the new title !
rtl::OUString NewTitle;
if( aTransferInfo.NewTitle.getLength() )
NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
rtl_UriCharClassPchar,
rtl_UriEncodeIgnoreEscapes,
RTL_TEXTENCODING_UTF8 );
else
NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
// Is destination a document or a folder ?
Sequence< beans::Property > seq(1);
seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
-1,
getCppuType( static_cast< sal_Bool* >(0) ),
0 );
Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
sal_Bool IsDocument = xRow->getBoolean( 1 );
if( xRow->wasNull() )
{ // Destination file type could not be determined
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_TRANSFER_DESTFILETYPE );
return;
}
rtl::OUString dstUncPath;
if( IsDocument )
{ // as sibling
sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
dstUncPath = m_aUncPath.copy(0,lastSlash );
}
else
// as child
dstUncPath = m_aUncPath;
dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle );
sal_Int32 NameClash = aTransferInfo.NameClash;
if( aTransferInfo.MoveData )
m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
else
m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
}
void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
const InsertCommandArgument& aInsertArgument )
throw()
{
if( m_nState & FullFeatured )
{
m_pMyShell->write( nMyCommandIdentifier,
m_aUncPath,
aInsertArgument.ReplaceExisting,
aInsertArgument.Data );
return;
}
if( ! ( m_nState & JustInserted ) )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
return;
}
// Inserts the content, which has the flag m_bIsFresh
if ( !m_nState | !NameForInsertionSet )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_NONAMESET_INSERT_COMMAND );
return;
}
// Inserting a document or a file?
sal_Bool bDocument = false;
Sequence< beans::Property > seq(1);
seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
-1,
getCppuType( static_cast< sal_Bool* >(0) ),
0 );
Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
bool contentTypeSet = true; // is set to false, if contentType not set
try
{
bDocument = xRow->getBoolean( 1 );
if( xRow->wasNull() )
contentTypeSet = false;
}
catch ( sdbc::SQLException const & )
{
OSL_ENSURE( false,
"BaseContent::insert - Caught SQLException!" );
contentTypeSet = false;
}
if( ! contentTypeSet )
{
m_pMyShell->installError( nMyCommandIdentifier,
TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
return;
}
sal_Bool success = false;
if( bDocument )
success = m_pMyShell->mkfil( nMyCommandIdentifier,
m_aUncPath,
aInsertArgument.ReplaceExisting,
aInsertArgument.Data );
else
{
while( ! success )
{
success = m_pMyShell->mkdir( nMyCommandIdentifier,
m_aUncPath,
aInsertArgument.ReplaceExisting );
if( success )
break;
XInteractionRequestImpl *aRequestImpl =
new XInteractionRequestImpl(
rtl::Uri::decode(
getTitle(m_aUncPath),
rtl_UriDecodeWithCharset,
RTL_TEXTENCODING_UTF8),
(cppu::OWeakObject*)this,
m_pMyShell,nMyCommandIdentifier);
uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
if( aRequestImpl->aborted() ||
!aRequestImpl->newName().getLength() )
// means aborting
break;
// determine new uncpath
m_pMyShell->clearError( nMyCommandIdentifier );
m_aUncPath = getParentName( m_aUncPath );
if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
m_aUncPath += rtl::OUString::createFromAscii("/");
m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
rtl_UriCharClassPchar,
rtl_UriEncodeIgnoreEscapes,
RTL_TEXTENCODING_UTF8 );
}
}
if ( ! success )
return;
FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
m_xContentIdentifier = Reference< XContentIdentifier >( p );
m_pMyShell->registerNotifier( m_aUncPath,this );
m_pMyShell->insertDefaultProperties( m_aUncPath );
osl::MutexGuard aGuard( m_aMutex );
m_nState = FullFeatured;
}
void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
{
// This is the only function allowed to throw an exception
m_pMyShell->endTask( CommandId,m_aUncPath,this );
}
ContentEventNotifier*
BaseContent::cDEL( void )
{
osl::MutexGuard aGuard( m_aMutex );
m_nState |= Deleted;
ContentEventNotifier* p;
if( m_pContentEventListeners )
p = new ContentEventNotifier( m_pMyShell,
this,
m_xContentIdentifier,
m_pContentEventListeners->getElements() );
else
p = 0;
return p;
}
ContentEventNotifier*
BaseContent::cEXC( const rtl::OUString aNewName )
{
osl::MutexGuard aGuard( m_aMutex );
Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
m_aUncPath = aNewName;
FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
m_xContentIdentifier = Reference< XContentIdentifier >( pp );
ContentEventNotifier* p = 0;
if( m_pContentEventListeners )
p = new ContentEventNotifier( m_pMyShell,
this,
m_xContentIdentifier,
xOldRef,
m_pContentEventListeners->getElements() );
return p;
}
ContentEventNotifier*
BaseContent::cCEL( void )
{
osl::MutexGuard aGuard( m_aMutex );
ContentEventNotifier* p = 0;
if( m_pContentEventListeners )
p = new ContentEventNotifier( m_pMyShell,
this,
m_xContentIdentifier,
m_pContentEventListeners->getElements() );
return p;
}
PropertySetInfoChangeNotifier*
BaseContent::cPSL( void )
{
osl::MutexGuard aGuard( m_aMutex );
PropertySetInfoChangeNotifier* p = 0;
if( m_pPropertySetInfoChangeListeners )
p = new PropertySetInfoChangeNotifier( m_pMyShell,
this,
m_xContentIdentifier,
m_pPropertySetInfoChangeListeners->getElements() );
return p;
}
PropertyChangeNotifier*
BaseContent::cPCL( void )
{
osl::MutexGuard aGuard( m_aMutex );
Sequence< rtl::OUString > seqNames;
if( m_pPropertyListener )
seqNames = m_pPropertyListener->getContainedTypes();
PropertyChangeNotifier* p = 0;
sal_Int32 length = seqNames.getLength();
if( length )
{
ListenerMap* listener = new ListenerMap();
for( sal_Int32 i = 0; i < length; ++i )
{
(*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
}
p = new PropertyChangeNotifier( m_pMyShell,
this,
m_xContentIdentifier,
listener );
}
return p;
}
rtl::OUString BaseContent::getKey( void )
{
return m_aUncPath;
}