Kaydet (Commit) f797fe11 authored tarafından Vladimir Glazounov's avatar Vladimir Glazounov

INTEGRATION: CWS ucpgio1 (1.1.2); FILE ADDED

2008/04/30 16:35:18 cmc 1.1.2.1: #i88090# add gio content provider
üst 725290a5
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_content.cxx,v $
* $Revision: 1.2 $
*
* 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 <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <osl/time.h>
#include <osl/diagnose.h>
#include <osl/doublecheckedlocking.h>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/PropertySetInfoChange.hpp>
#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/lang/IllegalAccessException.hpp>
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
#include <com/sun/star/ucb/NameClash.hpp>
#include <com/sun/star/ucb/NameClashException.hpp>
#include <com/sun/star/ucb/OpenMode.hpp>
#include <com/sun/star/ucb/PostCommandArgument2.hpp>
#include <com/sun/star/ucb/XCommandInfo.hpp>
#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
#include <com/sun/star/ucb/MissingInputStreamException.hpp>
#include <com/sun/star/ucb/MissingPropertiesException.hpp>
#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
#include <com/sun/star/ucb/NameClashException.hpp>
#include <com/sun/star/ucb/XDynamicResultSet.hpp>
#include <com/sun/star/ucb/XContentCreator.hpp>
#include <ucbhelper/contentidentifier.hxx>
#include <ucbhelper/propertyvalueset.hxx>
#include <ucbhelper/interactionrequest.hxx>
#include <ucbhelper/cancelcommandexecution.hxx>
#include <osl/conditn.hxx>
#include "gio_content.hxx"
#include "gio_provider.hxx"
#include "gio_resultset.hxx"
#include "gio_inputstream.hxx"
#include "gio_outputstream.hxx"
#include "gio_mount.hxx"
#include <stdio.h>
using namespace com::sun::star;
namespace gio
{
Content::Content(
const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
ContentProvider* pProvider,
const uno::Reference< ucb::XContentIdentifier >& Identifier)
throw ( ucb::ContentCreationException )
: ContentImplHelper( rxSMgr, pProvider, Identifier ),
m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(false)
{
#ifdef DEBUG
fprintf(stderr, "New Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
#endif
}
Content::Content(
const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
ContentProvider* pProvider,
const uno::Reference< ucb::XContentIdentifier >& Identifier,
sal_Bool bIsFolder)
throw ( ucb::ContentCreationException )
: ContentImplHelper( rxSMgr, pProvider, Identifier ),
m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(true)
{
#ifdef DEBUG
fprintf(stderr, "Create Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
#endif
mpInfo = g_file_info_new();
g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
}
Content::~Content()
{
if (mpInfo) g_object_unref(mpInfo);
if (mpFile) g_object_unref(mpFile);
}
rtl::OUString Content::getParentURL()
{
rtl::OUString sURL;
if (GFile* pFile = g_file_get_parent(getGFile()))
{
char* pPath = g_file_get_uri(pFile);
g_object_unref(pFile);
sURL = rtl::OUString::createFromAscii(pPath);
g_free(pPath);
}
return sURL;
}
void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
throw( uno::RuntimeException )
{
//TODO
//stick a map from each CommandId to a new GCancellable and propogate
//it throughout the g_file_* calls
}
rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException )
{
return isFolder(uno::Reference< ucb::XCommandEnvironment >())
? rtl::OUString::createFromAscii( GIO_FOLDER_TYPE )
: rtl::OUString::createFromAscii( GIO_FILE_TYPE );
}
#define EXCEPT(aExcept) \
do { \
if (bThrow) throw aExcept;\
aRet = uno::makeAny( aExcept );\
} while(0)
uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
{
uno::Any aRet;
gint eCode = pError->code;
rtl::OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
g_error_free(pError);
rtl::OUString sName;
rtl::OUString sHost;
uno::Sequence< uno::Any > aArgs( 1 );
aArgs[ 0 ] <<= sName;
switch (eCode)
{
case G_IO_ERROR_FAILED:
{ io::IOException aExcept(sMessage, rContext);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NOT_MOUNTED:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NOT_FOUND:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_EXISTS:
{ ucb::NameClashException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, sName);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_INVALID_ARGUMENT:
{ lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
EXCEPT(aExcept); }
break;
case G_IO_ERROR_PERMISSION_DENIED:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_IS_DIRECTORY:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NOT_REGULAR_FILE:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NOT_DIRECTORY:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_FILENAME_TOO_LONG:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_PENDING:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_CLOSED:
case G_IO_ERROR_CANCELLED:
case G_IO_ERROR_TOO_MANY_LINKS:
case G_IO_ERROR_WRONG_ETAG:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NOT_SUPPORTED:
case G_IO_ERROR_CANT_CREATE_BACKUP:
case G_IO_ERROR_WOULD_MERGE:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_NO_SPACE:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_INVALID_FILENAME:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_READ_ONLY:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_TIMED_OUT:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_WOULD_RECURSE:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_BUSY:
case G_IO_ERROR_WOULD_BLOCK:
{ ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, ucb::IOErrorCode_LOCKING_VIOLATION, aArgs);
EXCEPT(aExcept); }
break;
case G_IO_ERROR_HOST_NOT_FOUND:
{ ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR, sHost);
EXCEPT(aExcept);}
break;
default:
case G_IO_ERROR_ALREADY_MOUNTED:
case G_IO_ERROR_NOT_EMPTY:
case G_IO_ERROR_NOT_SYMBOLIC_LINK:
case G_IO_ERROR_NOT_MOUNTABLE_FILE:
case G_IO_ERROR_FAILED_HANDLED:
{ ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
task::InteractionClassification_ERROR);
EXCEPT(aExcept);}
break;
}
return aRet;
}
uno::Any Content::mapGIOError( GError *pError )
{
if (!pError)
return getBadArgExcept();
return convertToException(pError, static_cast< cppu::OWeakObject * >(this), false);
}
uno::Any Content::getBadArgExcept()
{
return uno::makeAny( lang::IllegalArgumentException(
rtl::OUString::createFromAscii( "Wrong argument type!" ),
static_cast< cppu::OWeakObject * >( this ), -1) );
}
class MountOperation
{
GMainLoop *mpLoop;
GMountOperation *mpAuthentication;
GError *mpError;
static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
public:
MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
~MountOperation();
GError *Mount(GFile *pFile);
};
MountOperation::MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv) : mpError(NULL)
{
mpLoop = g_main_loop_new(NULL, FALSE);
mpAuthentication = ooo_mount_operation_new(xEnv);
}
void MountOperation::Completed(GObject *source, GAsyncResult *res, gpointer user_data)
{
MountOperation *pThis = (MountOperation*)user_data;
g_file_mount_enclosing_volume_finish(G_FILE(source), res, &(pThis->mpError));
g_main_loop_quit(pThis->mpLoop);
}
GError *MountOperation::Mount(GFile *pFile)
{
g_file_mount_enclosing_volume(pFile, G_MOUNT_MOUNT_NONE, mpAuthentication, NULL, MountOperation::Completed, this);
g_main_loop_run(mpLoop);
return mpError;
}
MountOperation::~MountOperation()
{
g_object_unref(mpAuthentication);
g_main_loop_unref(mpLoop);
}
GFileInfo* Content::getGFileInfo(const uno::Reference< ucb::XCommandEnvironment >& xEnv, GError **ppError)
{
/*If we don't have it already, and we're not a "pre-creation" content then query for the info"*/
if (!mpInfo && !mbTransient)
{
if (!(mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError)))
{
//Try and mount if unmounted
if (ppError && (*ppError)->code == G_IO_ERROR_NOT_MOUNTED)
{
g_error_free(*ppError);
MountOperation aMounter(xEnv);
*ppError = aMounter.Mount(getGFile());
//No Mount error, reattempt query
if (!*ppError)
mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError);
}
}
}
return mpInfo;
}
GFile* Content::getGFile()
{
if (!mpFile)
mpFile = g_file_new_for_uri(rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
return mpFile;
}
bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv)
{
GFileInfo *pInfo = getGFileInfo(xEnv);
return pInfo && (g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY);
}
static util::DateTime getDateFromUnix (time_t t)
{
TimeValue tv;
tv.Nanosec = 0;
tv.Seconds = t;
oslDateTime dt;
if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
dt.Day, dt.Month, dt.Year);
else
return util::DateTime();
}
uno::Reference< sdbc::XRow > Content::getPropertyValuesFromGFileInfo(GFileInfo *pInfo,
const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
const uno::Sequence< beans::Property >& rProperties)
{
rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rSMgr );
sal_Int32 nProps;
const beans::Property* pProps;
nProps = rProperties.getLength();
pProps = rProperties.getConstArray();
for( sal_Int32 n = 0; n < nProps; ++n )
{
const beans::Property& rProp = pProps[ n ];
if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
{
if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE))
xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_REGULAR ||
g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_UNKNOWN ) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) )
xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_DIRECTORY ));
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
{
if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
{
const char *pName = g_file_info_get_display_name(pInfo);
xRow->appendString( rProp, rtl::OUString(pName, strlen(pName), RTL_TEXTENCODING_UTF8) );
}
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) )
xRow->appendBoolean( rProp, !g_file_info_get_attribute_boolean( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CREATED ) )
xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CREATED)) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED ) )
xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED)) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE) )
xRow->appendLong( rProp, ( g_file_info_get_size( pInfo ) ));
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) )
{
//What do we use this for ?
xRow->appendBoolean( rProp, sal_False );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisc" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT ) )
xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsRemoveable" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) )
xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) );
else
xRow->appendVoid( rProp );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFloppy" ) ) )
{
xRow->appendBoolean( rProp, sal_False );
}
else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
{
if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) )
xRow->appendBoolean( rProp, ( g_file_info_get_is_hidden ( pInfo ) ) );
else
xRow->appendVoid( rProp );
}
#ifdef DEBUG
else
{
fprintf(stderr, "Looking for unsupported property %s\n",
rtl::OUStringToOString(rProp.Name, RTL_TEXTENCODING_UTF8).getStr());
}
#endif
}
return uno::Reference< sdbc::XRow >( xRow.get() );
}
uno::Reference< sdbc::XRow > Content::getPropertyValues(
const uno::Sequence< beans::Property >& rProperties,
const uno::Reference< ucb::XCommandEnvironment >& xEnv )
{
GError *pError = NULL;
GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
if (!pInfo)
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
return getPropertyValuesFromGFileInfo(pInfo, m_xSMgr, rProperties);
}
static lang::IllegalAccessException
getReadOnlyException( const uno::Reference< uno::XInterface >& rContext )
{
return lang::IllegalAccessException ( rtl::OUString::createFromAscii( "Property is read-only!" ), rContext );
}
void Content::queryChildren( ContentRefList& rChildren )
{
// Obtain a list with a snapshot of all currently instanciated contents
// from provider and extract the contents which are direct children
// of this content.
ucbhelper::ContentRefList aAllContents;
m_xProvider->queryExistingContents( aAllContents );
rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
if ( nURLPos != ( aURL.getLength() - 1 ) )
aURL += rtl::OUString::createFromAscii( "/" );
sal_Int32 nLen = aURL.getLength();
ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
while ( it != end )
{
ucbhelper::ContentImplHelperRef xChild = (*it);
rtl::OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
// Is aURL a prefix of aChildURL?
if ( ( aChildURL.getLength() > nLen ) && ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
{
sal_Int32 nPos = nLen;
nPos = aChildURL.indexOf( '/', nPos );
if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) )
{
// No further slashes / only a final slash. It's a child!
rChildren.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content * >(xChild.get() ) ) );
}
}
++it;
}
}
sal_Bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
{
if ( !xNewId.is() )
return sal_False;
uno::Reference< ucb::XContent > xThis = this;
if ( mbTransient )
{
m_xIdentifier = xNewId;
return sal_False;
}
rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
// Exchange own identitity.
if ( exchange( xNewId ) )
{
// Process instanciated children...
ContentRefList aChildren;
queryChildren( aChildren );
ContentRefList::const_iterator it = aChildren.begin();
ContentRefList::const_iterator end = aChildren.end();
while ( it != end )
{
ContentRef xChild = (*it);
// Create new content identifier for the child...
uno::Reference< ucb::XContentIdentifier > xOldChildId = xChild->getIdentifier();
rtl::OUString aOldChildURL = xOldChildId->getContentIdentifier();
rtl::OUString aNewChildURL = aOldChildURL.replaceAt(
0, aOldURL.getLength(), xNewId->getContentIdentifier() );
uno::Reference< ucb::XContentIdentifier > xNewChildId
= new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL );
if ( !xChild->exchangeIdentity( xNewChildId ) )
return sal_False;
++it;
}
return sal_True;
}
return sal_False;
}
uno::Sequence< uno::Any > Content::setPropertyValues(
const uno::Sequence< beans::PropertyValue >& rValues,
const uno::Reference< ucb::XCommandEnvironment >& xEnv )
{
GError *pError=NULL;
GFileInfo *pNewInfo=NULL;
GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
if (pInfo)
pNewInfo = g_file_info_dup(pInfo);
else
{
if (!mbTransient)
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
else
{
if (pError)
g_error_free(pError);
pNewInfo = g_file_info_new();
}
}
sal_Int32 nCount = rValues.getLength();
beans::PropertyChangeEvent aEvent;
aEvent.Source = static_cast< cppu::OWeakObject * >( this );
aEvent.Further = sal_False;
aEvent.PropertyHandle = -1;
sal_Int32 nChanged = 0, nTitlePos = -1;
const char *newName = NULL;
uno::Sequence< beans::PropertyChangeEvent > aChanges(nCount);
uno::Sequence< uno::Any > aRet( nCount );
const beans::PropertyValue* pValues = rValues.getConstArray();
for ( sal_Int32 n = 0; n < nCount; ++n )
{
const beans::PropertyValue& rValue = pValues[ n ];
#ifdef DEBUG
g_warning("Set prop '%s'", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
#endif
if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
{
aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
}
else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
{
rtl::OUString aNewTitle;
if (!( rValue.Value >>= aNewTitle ))
{
aRet[ n ] <<= beans::IllegalTypeException
( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
static_cast< cppu::OWeakObject * >( this ) );
continue;
}
if ( aNewTitle.getLength() <= 0 )
{
aRet[ n ] <<= lang::IllegalArgumentException
( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
static_cast< cppu::OWeakObject * >( this ), -1 );
continue;
}
rtl::OString sNewTitle = OUStringToOString(aNewTitle, RTL_TEXTENCODING_UTF8);
newName = sNewTitle.getStr();
const char *oldName = g_file_info_get_name( pInfo);
if (!newName || !oldName || strcmp(newName, oldName))
{
#ifdef DEBUG
g_warning ("Set new name to '%s'", newName);
#endif
aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
if (oldName)
aEvent.OldValue = uno::makeAny(rtl::OUString(oldName, strlen(oldName), RTL_TEXTENCODING_UTF8));
aEvent.NewValue = uno::makeAny(aNewTitle);
aChanges.getArray()[ nChanged ] = aEvent;
nTitlePos = nChanged++;
g_file_info_set_name(pNewInfo, newName);
}
}
else
{
#ifdef DEBUG
fprintf(stderr, "Unknown property %s\n", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
#endif
aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
//TODO
}
}
if (nChanged)
{
bool bOk = true;
if (!mbTransient)
{
if ((bOk = doSetFileInfo(pNewInfo)))
{
for (sal_Int32 i = 0; i < nChanged; ++i)
aRet[ i ] <<= getBadArgExcept();
}
}
if (bOk)
{
if (nTitlePos > -1)
{
rtl::OUString aNewURL = getParentURL();
aNewURL += rtl::OUString( newName, strlen(newName), RTL_TEXTENCODING_UTF8 );
uno::Reference< ucb::XContentIdentifier > xNewId
= new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL );
if (!exchangeIdentity( xNewId ) )
{
aRet[ nTitlePos ] <<= uno::Exception
( rtl::OUString::createFromAscii( "Exchange failed!" ),
static_cast< cppu::OWeakObject * >( this ) );
}
}
if (!mbTransient) //Discard and refetch
{
g_object_unref(mpInfo);
mpInfo = NULL;
}
if (mpInfo)
{
g_file_info_copy_into(pNewInfo, mpInfo);
g_object_unref(pNewInfo);
}
else
mpInfo = pNewInfo;
if (mpFile) //Discard and refetch
{
g_object_unref(mpFile);
mpFile = NULL;
}
}
aChanges.realloc( nChanged );
notifyPropertiesChange( aChanges );
}
return aRet;
}
bool Content::doSetFileInfo(GFileInfo *pNewInfo)
{
g_assert (!mbTransient);
bool bOk = true;
GFile *pFile = getGFile();
if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
bOk = false;
return bOk;
}
const int TRANSFER_BUFFER_SIZE = 65536;
void Content::copyData( uno::Reference< io::XInputStream > xIn,
uno::Reference< io::XOutputStream > xOut )
{
uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
g_return_if_fail( xIn.is() && xOut.is() );
while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
xOut->writeBytes( theData );
xOut->closeOutput();
}
sal_Bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
{
if ( !xSink.is() )
return sal_False;
uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
if ( !xOut.is() && !xDataSink.is() )
return sal_False;
GError *pError=NULL;
GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
if (!pStream)
convertToException(pError, static_cast< cppu::OWeakObject * >(this));
uno::Reference< io::XInputStream > xIn = new ::gio::InputStream(pStream);
if ( !xIn.is() )
return sal_False;
if ( xOut.is() )
copyData( xIn, xOut );
if ( xDataSink.is() )
xDataSink->setInputStream( xIn );
return sal_True;
}
uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
const uno::Reference< ucb::XCommandEnvironment > & xEnv )
throw( uno::Exception )
{
bool bIsFolder = isFolder(xEnv);
if (!g_file_query_exists(getGFile(), NULL))
{
uno::Sequence< uno::Any > aArgs( 1 );
aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
uno::Any aErr = uno::makeAny(
ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
task::InteractionClassification_ERROR,
bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
);
ucbhelper::cancelCommandExecution(aErr, xEnv);
}
uno::Any aRet;
sal_Bool bOpenFolder = (
( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
);
if ( bOpenFolder && bIsFolder )
{
uno::Reference< ucb::XDynamicResultSet > xSet
= new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
aRet <<= xSet;
}
else if ( rOpenCommand.Sink.is() )
{
if (
( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
)
{
ucbhelper::cancelCommandExecution(
uno::makeAny ( ucb::UnsupportedOpenModeException
( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
sal_Int16( rOpenCommand.Mode ) ) ),
xEnv );
}
if ( !feedSink( rOpenCommand.Sink, xEnv ) )
{
// Note: rOpenCommand.Sink may contain an XStream
// implementation. Support for this type of
// sink is optional...
#ifdef DEBUG
g_warning ("Failed to load data from '%s'",
rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
#endif
ucbhelper::cancelCommandExecution(
uno::makeAny (ucb::UnsupportedDataSinkException
( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
rOpenCommand.Sink ) ),
xEnv );
}
}
else
g_warning ("Open falling through ...");
return aRet;
}
uno::Any SAL_CALL Content::execute(
const ucb::Command& aCommand,
sal_Int32 /*CommandId*/,
const uno::Reference< ucb::XCommandEnvironment >& xEnv )
throw( uno::Exception,
ucb::CommandAbortedException,
uno::RuntimeException )
{
#ifdef DEBUG
fprintf(stderr, "Content::execute %s\n", rtl::OUStringToOString(aCommand.Name, RTL_TEXTENCODING_UTF8).getStr());
#endif
uno::Any aRet;
if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ))
{
uno::Sequence< beans::Property > Properties;
if ( !( aCommand.Argument >>= Properties ) )
ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
aRet <<= getPropertyValues( Properties, xEnv );
}
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ))
aRet <<= getPropertySetInfo( xEnv, sal_False );
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ))
aRet <<= getCommandInfo( xEnv, sal_False );
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "open" ) ))
{
ucb::OpenCommandArgument2 aOpenCommand;
if ( !( aCommand.Argument >>= aOpenCommand ) )
ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
aRet = open( aOpenCommand, xEnv );
}
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "transfer" ) ))
{
ucb::TransferInfo transferArgs;
if ( !( aCommand.Argument >>= transferArgs ) )
ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
transfer( transferArgs, xEnv );
}
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ))
{
uno::Sequence< beans::PropertyValue > aProperties;
if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
aRet <<= setPropertyValues( aProperties, xEnv );
}
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ))
{
ucb::InsertCommandArgument arg;
if ( !( aCommand.Argument >>= arg ) )
ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
insert( arg.Data, arg.ReplaceExisting, xEnv );
}
else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ))
{
sal_Bool bDeletePhysical = sal_False;
aCommand.Argument >>= bDeletePhysical;
//If no delete physical, try and trashcan it, if that doesn't work go
//ahead and try and delete it anyway
if (!bDeletePhysical && !g_file_trash(getGFile(), NULL, NULL))
bDeletePhysical = true;
if (bDeletePhysical)
{
GError *pError = NULL;
if (!g_file_delete( getGFile(), NULL, &pError))
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
}
destroy( bDeletePhysical );
}
else
{
#ifdef DEBUG
fprintf(stderr, "UNKNOWN COMMAND\n");
//TODO
#endif
ucbhelper::cancelCommandExecution
( uno::makeAny( ucb::UnsupportedCommandException
( rtl::OUString(),
static_cast< cppu::OWeakObject * >( this ) ) ),
xEnv );
}
return aRet;
}
void Content::destroy( sal_Bool bDeletePhysical )
throw( uno::Exception )
{
uno::Reference< ucb::XContent > xThis = this;
deleted();
::gio::Content::ContentRefList aChildren;
queryChildren( aChildren );
ContentRefList::const_iterator it = aChildren.begin();
ContentRefList::const_iterator end = aChildren.end();
while ( it != end )
{
(*it)->destroy( bDeletePhysical );
++it;
}
}
void Content::insert(const uno::Reference< io::XInputStream > &xInputStream,
sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment > &xEnv )
throw( uno::Exception )
{
GError *pError = NULL;
GFileInfo *pInfo = getGFileInfo(xEnv);
if ( g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY )
{
#ifdef DEBUG
g_warning ("Make directory");
#endif
if( !g_file_make_directory( getGFile(), NULL, &pError))
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
return;
}
if ( !xInputStream.is() )
{
ucbhelper::cancelCommandExecution( uno::makeAny
( ucb::MissingInputStreamException
( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
xEnv );
}
GFileOutputStream* pOutStream = NULL;
if ( bReplaceExisting )
{
if (!(pOutStream = g_file_replace(getGFile(), NULL, false, G_FILE_CREATE_PRIVATE, NULL, &pError)))
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
}
else
{
if (!(pOutStream = g_file_create (getGFile(), G_FILE_CREATE_PRIVATE, NULL, &pError)))
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
}
uno::Reference < io::XOutputStream > xOutput = new ::gio::OutputStream(pOutStream);
copyData( xInputStream, xOutput );
if (mbTransient)
{
mbTransient = sal_False;
inserted();
}
}
void Content::transfer( const ucb::TransferInfo& aTransferInfo, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
throw( uno::Exception )
{
rtl::OUString sDest = m_xIdentifier->getContentIdentifier();
if (aTransferInfo.NewTitle.getLength())
sDest += aTransferInfo.NewTitle;
else
sDest += rtl::OUString::createFromAscii(g_file_get_basename(getGFile()));
GFile *pDest = g_file_new_for_uri(rtl::OUStringToOString(sDest, RTL_TEXTENCODING_UTF8).getStr());
GFile *pSource = g_file_new_for_uri(rtl::OUStringToOString(aTransferInfo.SourceURL, RTL_TEXTENCODING_UTF8).getStr());
gboolean bSuccess = false;
GError *pError = NULL;
if (aTransferInfo.MoveData)
bSuccess = g_file_move(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
else
bSuccess = g_file_copy(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
g_object_unref(pSource);
g_object_unref(pDest);
if (!bSuccess)
ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
}
com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
throw( com::sun::star::uno::RuntimeException )
{
uno::Sequence< ucb::ContentInfo > seq(2);
// Minimum set of props we really need
uno::Sequence< beans::Property > props( 1 );
props[0] = beans::Property(
rtl::OUString::createFromAscii( "Title" ),
-1,
getCppuType( static_cast< rtl::OUString* >( 0 ) ),
beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
// file
seq[0].Type = rtl::OUString::createFromAscii( GIO_FILE_TYPE );
seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
ucb::ContentInfoAttribute::KIND_DOCUMENT );
seq[0].Properties = props;
// folder
seq[1].Type = rtl::OUString::createFromAscii( GIO_FOLDER_TYPE );
seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
seq[1].Properties = props;
return seq;
}
com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
SAL_CALL Content::createNewContent( const com::sun::star::ucb::ContentInfo& Info )
throw( com::sun::star::uno::RuntimeException )
{
bool create_document;
const char *name;
if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FILE_TYPE ) ) )
create_document = true;
else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FOLDER_TYPE ) ) )
create_document = false;
else
{
#ifdef DEBUG
g_warning( "Failed to create new content '%s'", rtl::OUStringToOString(Info.Type,
RTL_TEXTENCODING_UTF8).getStr() );
#endif
return uno::Reference< ucb::XContent >();
}
#ifdef DEBUG
g_warning( "createNewContent (%d)", (int) create_document );
#endif
rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
aURL += rtl::OUString::createFromAscii( "/" );
name = create_document ? "[New_Content]" : "[New_Collection]";
aURL += rtl::OUString::createFromAscii( name );
uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(m_xSMgr, aURL));
try
{
return new ::gio::Content( m_xSMgr, m_pProvider, xId, !create_document );
} catch ( ucb::ContentCreationException & )
{
return uno::Reference< ucb::XContent >();
}
}
uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
throw( uno::RuntimeException )
{
if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
{
static cppu::OTypeCollection aFolderCollection
(CPPU_TYPE_REF( lang::XTypeProvider ),
CPPU_TYPE_REF( lang::XServiceInfo ),
CPPU_TYPE_REF( lang::XComponent ),
CPPU_TYPE_REF( ucb::XContent ),
CPPU_TYPE_REF( ucb::XCommandProcessor ),
CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
CPPU_TYPE_REF( beans::XPropertyContainer ),
CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
CPPU_TYPE_REF( container::XChild ),
CPPU_TYPE_REF( ucb::XContentCreator ) );
return aFolderCollection.getTypes();
}
else
{
static cppu::OTypeCollection aFileCollection
(CPPU_TYPE_REF( lang::XTypeProvider ),
CPPU_TYPE_REF( lang::XServiceInfo ),
CPPU_TYPE_REF( lang::XComponent ),
CPPU_TYPE_REF( ucb::XContent ),
CPPU_TYPE_REF( ucb::XCommandProcessor ),
CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
CPPU_TYPE_REF( beans::XPropertyContainer ),
CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
CPPU_TYPE_REF( container::XChild ) );
return aFileCollection.getTypes();
}
}
uno::Sequence< beans::Property > Content::getProperties(
const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
{
static const beans::Property aGenericProperties[] =
{
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
-1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
beans::PropertyAttribute::BOUND ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
-1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
-1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
-1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisc" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemoveable" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
};
const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
}
uno::Sequence< ucb::CommandInfo > Content::getCommands( const uno::Reference< ucb::XCommandEnvironment > & xEnv)
{
static ucb::CommandInfo aDocumentCommandInfoTable[] =
{
// Required commands
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
-1, getCppuVoidType() ),
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
-1, getCppuVoidType() ),
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
-1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
-1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
// Optional standard commands
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
-1, getCppuBooleanType() ),
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
-1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
-1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
// Folder Only, omitted if not a folder
ucb::CommandInfo
( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
-1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) )
};
const int nProps = sizeof (aDocumentCommandInfoTable) / sizeof (aDocumentCommandInfoTable[0]);
return uno::Sequence< ucb::CommandInfo >(aDocumentCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 1);
}
XTYPEPROVIDER_COMMON_IMPL( Content );
void SAL_CALL Content::acquire() throw()
{
ContentImplHelper::acquire();
}
void SAL_CALL Content::release() throw()
{
ContentImplHelper::release();
}
uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
{
uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
}
rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException )
{
return rtl::OUString::createFromAscii("com.sun.star.comp.GIOContent" );
}
uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
throw( uno::RuntimeException )
{
uno::Sequence< rtl::OUString > aSNS( 1 );
aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii("com.sun.star.ucb.GIOContent" );
return aSNS;
}
}
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_datasupplier.cxx,v $
* $Revision: 1.2 $
*
* 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 <vector>
#include <ucbhelper/contentidentifier.hxx>
#include <ucbhelper/providerhelper.hxx>
#include <com/sun/star/ucb/OpenMode.hpp>
#include "gio_datasupplier.hxx"
#include "gio_content.hxx"
#include "gio_provider.hxx"
#include <stdio.h>
using namespace com::sun::star;
using namespace gio;
namespace gio
{
typedef std::vector< ResultListEntry* > ResultList;
DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
const uno::Reference< ::gio::Content >& rContent, sal_Int32 nOpenMode )
: mxContent(rContent), m_xSMgr(rxSMgr), mnOpenMode(nOpenMode), mbCountFinal(false)
{
}
bool DataSupplier::getData()
{
if (mbCountFinal)
return true;
GFile *pFile = mxContent->getGFile();
GFileEnumerator* pEnumerator = g_file_enumerate_children(pFile, "*",
G_FILE_QUERY_INFO_NONE, NULL, NULL);
if (!pEnumerator)
return sal_False;
GFileInfo *pInfo = NULL;
while ((pInfo = g_file_enumerator_next_file (pEnumerator, NULL, NULL)))
{
switch ( mnOpenMode )
{
case ucb::OpenMode::FOLDERS:
if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_DIRECTORY)
continue;
break;
case ucb::OpenMode::DOCUMENTS:
if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_REGULAR)
continue;
break;
case ucb::OpenMode::ALL:
default:
break;
}
maResults.push_back( new ResultListEntry( pInfo ) );
g_object_unref(pInfo);
}
mbCountFinal = sal_True;
g_file_enumerator_close(pEnumerator, NULL, NULL);
return true;
}
DataSupplier::~DataSupplier()
{
ResultList::const_iterator it = maResults.begin();
ResultList::const_iterator end = maResults.end();
while ( it != end )
{
delete (*it);
it++;
}
}
::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
{
if ( nIndex < maResults.size() )
{
::rtl::OUString aId = maResults[ nIndex ]->aId;
if ( aId.getLength() )
{
// Already cached.
return aId;
}
}
if ( getResult( nIndex ) )
{
GFile *pFile = mxContent->getGFile();
char* parent = g_file_get_uri(pFile);
rtl::OUString aId = rtl::OUString::createFromAscii( parent );
g_free(parent);
char *escaped_name =
g_uri_escape_string( g_file_info_get_name(maResults[ nIndex ]->pInfo) , NULL, false);
if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
aId += rtl::OUString::createFromAscii( "/" );
aId += rtl::OUString::createFromAscii( escaped_name );
g_free( escaped_name );
maResults[ nIndex ]->aId = aId;
return aId;
return aId;
}
return ::rtl::OUString();
}
uno::Reference< ucb::XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
{
if ( nIndex < maResults.size() )
{
uno::Reference< ucb::XContentIdentifier > xId = maResults[ nIndex ]->xId;
if ( xId.is() )
{
// Already cached.
return xId;
}
}
::rtl::OUString aId = queryContentIdentifierString( nIndex );
if ( aId.getLength() )
{
uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aId );
maResults[ nIndex ]->xId = xId;
return xId;
}
return uno::Reference< ucb::XContentIdentifier >();
}
uno::Reference< ucb::XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
{
if ( nIndex < maResults.size() )
{
uno::Reference< ucb::XContent > xContent = maResults[ nIndex ]->xContent;
if ( xContent.is() )
{
// Already cached.
return xContent;
}
}
uno::Reference< ucb::XContentIdentifier > xId = queryContentIdentifier( nIndex );
if ( xId.is() )
{
try
{
uno::Reference< ucb::XContent > xContent = mxContent->getProvider()->queryContent( xId );
maResults[ nIndex ]->xContent = xContent;
return xContent;
}
catch ( ucb::IllegalIdentifierException& )
{
}
}
return uno::Reference< ucb::XContent >();
}
sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
{
if ( maResults.size() > nIndex ) // Result already present.
return sal_True;
if ( getData() && maResults.size() > nIndex )
return sal_True;
return sal_False;
}
sal_uInt32 DataSupplier::totalCount()
{
getData();
return maResults.size();
}
sal_uInt32 DataSupplier::currentCount()
{
return maResults.size();
}
sal_Bool DataSupplier::isCountFinal()
{
return mbCountFinal;
}
uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
{
if ( nIndex < maResults.size() )
{
uno::Reference< sdbc::XRow > xRow = maResults[ nIndex ]->xRow;
if ( xRow.is() )
{
// Already cached.
return xRow;
}
}
if ( getResult( nIndex ) )
{
uno::Reference< sdbc::XRow > xRow = Content::getPropertyValuesFromGFileInfo(
maResults[ nIndex ]->pInfo, m_xSMgr, getResultSet()->getProperties());
maResults[ nIndex ]->xRow = xRow;
return xRow;
}
return uno::Reference< sdbc::XRow >();
}
void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
{
if ( nIndex < maResults.size() )
maResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
}
void DataSupplier::close()
{
}
void DataSupplier::validate() throw( ucb::ResultSetException )
{
}
}
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_datasupplier.hxx,v $
* $Revision: 1.2 $
*
* 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.
*
************************************************************************/
#ifndef GIO_DATASUPPLIER_HXX
#define GIO_DATASUPPLIER_HXX
#include <ucbhelper/resultset.hxx>
#include "gio_content.hxx"
#include <vector>
namespace gio
{
class Content;
struct ResultListEntry
{
::rtl::OUString aId;
com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > xId;
com::sun::star::uno::Reference< com::sun::star::ucb::XContent > xContent;
com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > xRow;
GFileInfo *pInfo;
ResultListEntry( GFileInfo *pInInfo ) : pInfo(pInInfo)
{
g_object_ref( pInfo );
}
~ResultListEntry()
{
g_object_unref( pInfo );
}
};
typedef std::vector< ResultListEntry* > ResultList;
class DataSupplier : public ucbhelper::ResultSetDataSupplier
{
private:
com::sun::star::uno::Reference< ::gio::Content > mxContent;
com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
sal_Int32 mnOpenMode;
bool mbCountFinal;
bool getData();
ResultList maResults;
public:
DataSupplier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
const com::sun::star::uno::Reference< Content >& rContent, sal_Int32 nOpenMode );
virtual ~DataSupplier();
virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >
queryContentIdentifier( sal_uInt32 nIndex );
virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
queryContent( sal_uInt32 nIndex );
virtual sal_Bool getResult( sal_uInt32 nIndex );
virtual sal_uInt32 totalCount();
virtual sal_uInt32 currentCount();
virtual sal_Bool isCountFinal();
virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
queryPropertyValues( sal_uInt32 nIndex );
virtual void releasePropertyValues( sal_uInt32 nIndex );
virtual void close();
virtual void validate()
throw( com::sun::star::ucb::ResultSetException );
};
}
#endif
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_inputstream.cxx,v $
* $Revision: 1.2 $
*
* 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 <rtl/memory.h>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
#include <ucbhelper/cancelcommandexecution.hxx>
#include <string.h>
#include "gio_inputstream.hxx"
#include "gio_content.hxx"
using namespace com::sun::star;
namespace gio
{
InputStream::InputStream(GFileInputStream *pStream) : Seekable(G_SEEKABLE(pStream)), mpStream(pStream)
{
if (!mpStream)
throw io::NotConnectedException();
}
InputStream::~InputStream( void )
{
closeInput();
}
sal_Int32 SAL_CALL InputStream::available()
throw( io::NotConnectedException, io::IOException, uno::RuntimeException )
{
return 0;
}
void SAL_CALL InputStream::closeInput()
throw( io::NotConnectedException, io::IOException, uno::RuntimeException )
{
if (mpStream)
g_input_stream_close(G_INPUT_STREAM(mpStream), NULL, NULL);
}
void SAL_CALL InputStream::skipBytes( sal_Int32 nBytesToSkip )
throw( io::NotConnectedException, io::BufferSizeExceededException,
io::IOException, uno::RuntimeException )
{
if (!mpStream)
throw io::NotConnectedException();
if (!g_seekable_can_seek(G_SEEKABLE(mpStream)))
throw io::IOException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Seek unsupported")),
static_cast< cppu::OWeakObject * >(this));
GError *pError=NULL;
if (!g_seekable_seek(G_SEEKABLE(mpStream), nBytesToSkip, G_SEEK_CUR, NULL, &pError))
convertToException(pError, static_cast< cppu::OWeakObject * >(this));
}
sal_Int32 SAL_CALL InputStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
throw( io::NotConnectedException, io::BufferSizeExceededException,
io::IOException, uno::RuntimeException )
{
if (!mpStream)
throw io::NotConnectedException();
try
{
aData.realloc( nBytesToRead );
}
catch ( const uno::Exception &e )
{
throw io::BufferSizeExceededException();
}
gsize nBytesRead = 0;
GError *pError=NULL;
if (!g_input_stream_read_all(G_INPUT_STREAM(mpStream), aData.getArray(), nBytesToRead, &nBytesRead, NULL, &pError))
convertToException(pError, static_cast< cppu::OWeakObject * >(this));
aData.realloc(nBytesRead);
return nBytesRead;
}
sal_Int32 SAL_CALL InputStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
throw( io::NotConnectedException, io::BufferSizeExceededException,
io::IOException, uno::RuntimeException )
{
return readBytes(aData, nMaxBytesToRead);
}
uno::Any InputStream::queryInterface( const uno::Type &type ) throw( uno::RuntimeException )
{
uno::Any aRet = ::cppu::queryInterface ( type,
static_cast< XInputStream * >( this ) );
return aRet.hasValue() ? aRet : Seekable::queryInterface( type );
}
}
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_inputstream.hxx,v $
* $Revision: 1.2 $
*
* 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.
*
************************************************************************/
#ifndef GIO_INPUTSTREAM_HXX
#define GIO_INPUTSTREAM_HXX
#include <sal/types.h>
#include <rtl/ustring.hxx>
#include <cppuhelper/weak.hxx>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include "gio_seekable.hxx"
namespace gio
{
class InputStream :
public ::com::sun::star::io::XInputStream,
public Seekable
{
private:
GFileInputStream *mpStream;
public:
InputStream ( GFileInputStream *pStream );
virtual ~InputStream();
// XInterface
virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type )
throw( ::com::sun::star::uno::RuntimeException );
virtual void SAL_CALL acquire( void ) throw () { OWeakObject::acquire(); }
virtual void SAL_CALL release( void ) throw() { OWeakObject::release(); }
// XInputStream
virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
sal_Int32 nBytesToRead )
throw( ::com::sun::star::io::NotConnectedException,
::com::sun::star::io::BufferSizeExceededException,
::com::sun::star::io::IOException,
::com::sun::star::uno::RuntimeException );
virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
sal_Int32 nMaxBytesToRead )
throw( ::com::sun::star::io::NotConnectedException,
::com::sun::star::io::BufferSizeExceededException,
::com::sun::star::io::IOException,
::com::sun::star::uno::RuntimeException );
virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
throw( ::com::sun::star::io::NotConnectedException,
::com::sun::star::io::BufferSizeExceededException,
::com::sun::star::io::IOException,
::com::sun::star::uno::RuntimeException );
virtual sal_Int32 SAL_CALL available( void )
throw( ::com::sun::star::io::NotConnectedException,
::com::sun::star::io::IOException,
::com::sun::star::uno::RuntimeException );
virtual void SAL_CALL closeInput( void )
throw( ::com::sun::star::io::NotConnectedException,
::com::sun::star::io::IOException,
::com::sun::star::uno::RuntimeException );
};
} // namespace gio
#endif
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gio_mount.cxx,v $
* $Revision: 1.2 $
*
* 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 "gio_mount.hxx"
#include <ucbhelper/simpleauthenticationrequest.hxx>
#include <stdio.h>
#include <string.h>
G_DEFINE_TYPE (OOoMountOperation, ooo_mount_operation, G_TYPE_MOUNT_OPERATION);
static void ooo_mount_operation_ask_password (GMountOperation *op,
const char *message, const char *default_user, const char *default_domain,
GAskPasswordFlags flags);
static void ooo_mount_operation_init (OOoMountOperation *op)
{
op->m_pPrevPassword = NULL;
op->m_pPrevUsername = NULL;
}
static void ooo_mount_operation_finalize (GObject *object)
{
OOoMountOperation *mount_op = OOO_MOUNT_OPERATION (object);
if (mount_op->m_pPrevUsername)
free(mount_op->m_pPrevUsername);
if (mount_op->m_pPrevPassword)
free(mount_op->m_pPrevPassword);
G_OBJECT_CLASS (ooo_mount_operation_parent_class)->finalize (object);
}
static void ooo_mount_operation_class_init (OOoMountOperationClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = ooo_mount_operation_finalize;
GMountOperationClass *mount_op_class = G_MOUNT_OPERATION_CLASS (klass);
mount_op_class->ask_password = ooo_mount_operation_ask_password;
}
using namespace com::sun::star;
static void ooo_mount_operation_ask_password (GMountOperation *op,
const char *message, const char *default_user,
const char *default_domain, GAskPasswordFlags flags)
{
uno::Reference< task::XInteractionHandler > xIH;
OOoMountOperation *pThis = (OOoMountOperation*)op;
const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > &xEnv = *(pThis->pEnv);
if (xEnv.is())
xIH = xEnv->getInteractionHandler();
if (!xIH.is())
{
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
return;
}
::rtl::OUString aHostName, aDomain, aUserName, aPassword;
ucbhelper::SimpleAuthenticationRequest::EntityType eUserName =
(flags & G_ASK_PASSWORD_NEED_USERNAME)
? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
: ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
if (default_user)
aUserName = rtl::OUString(default_user, strlen(default_user), RTL_TEXTENCODING_UTF8);
ucbhelper::SimpleAuthenticationRequest::EntityType ePassword =
(flags & G_ASK_PASSWORD_NEED_PASSWORD)
? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
: ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
rtl::OUString aPrevPassword, aPrevUsername;
if (pThis->m_pPrevUsername)
aPrevUsername = rtl::OUString(pThis->m_pPrevUsername, strlen(pThis->m_pPrevUsername), RTL_TEXTENCODING_UTF8);
if (pThis->m_pPrevPassword)
aPrevPassword = rtl::OUString(pThis->m_pPrevPassword, strlen(pThis->m_pPrevPassword), RTL_TEXTENCODING_UTF8);
//The damn dialog is stupidly broken, so do like webdav, i.e. "#102871#"
if ( aUserName.getLength() == 0 )
aUserName = aPrevUsername;
if ( aPassword.getLength() == 0 )
aPassword = aPrevPassword;
ucbhelper::SimpleAuthenticationRequest::EntityType eDomain =
(flags & G_ASK_PASSWORD_NEED_DOMAIN)
? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
: ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
if (default_domain)
aDomain = rtl::OUString(default_domain, strlen(default_domain), RTL_TEXTENCODING_UTF8);
uno::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
= new ucbhelper::SimpleAuthenticationRequest (aHostName, eDomain, aDomain, eUserName, aUserName, ePassword, aPassword);
xIH->handle( xRequest.get() );
rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
if ( !xSelection.is() )
{
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
return;
}
uno::Reference< task::XInteractionAbort > xAbort(xSelection.get(), uno::UNO_QUERY );
if ( xAbort.is() )
{
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
return;
}
const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp = xRequest->getAuthenticationSupplier();
aUserName = xSupp->getUserName();
aPassword = xSupp->getPassword();
if (flags & G_ASK_PASSWORD_NEED_USERNAME)
g_mount_operation_set_username(op, rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr());
if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
g_mount_operation_set_password(op, rtl::OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr());
if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
g_mount_operation_set_domain(op, rtl::OUStringToOString(xSupp->getRealm(), RTL_TEXTENCODING_UTF8).getStr());
switch (xSupp->getRememberPasswordMode())
{
default:
case ucb::RememberAuthentication_NO:
g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_NEVER);
break;
case ucb::RememberAuthentication_SESSION:
g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_FOR_SESSION);
break;
case ucb::RememberAuthentication_PERSISTENT:
g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_PERMANENTLY);
break;
}
if (pThis->m_pPrevPassword)
free(pThis->m_pPrevPassword);
pThis->m_pPrevPassword = strdup(rtl::OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr());
if (pThis->m_pPrevUsername)
free(pThis->m_pPrevUsername);
pThis->m_pPrevUsername = strdup(rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr());
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
}
GMountOperation *ooo_mount_operation_new(const uno::Reference< ucb::XCommandEnvironment >& rEnv)
{
OOoMountOperation *pRet = (OOoMountOperation*)g_object_new (OOO_TYPE_MOUNT_OPERATION, NULL);
pRet->pEnv = &rEnv;
return (GMountOperation*)pRet;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment