/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 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 propagate //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::Reference< ucb::XCommandEnvironment > & xEnv, 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 ); } else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) { xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) ); } #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, xEnv, 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" ) ) || rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) { 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( "createNewContent" ) ) && isFolder( xEnv ) ) { ucb::ContentInfo arg; if ( !( aCommand.Argument >>= arg ) ) ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv ); aRet <<= createNewContent( arg ); } 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); } uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo( const uno::Reference< ucb::XCommandEnvironment >& xEnv) throw( uno::RuntimeException ) { if ( isFolder( xEnv ) ) { 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; } else { return uno::Sequence< ucb::ContentInfo >(); } } uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo() throw( uno::RuntimeException ) { return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() ); } uno::Reference< ucb::XContent > SAL_CALL Content::createNewContent( const ucb::ContentInfo& Info ) throw( 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 ), beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ), -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ), 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 aCommandInfoTable[] = { // 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 * >( 0 ) ) ), ucb::CommandInfo ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ), -1, getCppuType( static_cast * >( 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( 0 ) ) ), ucb::CommandInfo ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ), -1, getCppuType( static_cast( 0 ) ) ), // Folder Only, omitted if not a folder ucb::CommandInfo ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ), -1, getCppuType( static_cast( 0 ) ) ), ucb::CommandInfo ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ), -1, getCppuType( static_cast( 0 ) ) ) }; const int nProps = sizeof (aCommandInfoTable) / sizeof (aCommandInfoTable[0]); return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 2); } 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; } }