3068 lines
107 KiB
C++
3068 lines
107 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org 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 version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include <stack>
|
|
#include "osl/diagnose.h"
|
|
#include <rtl/uri.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <osl/time.h>
|
|
#include <osl/file.hxx>
|
|
#include <com/sun/star/lang/IllegalAccessException.hpp>
|
|
#include <com/sun/star/beans/IllegalTypeException.hpp>
|
|
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
|
|
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
|
|
#include <com/sun/star/ucb/NameClash.hpp>
|
|
#include <com/sun/star/ucb/XContentIdentifier.hpp>
|
|
#include <com/sun/star/lang/XComponent.hpp>
|
|
#include <com/sun/star/ucb/XContentAccess.hpp>
|
|
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
|
#include <com/sun/star/io/XSeekable.hpp>
|
|
#include <com/sun/star/io/XTruncate.hpp>
|
|
#include <com/sun/star/ucb/OpenCommandArgument.hpp>
|
|
#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
|
|
#include <com/sun/star/ucb/TransferInfo.hpp>
|
|
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
|
|
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
|
|
#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
|
|
#include <rtl/string.hxx>
|
|
#include "filerror.hxx"
|
|
#include "filglob.hxx"
|
|
#include "filcmd.hxx"
|
|
#include "filinpstr.hxx"
|
|
#include "filstr.hxx"
|
|
#include "filrset.hxx"
|
|
#include "filrow.hxx"
|
|
#include "filprp.hxx"
|
|
#include "filid.hxx"
|
|
#include "shell.hxx"
|
|
#include "prov.hxx"
|
|
#include "bc.hxx"
|
|
|
|
|
|
using namespace fileaccess;
|
|
using namespace com::sun::star;
|
|
using namespace com::sun::star::ucb;
|
|
|
|
|
|
shell::UnqPathData::UnqPathData()
|
|
: properties( 0 ),
|
|
notifier( 0 ),
|
|
xS( 0 ),
|
|
xC( 0 ),
|
|
xA( 0 )
|
|
{
|
|
// empty
|
|
}
|
|
|
|
|
|
shell::UnqPathData::UnqPathData( const UnqPathData& a )
|
|
: properties( a.properties ),
|
|
notifier( a.notifier ),
|
|
xS( a.xS ),
|
|
xC( a.xC ),
|
|
xA( a.xA )
|
|
{
|
|
}
|
|
|
|
|
|
shell::UnqPathData& shell::UnqPathData::operator=( UnqPathData& a )
|
|
{
|
|
properties = a.properties;
|
|
notifier = a.notifier;
|
|
xS = a.xS;
|
|
xC = a.xC;
|
|
xA = a.xA;
|
|
a.properties = 0;
|
|
a.notifier = 0;
|
|
a.xS = 0;
|
|
a.xC = 0;
|
|
a.xA = 0;
|
|
return *this;
|
|
}
|
|
|
|
shell::UnqPathData::~UnqPathData()
|
|
{
|
|
if( properties )
|
|
delete properties;
|
|
if( notifier )
|
|
delete notifier;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
shell::MyProperty::MyProperty( const rtl::OUString& __PropertyName )
|
|
: PropertyName( __PropertyName )
|
|
{
|
|
// empty
|
|
}
|
|
|
|
|
|
shell::MyProperty::MyProperty( const sal_Bool& __isNative,
|
|
const rtl::OUString& __PropertyName,
|
|
const sal_Int32& __Handle,
|
|
const com::sun::star::uno::Type& __Typ,
|
|
const com::sun::star::uno::Any& __Value,
|
|
const com::sun::star::beans::PropertyState& __State,
|
|
const sal_Int16& __Attributes )
|
|
: PropertyName( __PropertyName ),
|
|
Handle( __Handle ),
|
|
isNative( __isNative ),
|
|
Typ( __Typ ),
|
|
Value( __Value ),
|
|
State( __State ),
|
|
Attributes( __Attributes )
|
|
{
|
|
// empty
|
|
}
|
|
|
|
shell::MyProperty::~MyProperty()
|
|
{
|
|
// empty for now
|
|
}
|
|
|
|
|
|
#include "filinl.hxx"
|
|
|
|
|
|
shell::shell( const uno::Reference< lang::XMultiServiceFactory >& xMultiServiceFactory,
|
|
FileProvider* pProvider, sal_Bool bWithConfig )
|
|
: TaskManager(),
|
|
m_bWithConfig( bWithConfig ),
|
|
m_pProvider( pProvider ),
|
|
m_xMultiServiceFactory( xMultiServiceFactory ),
|
|
Title( RTL_CONSTASCII_USTRINGPARAM("Title") ),
|
|
CasePreservingURL(
|
|
RTL_CONSTASCII_USTRINGPARAM("CasePreservingURL") ),
|
|
IsDocument( RTL_CONSTASCII_USTRINGPARAM("IsDocument") ),
|
|
IsFolder( RTL_CONSTASCII_USTRINGPARAM("IsFolder") ),
|
|
DateModified( RTL_CONSTASCII_USTRINGPARAM("DateModified") ),
|
|
Size( RTL_CONSTASCII_USTRINGPARAM("Size") ),
|
|
IsVolume( RTL_CONSTASCII_USTRINGPARAM("IsVolume") ),
|
|
IsRemoveable( RTL_CONSTASCII_USTRINGPARAM("IsRemoveable") ),
|
|
IsRemote( RTL_CONSTASCII_USTRINGPARAM("IsRemote") ),
|
|
IsCompactDisc( RTL_CONSTASCII_USTRINGPARAM("IsCompactDisc") ),
|
|
IsFloppy( RTL_CONSTASCII_USTRINGPARAM("IsFloppy") ),
|
|
IsHidden( RTL_CONSTASCII_USTRINGPARAM("IsHidden") ),
|
|
ContentType( RTL_CONSTASCII_USTRINGPARAM("ContentType") ),
|
|
IsReadOnly( RTL_CONSTASCII_USTRINGPARAM("IsReadOnly") ),
|
|
CreatableContentsInfo( RTL_CONSTASCII_USTRINGPARAM("CreatableContentsInfo") ),
|
|
FolderContentType( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.staroffice.fsys-folder") ),
|
|
FileContentType( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.staroffice.fsys-file") ),
|
|
m_sCommandInfo( 9 )
|
|
{
|
|
// Title
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
Title,
|
|
-1 ,
|
|
getCppuType( static_cast< rtl::OUString* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND ) );
|
|
|
|
// CasePreservingURL
|
|
m_aDefaultProperties.insert(
|
|
MyProperty( true,
|
|
CasePreservingURL,
|
|
-1 ,
|
|
getCppuType( static_cast< rtl::OUString* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
|
|
// IsFolder
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsFolder,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
|
|
// IsDocument
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsDocument,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// Removable
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsVolume,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
|
|
// Removable
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsRemoveable,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// Remote
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsRemote,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// CompactDisc
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsCompactDisc,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// Floppy
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsFloppy,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// Hidden
|
|
m_aDefaultProperties.insert(
|
|
MyProperty(
|
|
true,
|
|
IsHidden,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
#if defined( WNT )
|
|
));
|
|
#else
|
|
| beans::PropertyAttribute::READONLY)); // under unix/linux only readable
|
|
#endif
|
|
|
|
|
|
// ContentType
|
|
uno::Any aAny;
|
|
aAny <<= rtl::OUString();
|
|
m_aDefaultProperties.insert( MyProperty( false,
|
|
ContentType,
|
|
-1 ,
|
|
getCppuType( static_cast< rtl::OUString* >( 0 ) ),
|
|
aAny,
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
|
|
// DateModified
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
DateModified,
|
|
-1 ,
|
|
getCppuType( static_cast< util::DateTime* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND ) );
|
|
|
|
// Size
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
Size,
|
|
-1,
|
|
getCppuType( static_cast< sal_Int64* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND ) );
|
|
|
|
// IsReadOnly
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
IsReadOnly,
|
|
-1 ,
|
|
getCppuType( static_cast< sal_Bool* >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND ) );
|
|
|
|
|
|
// CreatableContentsInfo
|
|
m_aDefaultProperties.insert( MyProperty( true,
|
|
CreatableContentsInfo,
|
|
-1 ,
|
|
getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
|
|
uno::Any(),
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND
|
|
| beans::PropertyAttribute::READONLY ) );
|
|
|
|
// Commands
|
|
m_sCommandInfo[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("getCommandInfo"));
|
|
m_sCommandInfo[0].Handle = -1;
|
|
m_sCommandInfo[0].ArgType = getCppuVoidType();
|
|
|
|
m_sCommandInfo[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("getPropertySetInfo"));
|
|
m_sCommandInfo[1].Handle = -1;
|
|
m_sCommandInfo[1].ArgType = getCppuVoidType();
|
|
|
|
m_sCommandInfo[2].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("getPropertyValues"));
|
|
m_sCommandInfo[2].Handle = -1;
|
|
m_sCommandInfo[2].ArgType = getCppuType( static_cast< uno::Sequence< beans::Property >* >( 0 ) );
|
|
|
|
m_sCommandInfo[3].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("setPropertyValues"));
|
|
m_sCommandInfo[3].Handle = -1;
|
|
m_sCommandInfo[3].ArgType = getCppuType( static_cast< uno::Sequence< beans::PropertyValue >* >( 0 ) );
|
|
|
|
m_sCommandInfo[4].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("open"));
|
|
m_sCommandInfo[4].Handle = -1;
|
|
m_sCommandInfo[4].ArgType = getCppuType( static_cast< OpenCommandArgument* >( 0 ) );
|
|
|
|
m_sCommandInfo[5].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("transfer"));
|
|
m_sCommandInfo[5].Handle = -1;
|
|
m_sCommandInfo[5].ArgType = getCppuType( static_cast< TransferInfo* >( 0 ) );
|
|
|
|
m_sCommandInfo[6].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("delete"));
|
|
m_sCommandInfo[6].Handle = -1;
|
|
m_sCommandInfo[6].ArgType = getCppuType( static_cast< sal_Bool* >( 0 ) );
|
|
|
|
m_sCommandInfo[7].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("insert"));
|
|
m_sCommandInfo[7].Handle = -1;
|
|
m_sCommandInfo[7].ArgType = getCppuType( static_cast< InsertCommandArgument* > ( 0 ) );
|
|
|
|
m_sCommandInfo[7].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("createNewContent"));
|
|
m_sCommandInfo[7].Handle = -1;
|
|
m_sCommandInfo[7].ArgType = getCppuType( static_cast< ucb::ContentInfo * > ( 0 ) );
|
|
|
|
if(m_bWithConfig)
|
|
{
|
|
rtl::OUString Store(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Store"));
|
|
uno::Reference< XPropertySetRegistryFactory > xRegFac(
|
|
m_xMultiServiceFactory->createInstance( Store ),
|
|
uno::UNO_QUERY );
|
|
if ( xRegFac.is() )
|
|
{
|
|
// Open/create a registry
|
|
m_xFileRegistry = xRegFac->createPropertySetRegistry( rtl::OUString() );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
shell::~shell()
|
|
{
|
|
}
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* de/registerNotifier-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
|
|
//
|
|
// This two methods register and deregister a change listener for the content belonging
|
|
// to URL aUnqPath
|
|
//
|
|
|
|
void SAL_CALL
|
|
shell::registerNotifier( const rtl::OUString& aUnqPath, Notifier* pNotifier )
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
ContentMap::iterator it =
|
|
m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
|
|
|
|
if( ! it->second.notifier )
|
|
it->second.notifier = new NotifierList();
|
|
|
|
std::list< Notifier* >& nlist = *( it->second.notifier );
|
|
|
|
std::list<Notifier*>::iterator it1 = nlist.begin();
|
|
while( it1 != nlist.end() ) // Every "Notifier" only once
|
|
{
|
|
if( *it1 == pNotifier ) return;
|
|
++it1;
|
|
}
|
|
nlist.push_back( pNotifier );
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL
|
|
shell::deregisterNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier )
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
ContentMap::iterator it = m_aContent.find( aUnqPath );
|
|
if( it == m_aContent.end() )
|
|
return;
|
|
|
|
it->second.notifier->remove( pNotifier );
|
|
|
|
if( ! it->second.notifier->size() )
|
|
m_aContent.erase( it );
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* de/associate-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Used to associate and deassociate a new property with
|
|
// the content belonging to URL UnqPath.
|
|
// The default value and the the attributes are input
|
|
//
|
|
|
|
void SAL_CALL
|
|
shell::associate( const rtl::OUString& aUnqPath,
|
|
const rtl::OUString& PropertyName,
|
|
const uno::Any& DefaultValue,
|
|
const sal_Int16 Attributes )
|
|
throw( beans::PropertyExistException,
|
|
beans::IllegalTypeException,
|
|
uno::RuntimeException )
|
|
{
|
|
MyProperty newProperty( false,
|
|
PropertyName,
|
|
-1,
|
|
DefaultValue.getValueType(),
|
|
DefaultValue,
|
|
beans::PropertyState_DEFAULT_VALUE,
|
|
Attributes );
|
|
|
|
shell::PropertySet::iterator it1 = m_aDefaultProperties.find( newProperty );
|
|
if( it1 != m_aDefaultProperties.end() )
|
|
throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
|
|
|
|
// Load the XPersistentPropertySetInfo and create it, if it does not exist
|
|
load( it,true );
|
|
|
|
PropertySet& properties = *(it->second.properties);
|
|
it1 = properties.find( newProperty );
|
|
if( it1 != properties.end() )
|
|
throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
|
|
// Property does not exist
|
|
properties.insert( newProperty );
|
|
it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
|
|
}
|
|
notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
|
|
}
|
|
|
|
|
|
|
|
|
|
void SAL_CALL
|
|
shell::deassociate( const rtl::OUString& aUnqPath,
|
|
const rtl::OUString& PropertyName )
|
|
throw( beans::UnknownPropertyException,
|
|
beans::NotRemoveableException,
|
|
uno::RuntimeException )
|
|
{
|
|
MyProperty oldProperty( PropertyName );
|
|
|
|
shell::PropertySet::iterator it1 = m_aDefaultProperties.find( oldProperty );
|
|
if( it1 != m_aDefaultProperties.end() )
|
|
throw beans::NotRemoveableException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
|
|
|
|
load( it,false );
|
|
|
|
PropertySet& properties = *(it->second.properties);
|
|
|
|
it1 = properties.find( oldProperty );
|
|
if( it1 == properties.end() )
|
|
throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
|
|
properties.erase( it1 );
|
|
|
|
if( it->second.xC.is() )
|
|
it->second.xC->removeProperty( PropertyName );
|
|
|
|
if( properties.size() == 9 )
|
|
{
|
|
MyProperty ContentTProperty( ContentType );
|
|
|
|
if( properties.find( ContentTProperty )->getState() == beans::PropertyState_DEFAULT_VALUE )
|
|
{
|
|
it->second.xS = 0;
|
|
it->second.xC = 0;
|
|
it->second.xA = 0;
|
|
if(m_xFileRegistry.is())
|
|
m_xFileRegistry->removePropertySet( aUnqPath );
|
|
}
|
|
}
|
|
notifyPropertyRemoved( getPropertySetListeners( aUnqPath ), PropertyName );
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* page-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Given an xOutputStream, this method writes the content of the file belonging to
|
|
// URL aUnqPath into the XOutputStream
|
|
//
|
|
|
|
|
|
void SAL_CALL shell::page( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
const uno::Reference< io::XOutputStream >& xOutputStream )
|
|
throw()
|
|
{
|
|
uno::Reference< XContentProvider > xProvider( m_pProvider );
|
|
osl::File aFile( aUnqPath );
|
|
osl::FileBase::RC err = aFile.open( osl_File_OpenFlag_Read );
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
aFile.close();
|
|
installError( CommandId,
|
|
TASKHANDLING_OPEN_FILE_FOR_PAGING,
|
|
err );
|
|
return;
|
|
}
|
|
|
|
const sal_uInt64 bfz = 4*1024;
|
|
sal_Int8 BFF[bfz];
|
|
sal_uInt64 nrc; // Retrieved number of Bytes;
|
|
|
|
do
|
|
{
|
|
err = aFile.read( (void*) BFF,bfz,nrc );
|
|
if( err == osl::FileBase::E_None )
|
|
{
|
|
uno::Sequence< sal_Int8 > seq( BFF, (sal_uInt32)nrc );
|
|
try
|
|
{
|
|
xOutputStream->writeBytes( seq );
|
|
}
|
|
catch (const io::NotConnectedException&)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NOTCONNECTED_FOR_PAGING );
|
|
break;
|
|
}
|
|
catch (const io::BufferSizeExceededException&)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING );
|
|
break;
|
|
}
|
|
catch (const io::IOException&)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_IOEXCEPTION_FOR_PAGING );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_READING_FILE_FOR_PAGING,
|
|
err );
|
|
break;
|
|
}
|
|
} while( nrc == bfz );
|
|
|
|
|
|
aFile.close();
|
|
|
|
|
|
try
|
|
{
|
|
xOutputStream->closeOutput();
|
|
}
|
|
catch (const io::NotConnectedException&)
|
|
{
|
|
}
|
|
catch (const io::BufferSizeExceededException&)
|
|
{
|
|
}
|
|
catch (const io::IOException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* open-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
|
|
//
|
|
|
|
|
|
uno::Reference< io::XInputStream > SAL_CALL
|
|
shell::open( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
sal_Bool bLock )
|
|
throw()
|
|
{
|
|
XInputStream_impl* xInputStream = new XInputStream_impl( this, aUnqPath, bLock ); // from filinpstr.hxx
|
|
|
|
sal_Int32 ErrorCode = xInputStream->CtorSuccess();
|
|
|
|
if( ErrorCode != TASKHANDLER_NO_ERROR )
|
|
{
|
|
installError( CommandId,
|
|
ErrorCode,
|
|
xInputStream->getMinorError() );
|
|
|
|
delete xInputStream;
|
|
xInputStream = 0;
|
|
}
|
|
|
|
return uno::Reference< io::XInputStream >( xInputStream );
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* open for read/write access-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Given a file URL aUnqPath, this methods returns a XStream which can be used
|
|
// to read and write from/to the file.
|
|
//
|
|
|
|
|
|
uno::Reference< io::XStream > SAL_CALL
|
|
shell::open_rw( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
sal_Bool bLock )
|
|
throw()
|
|
{
|
|
XStream_impl* xStream = new XStream_impl( this, aUnqPath, bLock ); // from filstr.hxx
|
|
|
|
sal_Int32 ErrorCode = xStream->CtorSuccess();
|
|
|
|
if( ErrorCode != TASKHANDLER_NO_ERROR )
|
|
{
|
|
installError( CommandId,
|
|
ErrorCode,
|
|
xStream->getMinorError() );
|
|
|
|
delete xStream;
|
|
xStream = 0;
|
|
}
|
|
return uno::Reference< io::XStream >( xStream );
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* ls-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// This method returns the result set containing the the children of the directory belonging
|
|
// to file URL aUnqPath
|
|
//
|
|
|
|
|
|
uno::Reference< XDynamicResultSet > SAL_CALL
|
|
shell::ls( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
const sal_Int32 OpenMode,
|
|
const uno::Sequence< beans::Property >& seq,
|
|
const uno::Sequence< NumberedSortingInfo >& seqSort )
|
|
throw()
|
|
{
|
|
XResultSet_impl* p = new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort );
|
|
|
|
sal_Int32 ErrorCode = p->CtorSuccess();
|
|
|
|
if( ErrorCode != TASKHANDLER_NO_ERROR )
|
|
{
|
|
installError( CommandId,
|
|
ErrorCode,
|
|
p->getMinorError() );
|
|
|
|
delete p;
|
|
p = 0;
|
|
}
|
|
|
|
return uno::Reference< XDynamicResultSet > ( p );
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* info_c implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
// Info for commands
|
|
|
|
uno::Reference< XCommandInfo > SAL_CALL
|
|
shell::info_c()
|
|
throw()
|
|
{
|
|
XCommandInfo_impl* p = new XCommandInfo_impl( this );
|
|
return uno::Reference< XCommandInfo >( p );
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* info_p-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
// Info for the properties
|
|
|
|
uno::Reference< beans::XPropertySetInfo > SAL_CALL
|
|
shell::info_p( const rtl::OUString& aUnqPath )
|
|
throw()
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
XPropertySetInfo_impl* p = new XPropertySetInfo_impl( this,aUnqPath );
|
|
return uno::Reference< beans::XPropertySetInfo >( p );
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* setv-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Sets the values of the properties belonging to fileURL aUnqPath
|
|
//
|
|
|
|
|
|
uno::Sequence< uno::Any > SAL_CALL
|
|
shell::setv( const rtl::OUString& aUnqPath,
|
|
const uno::Sequence< beans::PropertyValue >& values )
|
|
throw()
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
sal_Int32 propChanged = 0;
|
|
uno::Sequence< uno::Any > ret( values.getLength() );
|
|
uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
|
|
|
|
shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
|
|
PropertySet& properties = *( it->second.properties );
|
|
shell::PropertySet::iterator it1;
|
|
uno::Any aAny;
|
|
|
|
for( sal_Int32 i = 0; i < values.getLength(); ++i )
|
|
{
|
|
MyProperty toset( values[i].Name );
|
|
it1 = properties.find( toset );
|
|
if( it1 == properties.end() )
|
|
{
|
|
ret[i] <<= beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
continue;
|
|
}
|
|
|
|
aAny = it1->getValue();
|
|
if( aAny == values[i].Value )
|
|
continue; // nothing needs to be changed
|
|
|
|
if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
|
|
{
|
|
ret[i] <<= lang::IllegalAccessException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
continue;
|
|
}
|
|
|
|
seqChanged[ propChanged ].PropertyName = values[i].Name;
|
|
seqChanged[ propChanged ].PropertyHandle = -1;
|
|
seqChanged[ propChanged ].Further = false;
|
|
seqChanged[ propChanged ].OldValue <<= aAny;
|
|
seqChanged[ propChanged++ ].NewValue = values[i].Value;
|
|
|
|
it1->setValue( values[i].Value ); // Put the new value into the local cash
|
|
|
|
if( ! it1->IsNative() )
|
|
{
|
|
// Also put logical properties into storage
|
|
if( !it->second.xS.is() )
|
|
load( it,true );
|
|
|
|
if( ( values[i].Name == ContentType ) &&
|
|
it1->getState() == beans::PropertyState_DEFAULT_VALUE )
|
|
{ // Special logic for ContentType
|
|
// 09.07.01: Not reached anymore, because ContentType is readonly
|
|
it1->setState( beans::PropertyState_DIRECT_VALUE );
|
|
it->second.xC->addProperty( values[i].Name,
|
|
beans::PropertyAttribute::MAYBEVOID,
|
|
values[i].Value );
|
|
}
|
|
|
|
try
|
|
{
|
|
it->second.xS->setPropertyValue( values[i].Name,values[i].Value );
|
|
}
|
|
catch (const uno::Exception&e)
|
|
{
|
|
--propChanged; // unsuccessful setting
|
|
ret[i] <<= e;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// native properties
|
|
// Setting of physical file properties
|
|
if( values[i].Name == Size )
|
|
{
|
|
sal_Int64 newSize = 0;
|
|
if( values[i].Value >>= newSize )
|
|
{ // valid value for the size
|
|
osl::File aFile(aUnqPath);
|
|
bool err =
|
|
aFile.open(osl_File_OpenFlag_Write) != osl::FileBase::E_None ||
|
|
aFile.setSize(sal_uInt64(newSize)) != osl::FileBase::E_None ||
|
|
aFile.close() != osl::FileBase::E_None;
|
|
|
|
if( err )
|
|
{
|
|
--propChanged; // unsuccessful setting
|
|
uno::Sequence< uno::Any > names( 1 );
|
|
ret[0] <<= beans::PropertyValue(
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Uri")), -1,
|
|
uno::makeAny(aUnqPath),
|
|
beans::PropertyState_DIRECT_VALUE);
|
|
IOErrorCode ioError(IOErrorCode_GENERAL);
|
|
ret[i] <<= InteractiveAugmentedIOException(
|
|
rtl::OUString(),
|
|
0,
|
|
task::InteractionClassification_ERROR,
|
|
ioError,
|
|
names );
|
|
}
|
|
}
|
|
else
|
|
ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
}
|
|
else if(values[i].Name == IsReadOnly ||
|
|
values[i].Name == IsHidden)
|
|
{
|
|
sal_Bool value = sal_False;
|
|
if( values[i].Value >>= value )
|
|
{
|
|
osl::DirectoryItem aDirItem;
|
|
osl::FileBase::RC err =
|
|
osl::DirectoryItem::get(aUnqPath,aDirItem);
|
|
sal_uInt64 nAttributes(0);
|
|
if(err == osl::FileBase::E_None)
|
|
{
|
|
osl::FileStatus aFileStatus(osl_FileStatus_Mask_Attributes);
|
|
err = aDirItem.getFileStatus(aFileStatus);
|
|
if(err == osl::FileBase::E_None &&
|
|
aFileStatus.isValid(osl_FileStatus_Mask_Attributes))
|
|
nAttributes = aFileStatus.getAttributes();
|
|
}
|
|
// now we have the attributes provided all went well.
|
|
if(err == osl::FileBase::E_None) {
|
|
if(values[i].Name == IsReadOnly)
|
|
{
|
|
nAttributes &= ~(osl_File_Attribute_OwnWrite |
|
|
osl_File_Attribute_GrpWrite |
|
|
osl_File_Attribute_OthWrite |
|
|
osl_File_Attribute_ReadOnly);
|
|
if(value)
|
|
nAttributes |= osl_File_Attribute_ReadOnly;
|
|
else
|
|
nAttributes |= (
|
|
osl_File_Attribute_OwnWrite |
|
|
osl_File_Attribute_GrpWrite |
|
|
osl_File_Attribute_OthWrite);
|
|
}
|
|
else if(values[i].Name == IsHidden)
|
|
{
|
|
nAttributes &= ~(osl_File_Attribute_Hidden);
|
|
if(value)
|
|
nAttributes |= osl_File_Attribute_Hidden;
|
|
}
|
|
err = osl::File::setAttributes(
|
|
aUnqPath,nAttributes);
|
|
}
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
--propChanged; // unsuccessful setting
|
|
uno::Sequence< uno::Any > names( 1 );
|
|
names[0] <<= beans::PropertyValue(
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Uri")), -1,
|
|
uno::makeAny(aUnqPath),
|
|
beans::PropertyState_DIRECT_VALUE);
|
|
IOErrorCode ioError;
|
|
switch( err )
|
|
{
|
|
case osl::FileBase::E_NOMEM:
|
|
// not enough memory for allocating structures <br>
|
|
ioError = IOErrorCode_OUT_OF_MEMORY;
|
|
break;
|
|
case osl::FileBase::E_INVAL:
|
|
// the format of the parameters was not valid<p>
|
|
ioError = IOErrorCode_INVALID_PARAMETER;
|
|
break;
|
|
case osl::FileBase::E_NAMETOOLONG:
|
|
// File name too long<br>
|
|
ioError = IOErrorCode_NAME_TOO_LONG;
|
|
break;
|
|
case osl::FileBase::E_NOENT:
|
|
// No such file or directory<br>
|
|
case osl::FileBase::E_NOLINK:
|
|
// Link has been severed<br>
|
|
ioError = IOErrorCode_NOT_EXISTING;
|
|
break;
|
|
case osl::FileBase::E_ROFS:
|
|
// #i4735# handle ROFS transparently
|
|
// as ACCESS_DENIED
|
|
case osl::FileBase::E_PERM:
|
|
case osl::FileBase::E_ACCES:
|
|
// permission denied<br>
|
|
ioError = IOErrorCode_ACCESS_DENIED;
|
|
break;
|
|
case osl::FileBase::E_LOOP:
|
|
// Too many symbolic links encountered<br>
|
|
case osl::FileBase::E_FAULT:
|
|
// Bad address<br>
|
|
case osl::FileBase::E_IO:
|
|
// I/O error<br>
|
|
case osl::FileBase::E_NOSYS:
|
|
// Function not implemented<br>
|
|
case osl::FileBase::E_MULTIHOP:
|
|
// Multihop attempted<br>
|
|
case osl::FileBase::E_INTR:
|
|
// function call was interrupted<p>
|
|
default:
|
|
ioError = IOErrorCode_GENERAL;
|
|
break;
|
|
}
|
|
ret[i] <<= InteractiveAugmentedIOException(
|
|
rtl::OUString(),
|
|
0,
|
|
task::InteractionClassification_ERROR,
|
|
ioError,
|
|
names );
|
|
}
|
|
}
|
|
else
|
|
ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
|
|
}
|
|
}
|
|
} // end for
|
|
|
|
if( propChanged )
|
|
{
|
|
seqChanged.realloc( propChanged );
|
|
notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath ),seqChanged );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* getv-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Reads the values of the properties belonging to fileURL aUnqPath;
|
|
// Returns an XRow object containing the values in the requested order.
|
|
//
|
|
|
|
|
|
uno::Reference< sdbc::XRow > SAL_CALL
|
|
shell::getv( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
const uno::Sequence< beans::Property >& properties )
|
|
throw()
|
|
{
|
|
uno::Sequence< uno::Any > seq( properties.getLength() );
|
|
|
|
sal_Int32 n_Mask;
|
|
getMaskFromProperties( n_Mask,properties );
|
|
osl::FileStatus aFileStatus( n_Mask );
|
|
|
|
osl::DirectoryItem aDirItem;
|
|
osl::FileBase::RC nError1 = osl::DirectoryItem::get( aUnqPath,aDirItem );
|
|
if( nError1 != osl::FileBase::E_None )
|
|
installError(CommandId,
|
|
TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
|
|
nError1);
|
|
|
|
osl::FileBase::RC nError2 = aDirItem.getFileStatus( aFileStatus );
|
|
if( nError1 == osl::FileBase::E_None &&
|
|
nError2 != osl::FileBase::E_None )
|
|
installError(CommandId,
|
|
TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
|
|
nError2);
|
|
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
|
|
commit( it,aFileStatus );
|
|
|
|
shell::PropertySet::iterator it1;
|
|
PropertySet& propset = *(it->second.properties);
|
|
|
|
for( sal_Int32 i = 0; i < seq.getLength(); ++i )
|
|
{
|
|
MyProperty readProp( properties[i].Name );
|
|
it1 = propset.find( readProp );
|
|
if( it1 == propset.end() )
|
|
seq[i] = uno::Any();
|
|
else
|
|
seq[i] = it1->getValue();
|
|
}
|
|
}
|
|
|
|
XRow_impl* p = new XRow_impl( this,seq );
|
|
return uno::Reference< sdbc::XRow >( p );
|
|
}
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* transfer-commandos */
|
|
/* */
|
|
/********************************************************************************/
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* move-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
|
|
//
|
|
|
|
void SAL_CALL
|
|
shell::move( sal_Int32 CommandId,
|
|
const rtl::OUString srcUnqPath,
|
|
const rtl::OUString dstUnqPathIn,
|
|
const sal_Int32 NameClash )
|
|
throw()
|
|
{
|
|
// --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
|
|
// srcUnqPath and dstUnqPathIn are equal
|
|
if( srcUnqPath == dstUnqPathIn )
|
|
return;
|
|
//
|
|
osl::FileBase::RC nError;
|
|
rtl::OUString dstUnqPath( dstUnqPathIn );
|
|
|
|
switch( NameClash )
|
|
{
|
|
case NameClash::KEEP:
|
|
{
|
|
nError = osl_File_move( srcUnqPath,dstUnqPath,true );
|
|
if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_KEEPERROR_FOR_MOVE,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::OVERWRITE:
|
|
{
|
|
// stat to determine whether we have a symlink
|
|
rtl::OUString targetPath(dstUnqPath);
|
|
|
|
osl::FileStatus aStatus(osl_FileStatus_Mask_Type|osl_FileStatus_Mask_LinkTargetURL);
|
|
osl::DirectoryItem aItem;
|
|
osl::DirectoryItem::get(dstUnqPath,aItem);
|
|
aItem.getFileStatus(aStatus);
|
|
|
|
if( aStatus.isValid(osl_FileStatus_Mask_Type) &&
|
|
aStatus.isValid(osl_FileStatus_Mask_LinkTargetURL) &&
|
|
aStatus.getFileType() == osl::FileStatus::Link )
|
|
targetPath = aStatus.getLinkTargetURL();
|
|
|
|
// Will do nothing if file does not exist.
|
|
osl::File::remove( targetPath );
|
|
|
|
nError = osl_File_move( srcUnqPath,targetPath );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_OVERWRITE_FOR_MOVE,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::RENAME:
|
|
{
|
|
rtl::OUString newDstUnqPath;
|
|
nError = osl_File_move( srcUnqPath,dstUnqPath,true );
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
// "invent" a new valid title.
|
|
|
|
sal_Int32 nPos = -1;
|
|
sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
|
|
sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
|
|
if( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
|
|
&& ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
|
|
nPos = nLastDot;
|
|
else
|
|
nPos = dstUnqPath.getLength();
|
|
|
|
sal_Int32 nTry = 0;
|
|
|
|
do
|
|
{
|
|
newDstUnqPath = dstUnqPath;
|
|
|
|
rtl::OUString aPostFix( RTL_CONSTASCII_USTRINGPARAM("_") );
|
|
aPostFix += rtl::OUString::valueOf( ++nTry );
|
|
|
|
newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
|
|
|
|
nError = osl_File_move( srcUnqPath,newDstUnqPath,true );
|
|
}
|
|
while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
|
|
}
|
|
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_RENAME_FOR_MOVE );
|
|
return;
|
|
}
|
|
else if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_RENAMEMOVE_FOR_MOVE,
|
|
nError );
|
|
return;
|
|
}
|
|
else
|
|
dstUnqPath = newDstUnqPath;
|
|
|
|
break;
|
|
}
|
|
case NameClash::ERROR:
|
|
{
|
|
nError = osl_File_move( srcUnqPath,dstUnqPath,true );
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASH_FOR_MOVE );
|
|
return;
|
|
}
|
|
else if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASHMOVE_FOR_MOVE,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::ASK:
|
|
default:
|
|
{
|
|
nError = osl_File_move( srcUnqPath,dstUnqPath,true );
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE,
|
|
NameClash::ASK);
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Determine, whether we have moved a file or a folder
|
|
osl::DirectoryItem aItem;
|
|
nError = osl::DirectoryItem::get( dstUnqPath,aItem );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_TRANSFER_BY_MOVE_SOURCE,
|
|
nError );
|
|
return;
|
|
}
|
|
osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
|
|
nError = aItem.getFileStatus( aStatus );
|
|
if( nError != osl::FileBase::E_None || ! aStatus.isValid( osl_FileStatus_Mask_Type ) )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT,
|
|
nError );
|
|
return;
|
|
}
|
|
sal_Bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );
|
|
|
|
|
|
copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );
|
|
|
|
rtl::OUString aDstParent = getParentName( dstUnqPath );
|
|
rtl::OUString aDstTitle = getTitle( dstUnqPath );
|
|
|
|
rtl::OUString aSrcParent = getParentName( srcUnqPath );
|
|
rtl::OUString aSrcTitle = getTitle( srcUnqPath );
|
|
|
|
notifyInsert( getContentEventListeners( aDstParent ),dstUnqPath );
|
|
if( aDstParent != aSrcParent )
|
|
notifyContentRemoved( getContentEventListeners( aSrcParent ),srcUnqPath );
|
|
|
|
notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) );
|
|
erasePersistentSet( srcUnqPath,!isDocument );
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* copy-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
|
|
//
|
|
|
|
namespace {
|
|
|
|
bool getType(
|
|
TaskManager & task, sal_Int32 id, rtl::OUString const & fileUrl,
|
|
osl::DirectoryItem * item, osl::FileStatus::Type * type)
|
|
{
|
|
OSL_ASSERT(item != 0 && type != 0);
|
|
osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
|
|
if (err != osl::FileBase::E_None) {
|
|
task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCE, err);
|
|
return false;
|
|
}
|
|
osl::FileStatus stat(osl_FileStatus_Mask_Type);
|
|
err = item->getFileStatus(stat);
|
|
if (err != osl::FileBase::E_None) {
|
|
task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, err);
|
|
return false;
|
|
}
|
|
*type = stat.getFileType();
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
void SAL_CALL
|
|
shell::copy(
|
|
sal_Int32 CommandId,
|
|
const rtl::OUString srcUnqPath,
|
|
const rtl::OUString dstUnqPathIn,
|
|
sal_Int32 NameClash )
|
|
throw()
|
|
{
|
|
osl::FileBase::RC nError;
|
|
rtl::OUString dstUnqPath( dstUnqPathIn );
|
|
|
|
// Resolve symbolic links within the source path. If srcUnqPath denotes a
|
|
// symbolic link (targeting either a file or a folder), the contents of the
|
|
// target is copied (recursively, in the case of a folder). However, if
|
|
// recursively copying the contents of a folder causes a symbolic link to be
|
|
// copied, the symbolic link itself is copied.
|
|
osl::DirectoryItem item;
|
|
osl::FileStatus::Type type;
|
|
if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
|
|
return;
|
|
}
|
|
rtl::OUString rslvdSrcUnqPath;
|
|
if (type == osl::FileStatus::Link) {
|
|
osl::FileStatus stat(osl_FileStatus_Mask_LinkTargetURL);
|
|
nError = item.getFileStatus(stat);
|
|
if (nError != osl::FileBase::E_None) {
|
|
installError(
|
|
CommandId, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, nError);
|
|
return;
|
|
}
|
|
rslvdSrcUnqPath = stat.getLinkTargetURL();
|
|
if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
|
|
return;
|
|
}
|
|
} else {
|
|
rslvdSrcUnqPath = srcUnqPath;
|
|
}
|
|
|
|
sal_Bool isDocument
|
|
= type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
|
|
sal_Int32 IsWhat = isDocument ? -1 : 1;
|
|
|
|
switch( NameClash )
|
|
{
|
|
case NameClash::KEEP:
|
|
{
|
|
nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
|
|
if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_KEEPERROR_FOR_COPY,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::OVERWRITE:
|
|
{
|
|
// remove (..., MustExist = sal_False).
|
|
remove( CommandId, dstUnqPath, IsWhat, sal_False );
|
|
|
|
// copy.
|
|
nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_OVERWRITE_FOR_COPY,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::RENAME:
|
|
{
|
|
rtl::OUString newDstUnqPath;
|
|
nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
|
|
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
// "invent" a new valid title.
|
|
|
|
sal_Int32 nPos = -1;
|
|
sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
|
|
sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
|
|
if ( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
|
|
&& ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
|
|
nPos = nLastDot;
|
|
else
|
|
nPos = dstUnqPath.getLength();
|
|
|
|
sal_Int32 nTry = 0;
|
|
|
|
do
|
|
{
|
|
newDstUnqPath = dstUnqPath;
|
|
|
|
rtl::OUString aPostFix( RTL_CONSTASCII_USTRINGPARAM("_") );
|
|
aPostFix += rtl::OUString::valueOf( ++nTry );
|
|
|
|
newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
|
|
|
|
nError = copy_recursive( rslvdSrcUnqPath,newDstUnqPath,IsWhat,true );
|
|
}
|
|
while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
|
|
}
|
|
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_RENAME_FOR_COPY );
|
|
return;
|
|
}
|
|
else if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_RENAMEMOVE_FOR_COPY,
|
|
nError );
|
|
return;
|
|
}
|
|
else
|
|
dstUnqPath = newDstUnqPath;
|
|
|
|
break;
|
|
}
|
|
case NameClash::ERROR:
|
|
{
|
|
nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
|
|
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASH_FOR_COPY );
|
|
return;
|
|
}
|
|
else if( nError != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASHMOVE_FOR_COPY,
|
|
nError );
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case NameClash::ASK:
|
|
default:
|
|
{
|
|
nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
|
|
|
|
if( nError == osl::FileBase::E_EXIST )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY,
|
|
NameClash);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
copyPersistentSet( srcUnqPath,dstUnqPath, !isDocument );
|
|
notifyInsert( getContentEventListeners( getParentName( dstUnqPath ) ),dstUnqPath );
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* remove-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
|
|
// Return: success of operation
|
|
//
|
|
|
|
|
|
sal_Bool SAL_CALL
|
|
shell::remove( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
sal_Int32 IsWhat,
|
|
sal_Bool MustExist )
|
|
throw()
|
|
{
|
|
sal_Int32 nMask = osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL;
|
|
|
|
osl::DirectoryItem aItem;
|
|
osl::FileStatus aStatus( nMask );
|
|
osl::FileBase::RC nError;
|
|
|
|
if( IsWhat == 0 ) // Determine whether we are removing a directory or a file
|
|
{
|
|
nError = osl::DirectoryItem::get( aUnqPath, aItem );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
if (MustExist)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE,
|
|
nError );
|
|
}
|
|
return (!MustExist);
|
|
}
|
|
|
|
nError = aItem.getFileStatus( aStatus );
|
|
if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE,
|
|
nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
|
|
return sal_False;
|
|
}
|
|
|
|
if( aStatus.getFileType() == osl::FileStatus::Regular ||
|
|
aStatus.getFileType() == osl::FileStatus::Link )
|
|
IsWhat = -1; // RemoveFile
|
|
else if( aStatus.getFileType() == osl::FileStatus::Directory ||
|
|
aStatus.getFileType() == osl::FileStatus::Volume )
|
|
IsWhat = +1; // RemoveDirectory
|
|
}
|
|
|
|
|
|
if( IsWhat == -1 ) // Removing a file
|
|
{
|
|
nError = osl::File::remove( aUnqPath );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
if (MustExist)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_DELETEFILE_FOR_REMOVE,
|
|
nError );
|
|
}
|
|
return (!MustExist);
|
|
}
|
|
else
|
|
{
|
|
notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
|
|
erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
|
|
}
|
|
}
|
|
else if( IsWhat == +1 ) // Removing a directory
|
|
{
|
|
osl::Directory aDirectory( aUnqPath );
|
|
|
|
nError = aDirectory.open();
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
if (MustExist)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_OPENDIRECTORY_FOR_REMOVE,
|
|
nError );
|
|
}
|
|
return (!MustExist);
|
|
}
|
|
|
|
sal_Bool whileSuccess = sal_True;
|
|
sal_Int32 recurse = 0;
|
|
rtl::OUString name;
|
|
|
|
nError = aDirectory.getNextItem( aItem );
|
|
while( nError == osl::FileBase::E_None )
|
|
{
|
|
nError = aItem.getFileStatus( aStatus );
|
|
if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE,
|
|
nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
|
|
whileSuccess = sal_False;
|
|
break;
|
|
}
|
|
|
|
if( aStatus.getFileType() == osl::FileStatus::Regular ||
|
|
aStatus.getFileType() == osl::FileStatus::Link )
|
|
recurse = -1;
|
|
else if( aStatus.getFileType() == osl::FileStatus::Directory ||
|
|
aStatus.getFileType() == osl::FileStatus::Volume )
|
|
recurse = +1;
|
|
|
|
name = aStatus.getFileURL();
|
|
whileSuccess = remove(
|
|
CommandId, name, recurse, MustExist );
|
|
if( !whileSuccess )
|
|
break;
|
|
|
|
nError = aDirectory.getNextItem( aItem );
|
|
}
|
|
|
|
aDirectory.close();
|
|
|
|
if( ! whileSuccess )
|
|
return sal_False; // error code is installed
|
|
|
|
if( nError != osl::FileBase::E_NOENT )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE,
|
|
nError );
|
|
return sal_False;
|
|
}
|
|
|
|
nError = osl::Directory::remove( aUnqPath );
|
|
if( nError != osl::FileBase::E_None )
|
|
{
|
|
if (MustExist)
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE,
|
|
nError );
|
|
}
|
|
return (!MustExist);
|
|
}
|
|
else
|
|
{
|
|
notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
|
|
erasePersistentSet( aUnqPath );
|
|
}
|
|
}
|
|
else // Don't know what to remove
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FILETYPE_FOR_REMOVE );
|
|
return sal_False;
|
|
}
|
|
|
|
return sal_True;
|
|
}
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* mkdir-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// Creates new directory with given URL, recursively if necessary
|
|
// Return:: success of operation
|
|
//
|
|
|
|
sal_Bool SAL_CALL
|
|
shell::mkdir( sal_Int32 CommandId,
|
|
const rtl::OUString& rUnqPath,
|
|
sal_Bool OverWrite )
|
|
throw()
|
|
{
|
|
rtl::OUString aUnqPath;
|
|
|
|
// remove trailing slash
|
|
if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
|
|
aUnqPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
|
|
else
|
|
aUnqPath = rUnqPath;
|
|
|
|
osl::FileBase::RC nError = osl::Directory::create( aUnqPath );
|
|
|
|
switch ( nError )
|
|
{
|
|
case osl::FileBase::E_EXIST: // Directory cannot be overwritten
|
|
{
|
|
if( !OverWrite )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FOLDER_EXISTS_MKDIR );
|
|
return sal_False;
|
|
}
|
|
else
|
|
return sal_True;
|
|
}
|
|
case osl::FileBase::E_INVAL:
|
|
{
|
|
installError(CommandId,
|
|
TASKHANDLING_INVALID_NAME_MKDIR);
|
|
return sal_False;
|
|
}
|
|
case osl::FileBase::E_None:
|
|
{
|
|
rtl::OUString aPrtPath = getParentName( aUnqPath );
|
|
notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
|
|
return sal_True;
|
|
}
|
|
default:
|
|
return ensuredir(
|
|
CommandId,
|
|
aUnqPath,
|
|
TASKHANDLING_CREATEDIRECTORY_MKDIR );
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* mkfil-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// Creates new file with given URL.
|
|
// The content of aInputStream becomes the content of the file
|
|
// Return:: success of operation
|
|
//
|
|
|
|
sal_Bool SAL_CALL
|
|
shell::mkfil( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
sal_Bool Overwrite,
|
|
const uno::Reference< io::XInputStream >& aInputStream )
|
|
throw()
|
|
{
|
|
// return value unimportant
|
|
sal_Bool bSuccess = write( CommandId,
|
|
aUnqPath,
|
|
Overwrite,
|
|
aInputStream );
|
|
if ( bSuccess )
|
|
{
|
|
rtl::OUString aPrtPath = getParentName( aUnqPath );
|
|
notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
/********************************************************************************/
|
|
/* */
|
|
/* write-implementation */
|
|
/* */
|
|
/********************************************************************************/
|
|
//
|
|
// writes to the file with given URL.
|
|
// The content of aInputStream becomes the content of the file
|
|
// Return:: success of operation
|
|
//
|
|
|
|
sal_Bool SAL_CALL
|
|
shell::write( sal_Int32 CommandId,
|
|
const rtl::OUString& aUnqPath,
|
|
sal_Bool OverWrite,
|
|
const uno::Reference< io::XInputStream >& aInputStream )
|
|
throw()
|
|
{
|
|
if( ! aInputStream.is() )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_INPUTSTREAM_FOR_WRITE );
|
|
return sal_False;
|
|
}
|
|
|
|
// Create parent path, if necessary.
|
|
if ( ! ensuredir( CommandId,
|
|
getParentName( aUnqPath ),
|
|
TASKHANDLING_ENSUREDIR_FOR_WRITE ) )
|
|
return sal_False;
|
|
|
|
osl::FileBase::RC err;
|
|
osl::File aFile( aUnqPath );
|
|
|
|
if( OverWrite )
|
|
{
|
|
err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
aFile.close();
|
|
err = aFile.open( osl_File_OpenFlag_Write );
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE,
|
|
err );
|
|
return sal_False;
|
|
}
|
|
|
|
// the existing file was just opened and should be overwritten now,
|
|
// truncate it first
|
|
|
|
err = aFile.setSize( 0 );
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FILESIZE_FOR_WRITE,
|
|
err );
|
|
return sal_False;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = aFile.open( osl_File_OpenFlag_Read | osl_File_OpenFlag_NoLock );
|
|
if( err == osl::FileBase::E_None ) // The file exists and shall not be overwritten
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NOREPLACE_FOR_WRITE, // Now an exception
|
|
err );
|
|
|
|
aFile.close();
|
|
return sal_False;
|
|
}
|
|
|
|
// as a temporary solution the creation does not lock the file at all
|
|
// in future it should be possible to create the file without lock explicitly
|
|
err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock );
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
aFile.close();
|
|
installError( CommandId,
|
|
TASKHANDLING_NO_OPEN_FILE_FOR_WRITE,
|
|
err );
|
|
return sal_False;
|
|
}
|
|
}
|
|
|
|
sal_Bool bSuccess = sal_True;
|
|
|
|
sal_uInt64 nWrittenBytes;
|
|
sal_Int32 nReadBytes = 0, nRequestedBytes = 32768 /*32k*/;
|
|
uno::Sequence< sal_Int8 > seq( nRequestedBytes );
|
|
|
|
do
|
|
{
|
|
try
|
|
{
|
|
nReadBytes = aInputStream->readBytes( seq,
|
|
nRequestedBytes );
|
|
}
|
|
catch( const io::NotConnectedException& )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_NOTCONNECTED_FOR_WRITE );
|
|
bSuccess = sal_False;
|
|
break;
|
|
}
|
|
catch( const io::BufferSizeExceededException& )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE );
|
|
bSuccess = sal_False;
|
|
break;
|
|
}
|
|
catch( const io::IOException& )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_IOEXCEPTION_FOR_WRITE );
|
|
bSuccess = sal_False;
|
|
break;
|
|
}
|
|
|
|
if( nReadBytes )
|
|
{
|
|
const sal_Int8* p = seq.getConstArray();
|
|
|
|
err = aFile.write( ((void*)(p)),
|
|
sal_uInt64( nReadBytes ),
|
|
nWrittenBytes );
|
|
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FILEIOERROR_FOR_WRITE,
|
|
err );
|
|
bSuccess = sal_False;
|
|
break;
|
|
}
|
|
else if( nWrittenBytes != sal_uInt64( nReadBytes ) )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FILEIOERROR_FOR_NO_SPACE );
|
|
bSuccess = sal_False;
|
|
break;
|
|
}
|
|
}
|
|
} while( nReadBytes == nRequestedBytes );
|
|
|
|
aFile.sync(); // fsync / flush it to disk.
|
|
OSL_TRACE( "fsync'd file '%s'\n",
|
|
rtl::OUStringToOString( aUnqPath, RTL_TEXTENCODING_UTF8 ).getStr() );
|
|
|
|
err = aFile.close();
|
|
if( err != osl::FileBase::E_None )
|
|
{
|
|
installError( CommandId,
|
|
TASKHANDLING_FILEIOERROR_FOR_WRITE,
|
|
err );
|
|
bSuccess = sal_False;
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* insertDefaultProperties-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
|
|
|
|
void SAL_CALL shell::insertDefaultProperties( const rtl::OUString& aUnqPath )
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
ContentMap::iterator it =
|
|
m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
|
|
|
|
load( it,false );
|
|
|
|
MyProperty ContentTProperty( ContentType );
|
|
|
|
PropertySet& properties = *(it->second.properties);
|
|
sal_Bool ContentNotDefau = properties.find( ContentTProperty ) != properties.end();
|
|
|
|
shell::PropertySet::iterator it1 = m_aDefaultProperties.begin();
|
|
while( it1 != m_aDefaultProperties.end() )
|
|
{
|
|
if( ContentNotDefau && it1->getPropertyName() == ContentType )
|
|
{
|
|
// No insertion
|
|
}
|
|
else
|
|
properties.insert( *it1 );
|
|
++it1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
/* */
|
|
/* mapping of file urls */
|
|
/* to uncpath and vice versa */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
|
|
sal_Bool SAL_CALL shell::getUnqFromUrl( const rtl::OUString& Url,rtl::OUString& Unq )
|
|
{
|
|
if (Url.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file:///")) ||
|
|
Url.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file://localhost/")) ||
|
|
Url.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("file://127.0.0.1/")))
|
|
{
|
|
Unq = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///"));
|
|
return false;
|
|
}
|
|
|
|
sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Url,Unq );
|
|
|
|
Unq = Url;
|
|
|
|
sal_Int32 l = Unq.getLength()-1;
|
|
if( ! err && Unq.getStr()[ l ] == '/' &&
|
|
Unq.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) < l )
|
|
Unq = Unq.copy(0, Unq.getLength() - 1);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SAL_CALL shell::getUrlFromUnq( const rtl::OUString& Unq,rtl::OUString& Url )
|
|
{
|
|
sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Unq,Url );
|
|
|
|
Url = Unq;
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
// Helper function for public copy
|
|
|
|
osl::FileBase::RC SAL_CALL
|
|
shell::copy_recursive( const rtl::OUString& srcUnqPath,
|
|
const rtl::OUString& dstUnqPath,
|
|
sal_Int32 TypeToCopy,
|
|
sal_Bool testExistBeforeCopy )
|
|
throw()
|
|
{
|
|
osl::FileBase::RC err = osl::FileBase::E_None;
|
|
|
|
if( TypeToCopy == -1 ) // Document
|
|
{
|
|
err = osl_File_copy( srcUnqPath,dstUnqPath,testExistBeforeCopy );
|
|
}
|
|
else if( TypeToCopy == +1 ) // Folder
|
|
{
|
|
osl::Directory aDir( srcUnqPath );
|
|
aDir.open();
|
|
|
|
err = osl::Directory::create( dstUnqPath );
|
|
osl::FileBase::RC next = err;
|
|
if( err == osl::FileBase::E_None )
|
|
{
|
|
sal_Int32 n_Mask = osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Type;
|
|
|
|
osl::DirectoryItem aDirItem;
|
|
|
|
while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
|
|
{
|
|
sal_Bool IsDoc = false;
|
|
osl::FileStatus aFileStatus( n_Mask );
|
|
aDirItem.getFileStatus( aFileStatus );
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
|
|
IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
|
|
|
|
// Getting the information for the next recursive copy
|
|
sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
|
|
|
|
rtl::OUString newSrcUnqPath;
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
|
|
newSrcUnqPath = aFileStatus.getFileURL();
|
|
|
|
rtl::OUString newDstUnqPath = dstUnqPath;
|
|
rtl::OUString tit;
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
|
|
tit = rtl::Uri::encode( aFileStatus.getFileName(),
|
|
rtl_UriCharClassPchar,
|
|
rtl_UriEncodeIgnoreEscapes,
|
|
RTL_TEXTENCODING_UTF8 );
|
|
|
|
if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
|
|
newDstUnqPath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
|
|
|
|
newDstUnqPath += tit;
|
|
|
|
if ( newSrcUnqPath != dstUnqPath )
|
|
err = copy_recursive( newSrcUnqPath,newDstUnqPath,newTypeToCopy,false );
|
|
}
|
|
|
|
if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
|
|
err = next;
|
|
}
|
|
aDir.close();
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
// Helper function for mkfil,mkdir and write
|
|
// Creates whole path
|
|
// returns success of the operation
|
|
|
|
|
|
sal_Bool SAL_CALL shell::ensuredir( sal_Int32 CommandId,
|
|
const rtl::OUString& rUnqPath,
|
|
sal_Int32 errorCode )
|
|
throw()
|
|
{
|
|
rtl::OUString aPath;
|
|
|
|
if ( rUnqPath.isEmpty() )
|
|
return sal_False;
|
|
|
|
if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
|
|
aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
|
|
else
|
|
aPath = rUnqPath;
|
|
|
|
|
|
// HACK: create directory on a mount point with nobrowse option
|
|
// returns ENOSYS in any case !!
|
|
osl::Directory aDirectory( aPath );
|
|
osl::FileBase::RC nError = aDirectory.open();
|
|
aDirectory.close();
|
|
|
|
if( nError == osl::File::E_None )
|
|
return sal_True;
|
|
|
|
nError = osl::Directory::create( aPath );
|
|
|
|
if( nError == osl::File::E_None )
|
|
notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
|
|
|
|
sal_Bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
|
|
|
|
if( ! bSuccess )
|
|
{
|
|
rtl::OUString aParentDir = getParentName( aPath );
|
|
|
|
if ( aParentDir != aPath )
|
|
{ // Create first the parent directory
|
|
bSuccess = ensuredir( CommandId,
|
|
getParentName( aPath ),
|
|
errorCode );
|
|
|
|
// After parent directory structure exists try it one's more
|
|
|
|
if ( bSuccess )
|
|
{ // Parent directory exists, retry creation of directory
|
|
nError = osl::Directory::create( aPath );
|
|
|
|
if( nError == osl::File::E_None )
|
|
notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
|
|
|
|
bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( ! bSuccess )
|
|
installError( CommandId,
|
|
errorCode,
|
|
nError );
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Given a sequence of properties seq, this method determines the mask
|
|
// used to instantiate a osl::FileStatus, so that a call to
|
|
// osl::DirectoryItem::getFileStatus fills the required fields.
|
|
//
|
|
|
|
|
|
void SAL_CALL
|
|
shell::getMaskFromProperties(
|
|
sal_Int32& n_Mask,
|
|
const uno::Sequence< beans::Property >& seq )
|
|
{
|
|
n_Mask = 0;
|
|
for(sal_Int32 j = 0; j < seq.getLength(); ++j) {
|
|
if(seq[j].Name == Title)
|
|
n_Mask |= osl_FileStatus_Mask_FileName;
|
|
else if(seq[j].Name == CasePreservingURL)
|
|
n_Mask |= osl_FileStatus_Mask_FileURL;
|
|
else if(seq[j].Name == IsDocument ||
|
|
seq[j].Name == IsFolder ||
|
|
seq[j].Name == IsVolume ||
|
|
seq[j].Name == IsRemoveable ||
|
|
seq[j].Name == IsRemote ||
|
|
seq[j].Name == IsCompactDisc ||
|
|
seq[j].Name == IsFloppy ||
|
|
seq[j].Name == ContentType)
|
|
n_Mask |= (osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL);
|
|
else if(seq[j].Name == Size)
|
|
n_Mask |= (osl_FileStatus_Mask_FileSize |
|
|
osl_FileStatus_Mask_Type |
|
|
osl_FileStatus_Mask_LinkTargetURL);
|
|
else if(seq[j].Name == IsHidden ||
|
|
seq[j].Name == IsReadOnly)
|
|
n_Mask |= osl_FileStatus_Mask_Attributes;
|
|
else if(seq[j].Name == DateModified)
|
|
n_Mask |= osl_FileStatus_Mask_ModifyTime;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* load-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
//
|
|
// Load the properties from configuration, if create == true create them.
|
|
// The Properties are stored under the url belonging to it->first.
|
|
//
|
|
|
|
void SAL_CALL
|
|
shell::load( const ContentMap::iterator& it, sal_Bool create )
|
|
{
|
|
if( ! it->second.properties )
|
|
it->second.properties = new PropertySet;
|
|
|
|
if( ( ! it->second.xS.is() ||
|
|
! it->second.xC.is() ||
|
|
! it->second.xA.is() )
|
|
&& m_xFileRegistry.is() )
|
|
{
|
|
|
|
uno::Reference< ucb::XPersistentPropertySet > xS = m_xFileRegistry->openPropertySet( it->first,create );
|
|
if( xS.is() )
|
|
{
|
|
uno::Reference< beans::XPropertyContainer > xC( xS,uno::UNO_QUERY );
|
|
uno::Reference< beans::XPropertyAccess > xA( xS,uno::UNO_QUERY );
|
|
|
|
it->second.xS = xS;
|
|
it->second.xC = xC;
|
|
it->second.xA = xA;
|
|
|
|
// Now put in all values in the storage in the local hash;
|
|
|
|
PropertySet& properties = *(it->second.properties);
|
|
uno::Sequence< beans::Property > seq = xS->getPropertySetInfo()->getProperties();
|
|
|
|
for( sal_Int32 i = 0; i < seq.getLength(); ++i )
|
|
{
|
|
MyProperty readProp( false,
|
|
seq[i].Name,
|
|
seq[i].Handle,
|
|
seq[i].Type,
|
|
xS->getPropertyValue( seq[i].Name ),
|
|
beans::PropertyState_DIRECT_VALUE,
|
|
seq[i].Attributes );
|
|
if( properties.find( readProp ) == properties.end() )
|
|
properties.insert( readProp );
|
|
}
|
|
}
|
|
else if( create )
|
|
{
|
|
// Catastrophic error
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************/
|
|
/* */
|
|
/* commit-Implementation */
|
|
/* */
|
|
/*********************************************************************************/
|
|
// Commit inserts the determined properties in the filestatus object into
|
|
// the internal map, so that is possible to determine on a subsequent
|
|
// setting of file properties which properties have changed without filestat
|
|
|
|
|
|
void SAL_CALL
|
|
shell::commit( const shell::ContentMap::iterator& it,
|
|
const osl::FileStatus& aFileStatus )
|
|
{
|
|
uno::Any aAny;
|
|
uno::Any emptyAny;
|
|
shell::PropertySet::iterator it1;
|
|
|
|
if( it->second.properties == 0 )
|
|
{
|
|
rtl::OUString aPath = it->first;
|
|
insertDefaultProperties( aPath );
|
|
}
|
|
|
|
PropertySet& properties = *( it->second.properties );
|
|
|
|
it1 = properties.find( MyProperty( Title ) );
|
|
if( it1 != properties.end() )
|
|
{
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
|
|
{
|
|
aAny <<= aFileStatus.getFileName();
|
|
it1->setValue( aAny );
|
|
}
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( CasePreservingURL ) );
|
|
if( it1 != properties.end() )
|
|
{
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
|
|
{
|
|
aAny <<= aFileStatus.getFileURL();
|
|
it1->setValue( aAny );
|
|
}
|
|
}
|
|
|
|
|
|
sal_Bool isDirectory,isFile,isVolume,isRemoveable,isRemote,isFloppy,isCompactDisc;
|
|
|
|
sal_Int64 dirSize = 0;
|
|
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_FileSize ) )
|
|
dirSize = aFileStatus.getFileSize();
|
|
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
|
|
{
|
|
if( osl::FileStatus::Link == aFileStatus.getFileType() &&
|
|
aFileStatus.isValid( osl_FileStatus_Mask_LinkTargetURL ) )
|
|
{
|
|
osl::DirectoryItem aDirItem;
|
|
osl::FileStatus aFileStatus2( osl_FileStatus_Mask_Type );
|
|
if( osl::FileBase::E_None == osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(),aDirItem ) &&
|
|
osl::FileBase::E_None == aDirItem.getFileStatus( aFileStatus2 ) &&
|
|
aFileStatus2.isValid( osl_FileStatus_Mask_Type ) )
|
|
{
|
|
isVolume = osl::FileStatus::Volume == aFileStatus2.getFileType();
|
|
isDirectory =
|
|
osl::FileStatus::Volume == aFileStatus2.getFileType() ||
|
|
osl::FileStatus::Directory == aFileStatus2.getFileType();
|
|
isFile =
|
|
osl::FileStatus::Regular == aFileStatus2.getFileType();
|
|
|
|
if( aFileStatus2.isValid( osl_FileStatus_Mask_FileSize ) )
|
|
dirSize = aFileStatus2.getFileSize();
|
|
}
|
|
else
|
|
{
|
|
// extremly ugly, but otherwise default construction
|
|
// of aDirItem and aFileStatus2
|
|
// before the preciding if
|
|
isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
|
|
isDirectory =
|
|
osl::FileStatus::Volume == aFileStatus.getFileType() ||
|
|
osl::FileStatus::Directory == aFileStatus.getFileType();
|
|
isFile =
|
|
osl::FileStatus::Regular == aFileStatus.getFileType();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
|
|
isDirectory =
|
|
osl::FileStatus::Volume == aFileStatus.getFileType() ||
|
|
osl::FileStatus::Directory == aFileStatus.getFileType();
|
|
isFile =
|
|
osl::FileStatus::Regular == aFileStatus.getFileType();
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( IsVolume ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isVolume ) );
|
|
|
|
it1 = properties.find( MyProperty( IsFolder ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isDirectory ) );
|
|
|
|
it1 = properties.find( MyProperty( IsDocument ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isFile ) );
|
|
|
|
osl::VolumeInfo aVolumeInfo( osl_VolumeInfo_Mask_Attributes );
|
|
if( isVolume &&
|
|
osl::FileBase::E_None == osl::Directory::getVolumeInfo( it->first,aVolumeInfo ) &&
|
|
aVolumeInfo.isValid( osl_VolumeInfo_Mask_Attributes ) )
|
|
{
|
|
// Retrieve the flags;
|
|
isRemote = aVolumeInfo.getRemoteFlag();
|
|
isRemoveable = aVolumeInfo.getRemoveableFlag();
|
|
isCompactDisc = aVolumeInfo.getCompactDiscFlag();
|
|
isFloppy = aVolumeInfo.getFloppyDiskFlag();
|
|
|
|
it1 = properties.find( MyProperty( IsRemote ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isRemote ) );
|
|
|
|
it1 = properties.find( MyProperty( IsRemoveable ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isRemoveable ) );
|
|
|
|
it1 = properties.find( MyProperty( IsCompactDisc ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isCompactDisc ) );
|
|
|
|
it1 = properties.find( MyProperty( IsFloppy ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( isFloppy ) );
|
|
}
|
|
else
|
|
{
|
|
sal_Bool dummy = false;
|
|
aAny <<= dummy;
|
|
it1 = properties.find( MyProperty( IsRemote ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( aAny );
|
|
|
|
it1 = properties.find( MyProperty( IsRemoveable ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( aAny );
|
|
|
|
it1 = properties.find( MyProperty( IsCompactDisc ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( aAny );
|
|
|
|
it1 = properties.find( MyProperty( IsFloppy ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( aAny );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isDirectory = sal_False;
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( Size ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny( dirSize ) );
|
|
|
|
it1 = properties.find( MyProperty( IsReadOnly ) );
|
|
if( it1 != properties.end() )
|
|
{
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
|
|
{
|
|
sal_uInt64 Attr = aFileStatus.getAttributes();
|
|
sal_Bool readonly = ( Attr & osl_File_Attribute_ReadOnly ) != 0;
|
|
it1->setValue( uno::makeAny( readonly ) );
|
|
}
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( IsHidden ) );
|
|
if( it1 != properties.end() )
|
|
{
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
|
|
{
|
|
sal_uInt64 Attr = aFileStatus.getAttributes();
|
|
sal_Bool ishidden = ( Attr & osl_File_Attribute_Hidden ) != 0;
|
|
it1->setValue( uno::makeAny( ishidden ) );
|
|
}
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( DateModified ) );
|
|
if( it1 != properties.end() )
|
|
{
|
|
if( aFileStatus.isValid( osl_FileStatus_Mask_ModifyTime ) )
|
|
{
|
|
TimeValue temp = aFileStatus.getModifyTime();
|
|
|
|
// Convert system time to local time (for EA)
|
|
TimeValue myLocalTime;
|
|
osl_getLocalTimeFromSystemTime( &temp, &myLocalTime );
|
|
|
|
oslDateTime myDateTime;
|
|
osl_getDateTimeFromTimeValue( &myLocalTime, &myDateTime );
|
|
util::DateTime aDateTime;
|
|
|
|
aDateTime.HundredthSeconds = (unsigned short)(myDateTime.NanoSeconds / 10000000);
|
|
aDateTime.Seconds = myDateTime.Seconds;
|
|
aDateTime.Minutes = myDateTime.Minutes;
|
|
aDateTime.Hours = myDateTime.Hours;
|
|
aDateTime.Day = myDateTime.Day;
|
|
aDateTime.Month = myDateTime.Month;
|
|
aDateTime.Year = myDateTime.Year;
|
|
it1->setValue( uno::makeAny( aDateTime ) );
|
|
}
|
|
}
|
|
|
|
it1 = properties.find( MyProperty( CreatableContentsInfo ) );
|
|
if( it1 != properties.end() )
|
|
it1->setValue( uno::makeAny(
|
|
isDirectory || !aFileStatus.isValid( osl_FileStatus_Mask_Type )
|
|
? queryCreatableContentsInfo()
|
|
: uno::Sequence< ucb::ContentInfo >() ) );
|
|
}
|
|
|
|
|
|
// Special optimized method for getting the properties of a
|
|
// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
|
|
|
|
|
|
uno::Reference< sdbc::XRow > SAL_CALL
|
|
shell::getv(
|
|
Notifier* pNotifier,
|
|
const uno::Sequence< beans::Property >& properties,
|
|
osl::DirectoryItem& aDirItem,
|
|
rtl::OUString& aUnqPath,
|
|
sal_Bool& aIsRegular )
|
|
{
|
|
uno::Sequence< uno::Any > seq( properties.getLength() );
|
|
|
|
sal_Int32 n_Mask;
|
|
getMaskFromProperties( n_Mask,properties );
|
|
|
|
// Always retrieve the type and the target URL because item might be a link
|
|
osl::FileStatus aFileStatus( n_Mask |
|
|
osl_FileStatus_Mask_FileURL |
|
|
osl_FileStatus_Mask_Type |
|
|
osl_FileStatus_Mask_LinkTargetURL );
|
|
aDirItem.getFileStatus( aFileStatus );
|
|
aUnqPath = aFileStatus.getFileURL();
|
|
|
|
// If the directory item type is a link retrieve the type of the target
|
|
|
|
if ( aFileStatus.getFileType() == osl::FileStatus::Link )
|
|
{
|
|
// Assume failure
|
|
aIsRegular = false;
|
|
osl::FileBase::RC result = osl::FileBase::E_INVAL;
|
|
osl::DirectoryItem aTargetItem;
|
|
osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
|
|
if ( aTargetItem.is() )
|
|
{
|
|
osl::FileStatus aTargetStatus( osl_FileStatus_Mask_Type );
|
|
|
|
if ( osl::FileBase::E_None ==
|
|
( result = aTargetItem.getFileStatus( aTargetStatus ) ) )
|
|
aIsRegular =
|
|
aTargetStatus.getFileType() == osl::FileStatus::Regular;
|
|
}
|
|
}
|
|
else
|
|
aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
|
|
|
|
registerNotifier( aUnqPath,pNotifier );
|
|
insertDefaultProperties( aUnqPath );
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
|
|
commit( it,aFileStatus );
|
|
|
|
shell::PropertySet::iterator it1;
|
|
PropertySet& propset = *(it->second.properties);
|
|
|
|
for( sal_Int32 i = 0; i < seq.getLength(); ++i )
|
|
{
|
|
MyProperty readProp( properties[i].Name );
|
|
it1 = propset.find( readProp );
|
|
if( it1 == propset.end() )
|
|
seq[i] = uno::Any();
|
|
else
|
|
seq[i] = it1->getValue();
|
|
}
|
|
}
|
|
deregisterNotifier( aUnqPath,pNotifier );
|
|
|
|
XRow_impl* p = new XRow_impl( this,seq );
|
|
return uno::Reference< sdbc::XRow >( p );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// EventListener
|
|
|
|
|
|
std::list< ContentEventNotifier* >* SAL_CALL
|
|
shell::getContentEventListeners( const rtl::OUString& aName )
|
|
{
|
|
std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
|
|
std::list< ContentEventNotifier* >& listeners = *p;
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
shell::ContentMap::iterator it = m_aContent.find( aName );
|
|
if( it != m_aContent.end() && it->second.notifier )
|
|
{
|
|
std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
|
|
std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
|
|
while( it1 != listOfNotifiers.end() )
|
|
{
|
|
Notifier* pointer = *it1;
|
|
ContentEventNotifier* notifier = pointer->cCEL();
|
|
if( notifier )
|
|
listeners.push_back( notifier );
|
|
++it1;
|
|
}
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
std::list< ContentEventNotifier* >* SAL_CALL
|
|
shell::getContentDeletedEventListeners( const rtl::OUString& aName )
|
|
{
|
|
std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
|
|
std::list< ContentEventNotifier* >& listeners = *p;
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
shell::ContentMap::iterator it = m_aContent.find( aName );
|
|
if( it != m_aContent.end() && it->second.notifier )
|
|
{
|
|
std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
|
|
std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
|
|
while( it1 != listOfNotifiers.end() )
|
|
{
|
|
Notifier* pointer = *it1;
|
|
ContentEventNotifier* notifier = pointer->cDEL();
|
|
if( notifier )
|
|
listeners.push_back( notifier );
|
|
++it1;
|
|
}
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyInsert( std::list< ContentEventNotifier* >* listeners,const rtl::OUString& aChildName )
|
|
{
|
|
std::list< ContentEventNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyChildInserted( aChildName );
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyContentDeleted( std::list< ContentEventNotifier* >* listeners )
|
|
{
|
|
std::list< ContentEventNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyDeleted();
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyContentRemoved( std::list< ContentEventNotifier* >* listeners,
|
|
const rtl::OUString& aChildName )
|
|
{
|
|
std::list< ContentEventNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyRemoved( aChildName );
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
|
|
|
|
std::list< PropertySetInfoChangeNotifier* >* SAL_CALL
|
|
shell::getPropertySetListeners( const rtl::OUString& aName )
|
|
{
|
|
std::list< PropertySetInfoChangeNotifier* >* p = new std::list< PropertySetInfoChangeNotifier* >;
|
|
std::list< PropertySetInfoChangeNotifier* >& listeners = *p;
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
shell::ContentMap::iterator it = m_aContent.find( aName );
|
|
if( it != m_aContent.end() && it->second.notifier )
|
|
{
|
|
std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
|
|
std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
|
|
while( it1 != listOfNotifiers.end() )
|
|
{
|
|
Notifier* pointer = *it1;
|
|
PropertySetInfoChangeNotifier* notifier = pointer->cPSL();
|
|
if( notifier )
|
|
listeners.push_back( notifier );
|
|
++it1;
|
|
}
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyPropertyAdded( std::list< PropertySetInfoChangeNotifier* >* listeners,
|
|
const rtl::OUString& aPropertyName )
|
|
{
|
|
std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyPropertyAdded( aPropertyName );
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyPropertyRemoved( std::list< PropertySetInfoChangeNotifier* >* listeners,
|
|
const rtl::OUString& aPropertyName )
|
|
{
|
|
std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyPropertyRemoved( aPropertyName );
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
|
|
std::vector< std::list< ContentEventNotifier* >* >* SAL_CALL
|
|
shell::getContentExchangedEventListeners( const rtl::OUString aOldPrefix,
|
|
const rtl::OUString aNewPrefix,
|
|
sal_Bool withChildren )
|
|
{
|
|
|
|
std::vector< std::list< ContentEventNotifier* >* >* aVectorOnHeap =
|
|
new std::vector< std::list< ContentEventNotifier* >* >;
|
|
std::vector< std::list< ContentEventNotifier* >* >& aVector = *aVectorOnHeap;
|
|
|
|
sal_Int32 count;
|
|
rtl::OUString aOldName;
|
|
rtl::OUString aNewName;
|
|
std::vector< rtl::OUString > oldChildList;
|
|
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
if( ! withChildren )
|
|
{
|
|
aOldName = aOldPrefix;
|
|
aNewName = aNewPrefix;
|
|
count = 1;
|
|
}
|
|
else
|
|
{
|
|
ContentMap::iterator itnames = m_aContent.begin();
|
|
while( itnames != m_aContent.end() )
|
|
{
|
|
if( isChild( aOldPrefix,itnames->first ) )
|
|
{
|
|
oldChildList.push_back( itnames->first );
|
|
}
|
|
++itnames;
|
|
}
|
|
count = oldChildList.size();
|
|
}
|
|
|
|
|
|
for( sal_Int32 j = 0; j < count; ++j )
|
|
{
|
|
std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
|
|
std::list< ContentEventNotifier* >& listeners = *p;
|
|
|
|
if( withChildren )
|
|
{
|
|
aOldName = oldChildList[j];
|
|
aNewName = newName( aNewPrefix,aOldPrefix,aOldName );
|
|
}
|
|
|
|
shell::ContentMap::iterator itold = m_aContent.find( aOldName );
|
|
if( itold != m_aContent.end() )
|
|
{
|
|
shell::ContentMap::iterator itnew = m_aContent.insert(
|
|
ContentMap::value_type( aNewName,UnqPathData() ) ).first;
|
|
|
|
// copy Ownership also
|
|
delete itnew->second.properties;
|
|
itnew->second.properties = itold->second.properties;
|
|
itold->second.properties = 0;
|
|
|
|
// copy existing list
|
|
std::list< Notifier* >* copyList = itnew->second.notifier;
|
|
itnew->second.notifier = itold->second.notifier;
|
|
itold->second.notifier = 0;
|
|
|
|
m_aContent.erase( itold );
|
|
|
|
if( itnew != m_aContent.end() && itnew->second.notifier )
|
|
{
|
|
std::list<Notifier*>& listOfNotifiers = *( itnew->second.notifier );
|
|
std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
|
|
while( it1 != listOfNotifiers.end() )
|
|
{
|
|
Notifier* pointer = *it1;
|
|
ContentEventNotifier* notifier = pointer->cEXC( aNewName );
|
|
if( notifier )
|
|
listeners.push_back( notifier );
|
|
++it1;
|
|
}
|
|
}
|
|
|
|
// Merge with preexisting notifiers
|
|
// However, these may be in status BaseContent::Deleted
|
|
if( copyList != 0 )
|
|
{
|
|
std::list< Notifier* >::iterator copyIt = copyList->begin();
|
|
while( copyIt != copyList->end() )
|
|
{
|
|
itnew->second.notifier->push_back( *copyIt );
|
|
++copyIt;
|
|
}
|
|
}
|
|
delete copyList;
|
|
}
|
|
aVector.push_back( p );
|
|
}
|
|
}
|
|
|
|
return aVectorOnHeap;
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL
|
|
shell::notifyContentExchanged( std::vector< std::list< ContentEventNotifier* >* >* listeners_vec )
|
|
{
|
|
std::list< ContentEventNotifier* >* listeners;
|
|
for( sal_uInt32 i = 0; i < listeners_vec->size(); ++i )
|
|
{
|
|
listeners = (*listeners_vec)[i];
|
|
std::list< ContentEventNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyExchanged();
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
delete listeners_vec;
|
|
}
|
|
|
|
|
|
|
|
std::list< PropertyChangeNotifier* >* SAL_CALL
|
|
shell::getPropertyChangeNotifier( const rtl::OUString& aName )
|
|
{
|
|
std::list< PropertyChangeNotifier* >* p = new std::list< PropertyChangeNotifier* >;
|
|
std::list< PropertyChangeNotifier* >& listeners = *p;
|
|
{
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
shell::ContentMap::iterator it = m_aContent.find( aName );
|
|
if( it != m_aContent.end() && it->second.notifier )
|
|
{
|
|
std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
|
|
std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
|
|
while( it1 != listOfNotifiers.end() )
|
|
{
|
|
Notifier* pointer = *it1;
|
|
PropertyChangeNotifier* notifier = pointer->cPCL();
|
|
if( notifier )
|
|
listeners.push_back( notifier );
|
|
++it1;
|
|
}
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
void SAL_CALL shell::notifyPropertyChanges( std::list< PropertyChangeNotifier* >* listeners,
|
|
const uno::Sequence< beans::PropertyChangeEvent >& seqChanged )
|
|
{
|
|
std::list< PropertyChangeNotifier* >::iterator it = listeners->begin();
|
|
while( it != listeners->end() )
|
|
{
|
|
(*it)->notifyPropertyChanged( seqChanged );
|
|
delete (*it);
|
|
++it;
|
|
}
|
|
delete listeners;
|
|
}
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* remove persistent propertyset */
|
|
/********************************************************************************/
|
|
|
|
void SAL_CALL
|
|
shell::erasePersistentSet( const rtl::OUString& aUnqPath,
|
|
sal_Bool withChildren )
|
|
{
|
|
if( ! m_xFileRegistry.is() )
|
|
{
|
|
OSL_ASSERT( m_xFileRegistry.is() );
|
|
return;
|
|
}
|
|
|
|
uno::Sequence< rtl::OUString > seqNames;
|
|
|
|
if( withChildren )
|
|
{
|
|
uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
|
|
seqNames = xName->getElementNames();
|
|
}
|
|
|
|
sal_Int32 count = withChildren ? seqNames.getLength() : 1;
|
|
|
|
rtl::OUString
|
|
old_Name = aUnqPath;
|
|
|
|
for( sal_Int32 j = 0; j < count; ++j )
|
|
{
|
|
if( withChildren && ! ( isChild( old_Name,seqNames[j] ) ) )
|
|
continue;
|
|
|
|
if( withChildren )
|
|
{
|
|
old_Name = seqNames[j];
|
|
}
|
|
|
|
{
|
|
// Release possible references
|
|
osl::MutexGuard aGuard( m_aMutex );
|
|
ContentMap::iterator it = m_aContent.find( old_Name );
|
|
if( it != m_aContent.end() )
|
|
{
|
|
it->second.xS = 0;
|
|
it->second.xC = 0;
|
|
it->second.xA = 0;
|
|
|
|
delete it->second.properties;
|
|
it->second.properties = 0;
|
|
}
|
|
}
|
|
|
|
if( m_xFileRegistry.is() )
|
|
m_xFileRegistry->removePropertySet( old_Name );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
/* copy persistent propertyset */
|
|
/* from srcUnqPath to dstUnqPath */
|
|
/********************************************************************************/
|
|
|
|
|
|
void SAL_CALL
|
|
shell::copyPersistentSet( const rtl::OUString& srcUnqPath,
|
|
const rtl::OUString& dstUnqPath,
|
|
sal_Bool withChildren )
|
|
{
|
|
if( ! m_xFileRegistry.is() )
|
|
{
|
|
OSL_ASSERT( m_xFileRegistry.is() );
|
|
return;
|
|
}
|
|
|
|
uno::Sequence< rtl::OUString > seqNames;
|
|
|
|
if( withChildren )
|
|
{
|
|
uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
|
|
seqNames = xName->getElementNames();
|
|
}
|
|
|
|
sal_Int32 count = withChildren ? seqNames.getLength() : 1;
|
|
|
|
rtl::OUString
|
|
old_Name = srcUnqPath,
|
|
new_Name = dstUnqPath;
|
|
|
|
for( sal_Int32 j = 0; j < count; ++j )
|
|
{
|
|
if( withChildren && ! ( isChild( srcUnqPath,seqNames[j] ) ) )
|
|
continue;
|
|
|
|
if( withChildren )
|
|
{
|
|
old_Name = seqNames[j];
|
|
new_Name = newName( dstUnqPath,srcUnqPath,old_Name );
|
|
}
|
|
|
|
uno::Reference< XPersistentPropertySet > x_src;
|
|
|
|
if( m_xFileRegistry.is() )
|
|
{
|
|
x_src = m_xFileRegistry->openPropertySet( old_Name,false );
|
|
m_xFileRegistry->removePropertySet( new_Name );
|
|
}
|
|
|
|
if( x_src.is() )
|
|
{
|
|
uno::Sequence< beans::Property > seqProperty =
|
|
x_src->getPropertySetInfo()->getProperties();
|
|
|
|
if( seqProperty.getLength() )
|
|
{
|
|
uno::Reference< XPersistentPropertySet >
|
|
x_dstS = m_xFileRegistry->openPropertySet( new_Name,true );
|
|
uno::Reference< beans::XPropertyContainer >
|
|
x_dstC( x_dstS,uno::UNO_QUERY );
|
|
|
|
for( sal_Int32 i = 0; i < seqProperty.getLength(); ++i )
|
|
{
|
|
x_dstC->addProperty( seqProperty[i].Name,
|
|
seqProperty[i].Attributes,
|
|
x_src->getPropertyValue( seqProperty[i].Name ) );
|
|
}
|
|
}
|
|
}
|
|
} // end for( sal_Int...
|
|
}
|
|
|
|
uno::Sequence< ucb::ContentInfo > shell::queryCreatableContentsInfo()
|
|
{
|
|
uno::Sequence< ucb::ContentInfo > seq(2);
|
|
|
|
// file
|
|
seq[0].Type = FileContentType;
|
|
seq[0].Attributes = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
|
|
| ucb::ContentInfoAttribute::KIND_DOCUMENT;
|
|
|
|
uno::Sequence< beans::Property > props( 1 );
|
|
props[0] = beans::Property(
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
|
|
-1,
|
|
getCppuType( static_cast< rtl::OUString* >( 0 ) ),
|
|
beans::PropertyAttribute::MAYBEVOID
|
|
| beans::PropertyAttribute::BOUND );
|
|
seq[0].Properties = props;
|
|
|
|
// folder
|
|
seq[1].Type = FolderContentType;
|
|
seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
|
|
seq[1].Properties = props;
|
|
return seq;
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
/* */
|
|
/* some misceancellous static functions */
|
|
/* */
|
|
/*******************************************************************************/
|
|
|
|
void SAL_CALL
|
|
shell::getScheme( rtl::OUString& Scheme )
|
|
{
|
|
Scheme = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file"));
|
|
}
|
|
|
|
rtl::OUString SAL_CALL
|
|
shell::getImplementationName_static( void )
|
|
{
|
|
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ucb.FileProvider"));
|
|
}
|
|
|
|
|
|
uno::Sequence< rtl::OUString > SAL_CALL
|
|
shell::getSupportedServiceNames_static( void )
|
|
{
|
|
rtl::OUString Supported(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.FileContentProvider"));
|
|
com::sun::star::uno::Sequence< rtl::OUString > Seq( &Supported,1 );
|
|
return Seq;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|