LCOV - code coverage report
Current view: top level - ucb/source/ucp/gio - gio_content.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 604 0.0 %
Date: 2014-04-14 Functions: 0 46 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string.h>
      21             : #include <unistd.h>
      22             : #include <sys/types.h>
      23             : #include <sal/macros.h>
      24             : #include <osl/time.h>
      25             : 
      26             : #include <osl/diagnose.h>
      27             : #include <osl/doublecheckedlocking.h>
      28             : 
      29             : #include <com/sun/star/beans/PropertyValue.hpp>
      30             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      31             : #include <com/sun/star/beans/PropertySetInfoChange.hpp>
      32             : #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
      33             : #include <com/sun/star/io/XActiveDataSink.hpp>
      34             : #include <com/sun/star/io/XOutputStream.hpp>
      35             : #include <com/sun/star/lang/IllegalAccessException.hpp>
      36             : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
      37             : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      38             : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
      39             : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
      40             : #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
      41             : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
      42             : #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
      43             : #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
      44             : #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
      45             : #include <com/sun/star/ucb/NameClash.hpp>
      46             : #include <com/sun/star/ucb/NameClashException.hpp>
      47             : #include <com/sun/star/ucb/OpenMode.hpp>
      48             : #include <com/sun/star/ucb/PostCommandArgument2.hpp>
      49             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      50             : #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
      51             : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
      52             : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
      53             : #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
      54             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      55             : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      56             : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
      57             : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
      58             : #include <com/sun/star/ucb/XContentCreator.hpp>
      59             : 
      60             : #include <comphelper/processfactory.hxx>
      61             : #include <ucbhelper/contentidentifier.hxx>
      62             : #include <ucbhelper/propertyvalueset.hxx>
      63             : #include <ucbhelper/interactionrequest.hxx>
      64             : #include <ucbhelper/cancelcommandexecution.hxx>
      65             : #include <vcl/svapp.hxx>
      66             : 
      67             : #include <osl/conditn.hxx>
      68             : 
      69             : #include "gio_content.hxx"
      70             : #include "gio_provider.hxx"
      71             : #include "gio_resultset.hxx"
      72             : #include "gio_inputstream.hxx"
      73             : #include "gio_outputstream.hxx"
      74             : #include "gio_mount.hxx"
      75             : 
      76             : #include <stdio.h>
      77             : 
      78             : using namespace com::sun::star;
      79             : 
      80             : namespace gio
      81             : {
      82             : 
      83           0 : Content::Content(
      84             :     const uno::Reference< uno::XComponentContext >& rxContext,
      85             :     ContentProvider* pProvider,
      86             :     const uno::Reference< ucb::XContentIdentifier >& Identifier)
      87             :         throw ( ucb::ContentCreationException )
      88             :     : ContentImplHelper( rxContext, pProvider, Identifier ),
      89           0 :       m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(false)
      90             : {
      91             : #if OSL_DEBUG_LEVEL > 1
      92             :     fprintf(stderr, "New Content ('%s')\n", OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
      93             : #endif
      94           0 : }
      95             : 
      96           0 : Content::Content(
      97             :     const uno::Reference< uno::XComponentContext >& rxContext,
      98             :     ContentProvider* pProvider,
      99             :     const uno::Reference< ucb::XContentIdentifier >& Identifier,
     100             :     sal_Bool bIsFolder)
     101             :         throw ( ucb::ContentCreationException )
     102             :     : ContentImplHelper( rxContext, pProvider, Identifier ),
     103           0 :       m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(true)
     104             : {
     105             : #if OSL_DEBUG_LEVEL > 1
     106             :     fprintf(stderr, "Create Content ('%s')\n", OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
     107             : #endif
     108           0 :     mpInfo = g_file_info_new();
     109           0 :     g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
     110           0 : }
     111             : 
     112           0 : Content::~Content()
     113             : {
     114           0 :     if (mpInfo) g_object_unref(mpInfo);
     115           0 :     if (mpFile) g_object_unref(mpFile);
     116           0 : }
     117             : 
     118           0 : OUString Content::getParentURL()
     119             : {
     120           0 :     OUString sURL;
     121           0 :     if (GFile* pFile = g_file_get_parent(getGFile()))
     122             :     {
     123           0 :         char* pPath = g_file_get_uri(pFile);
     124           0 :         g_object_unref(pFile);
     125           0 :         sURL = OUString::createFromAscii(pPath);
     126           0 :         g_free(pPath);
     127             :     }
     128           0 :     return sURL;
     129             : }
     130             : 
     131           0 : void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
     132             :        throw( uno::RuntimeException, std::exception )
     133             : {
     134             :     //TODO
     135             :     //stick a map from each CommandId to a new GCancellable and propogate
     136             :     //it throughout the g_file_* calls
     137           0 : }
     138             : 
     139           0 : OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException, std::exception )
     140             : {
     141           0 :     return isFolder(uno::Reference< ucb::XCommandEnvironment >())
     142             :         ? OUString( GIO_FOLDER_TYPE )
     143           0 :         : OUString( GIO_FILE_TYPE );
     144             : }
     145             : 
     146             : #define EXCEPT(aExcept) \
     147             : do { \
     148             :     if (bThrow) throw aExcept;\
     149             :     aRet = uno::makeAny( aExcept );\
     150             : } while(false)
     151             : 
     152           0 : uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
     153             : {
     154           0 :     uno::Any aRet;
     155             : 
     156           0 :     gint eCode = pError->code;
     157           0 :     OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
     158           0 :     g_error_free(pError);
     159             : 
     160           0 :     OUString sName;
     161           0 :     OUString sHost;
     162             : 
     163           0 :     uno::Sequence< uno::Any > aArgs( 1 );
     164           0 :     aArgs[ 0 ] <<= sName;
     165             : 
     166           0 :     switch (eCode)
     167             :     {
     168             :         case G_IO_ERROR_FAILED:
     169           0 :             { io::IOException aExcept(sMessage, rContext);
     170           0 :             EXCEPT(aExcept); }
     171           0 :             break;
     172             :         case G_IO_ERROR_NOT_MOUNTED:
     173             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     174           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
     175           0 :             EXCEPT(aExcept); }
     176           0 :             break;
     177             :         case G_IO_ERROR_NOT_FOUND:
     178             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     179           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
     180           0 :             EXCEPT(aExcept); }
     181           0 :             break;
     182             :         case G_IO_ERROR_EXISTS:
     183             :             { ucb::NameClashException aExcept(sMessage, rContext,
     184           0 :                 task::InteractionClassification_ERROR, sName);
     185           0 :             EXCEPT(aExcept); }
     186           0 :             break;
     187             :         case G_IO_ERROR_INVALID_ARGUMENT:
     188           0 :             { lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
     189           0 :             EXCEPT(aExcept); }
     190           0 :             break;
     191             :         case G_IO_ERROR_PERMISSION_DENIED:
     192             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     193           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
     194           0 :             EXCEPT(aExcept); }
     195           0 :             break;
     196             :         case G_IO_ERROR_IS_DIRECTORY:
     197             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     198           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
     199           0 :             EXCEPT(aExcept); }
     200           0 :             break;
     201             :         case G_IO_ERROR_NOT_REGULAR_FILE:
     202             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     203           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
     204           0 :             EXCEPT(aExcept); }
     205           0 :             break;
     206             :         case G_IO_ERROR_NOT_DIRECTORY:
     207             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     208           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
     209           0 :             EXCEPT(aExcept); }
     210           0 :             break;
     211             :         case G_IO_ERROR_FILENAME_TOO_LONG:
     212             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     213           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
     214           0 :             EXCEPT(aExcept); }
     215           0 :             break;
     216             :         case G_IO_ERROR_PENDING:
     217             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     218           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
     219           0 :             EXCEPT(aExcept); }
     220           0 :             break;
     221             :         case G_IO_ERROR_CLOSED:
     222             :         case G_IO_ERROR_CANCELLED:
     223             :         case G_IO_ERROR_TOO_MANY_LINKS:
     224             :         case G_IO_ERROR_WRONG_ETAG:
     225             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     226           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
     227           0 :             EXCEPT(aExcept); }
     228           0 :             break;
     229             :         case G_IO_ERROR_NOT_SUPPORTED:
     230             :         case G_IO_ERROR_CANT_CREATE_BACKUP:
     231             :         case G_IO_ERROR_WOULD_MERGE:
     232             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     233           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
     234           0 :             EXCEPT(aExcept); }
     235           0 :             break;
     236             :         case G_IO_ERROR_NO_SPACE:
     237             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     238           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
     239           0 :             EXCEPT(aExcept); }
     240           0 :             break;
     241             :         case G_IO_ERROR_INVALID_FILENAME:
     242             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     243           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
     244           0 :             EXCEPT(aExcept); }
     245           0 :             break;
     246             :         case G_IO_ERROR_READ_ONLY:
     247             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     248           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
     249           0 :             EXCEPT(aExcept); }
     250           0 :             break;
     251             :         case G_IO_ERROR_TIMED_OUT:
     252             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     253           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
     254           0 :             EXCEPT(aExcept); }
     255           0 :             break;
     256             :         case G_IO_ERROR_WOULD_RECURSE:
     257             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     258           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
     259           0 :             EXCEPT(aExcept); }
     260           0 :             break;
     261             :         case G_IO_ERROR_BUSY:
     262             :         case G_IO_ERROR_WOULD_BLOCK:
     263             :             { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
     264           0 :                 task::InteractionClassification_ERROR, ucb::IOErrorCode_LOCKING_VIOLATION, aArgs);
     265           0 :             EXCEPT(aExcept); }
     266           0 :             break;
     267             :         case G_IO_ERROR_HOST_NOT_FOUND:
     268             :             { ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
     269           0 :                 task::InteractionClassification_ERROR, sHost);
     270           0 :               EXCEPT(aExcept);}
     271           0 :             break;
     272             :         default:
     273             :         case G_IO_ERROR_ALREADY_MOUNTED:
     274             :         case G_IO_ERROR_NOT_EMPTY:
     275             :         case G_IO_ERROR_NOT_SYMBOLIC_LINK:
     276             :         case G_IO_ERROR_NOT_MOUNTABLE_FILE:
     277             :         case G_IO_ERROR_FAILED_HANDLED:
     278             :             { ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
     279           0 :                 task::InteractionClassification_ERROR);
     280           0 :               EXCEPT(aExcept);}
     281           0 :             break;
     282             :     }
     283           0 :     return aRet;
     284             : }
     285             : 
     286           0 : uno::Any Content::mapGIOError( GError *pError )
     287             : {
     288           0 :     if (!pError)
     289           0 :         return getBadArgExcept();
     290             : 
     291           0 :     return convertToException(pError, static_cast< cppu::OWeakObject * >(this), false);
     292             : }
     293             : 
     294           0 : uno::Any Content::getBadArgExcept()
     295             : {
     296             :     return uno::makeAny( lang::IllegalArgumentException(
     297             :         OUString("Wrong argument type!"),
     298           0 :         static_cast< cppu::OWeakObject * >( this ), -1) );
     299             : }
     300             : 
     301             : class MountOperation
     302             : {
     303             :     GMainLoop *mpLoop;
     304             :     GMountOperation *mpAuthentication;
     305             :     GError *mpError;
     306             :     static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
     307             : public:
     308             :     MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
     309             :     ~MountOperation();
     310             :     GError *Mount(GFile *pFile);
     311             : };
     312             : 
     313           0 : MountOperation::MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv) : mpError(NULL)
     314             : {
     315           0 :     mpLoop = g_main_loop_new(NULL, FALSE);
     316           0 :     mpAuthentication = ooo_mount_operation_new(xEnv);
     317           0 : }
     318             : 
     319           0 : void MountOperation::Completed(GObject *source, GAsyncResult *res, gpointer user_data)
     320             : {
     321           0 :     MountOperation *pThis = (MountOperation*)user_data;
     322           0 :     g_file_mount_enclosing_volume_finish(G_FILE(source), res, &(pThis->mpError));
     323           0 :     g_main_loop_quit(pThis->mpLoop);
     324           0 : }
     325             : 
     326           0 : GError *MountOperation::Mount(GFile *pFile)
     327             : {
     328           0 :     g_file_mount_enclosing_volume(pFile, G_MOUNT_MOUNT_NONE, mpAuthentication, NULL, MountOperation::Completed, this);
     329             :     {
     330             :         //HACK: At least the gdk_threads_set_lock_functions(GdkThreadsEnter,
     331             :         // GdkThreadsLeave) call in vcl/unx/gtk/app/gtkinst.cxx will lead to
     332             :         // GdkThreadsLeave unlock the SolarMutex down to zero at the end of
     333             :         // g_main_loop_run, so we need ~SolarMutexReleaser to raise it back to
     334             :         // the original value again:
     335           0 :         SolarMutexReleaser rel;
     336           0 :         g_main_loop_run(mpLoop);
     337             :     }
     338           0 :     return mpError;
     339             : }
     340             : 
     341           0 : MountOperation::~MountOperation()
     342             : {
     343           0 :     g_object_unref(mpAuthentication);
     344           0 :     g_main_loop_unref(mpLoop);
     345           0 : }
     346             : 
     347           0 : GFileInfo* Content::getGFileInfo(const uno::Reference< ucb::XCommandEnvironment >& xEnv, GError **ppError)
     348             : {
     349           0 :     GError * err = 0;
     350           0 :     if (mpInfo == 0 && !mbTransient) {
     351           0 :         for (bool retried = false;; retried = true) {
     352             :             mpInfo = g_file_query_info(
     353           0 :                 getGFile(), "*", G_FILE_QUERY_INFO_NONE, 0, &err);
     354           0 :             if (mpInfo != 0) {
     355           0 :                 break;
     356             :             }
     357             :             assert(err != 0);
     358           0 :             if (err->code != G_IO_ERROR_NOT_MOUNTED || retried) {
     359             :                 break;
     360             :             }
     361             :             SAL_INFO(
     362             :                 "ucb.ucp.gio",
     363             :                 "G_IO_ERROR_NOT_MOUNTED \"" << err->message
     364             :                     << "\", trying to mount");
     365           0 :             g_error_free(err);
     366           0 :             err = MountOperation(xEnv).Mount(getGFile());
     367           0 :             if (err != 0) {
     368           0 :                 break;
     369             :             }
     370           0 :         }
     371             :     }
     372           0 :     if (ppError != 0) {
     373           0 :         *ppError = err;
     374           0 :     } else if (err != 0) {
     375             :         SAL_WARN(
     376             :             "ucb.ucp.gio",
     377             :             "ignoring GError \"" << err->message << "\" for <"
     378             :                 << m_xIdentifier->getContentIdentifier() << ">");
     379           0 :         g_error_free(err);
     380             :     }
     381           0 :     return mpInfo;
     382             : }
     383             : 
     384           0 : GFile* Content::getGFile()
     385             : {
     386           0 :     if (!mpFile)
     387           0 :         mpFile = g_file_new_for_uri(OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
     388           0 :     return mpFile;
     389             : }
     390             : 
     391           0 : bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv)
     392             : {
     393           0 :     GFileInfo *pInfo = getGFileInfo(xEnv);
     394           0 :     return pInfo && (g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY);
     395             : }
     396             : 
     397           0 : static util::DateTime getDateFromUnix (time_t t)
     398             : {
     399             :     TimeValue tv;
     400           0 :     tv.Nanosec = 0;
     401           0 :     tv.Seconds = t;
     402             :     oslDateTime dt;
     403             : 
     404           0 :     if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
     405             :         return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
     406           0 :                    dt.Day, dt.Month, dt.Year, false);
     407             :     else
     408           0 :         return util::DateTime();
     409             : }
     410             : 
     411           0 : uno::Reference< sdbc::XRow > Content::getPropertyValuesFromGFileInfo(GFileInfo *pInfo,
     412             :     const uno::Reference< uno::XComponentContext >& rxContext,
     413             :     const uno::Reference< ucb::XCommandEnvironment > & xEnv,
     414             :     const uno::Sequence< beans::Property >& rProperties)
     415             : {
     416           0 :     rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rxContext );
     417             : 
     418             :     sal_Int32 nProps;
     419             :     const beans::Property* pProps;
     420             : 
     421           0 :     nProps = rProperties.getLength();
     422           0 :     pProps = rProperties.getConstArray();
     423             : 
     424           0 :     for( sal_Int32 n = 0; n < nProps; ++n )
     425             :     {
     426           0 :         const beans::Property& rProp = pProps[ n ];
     427             : 
     428           0 :         if ( rProp.Name == "IsDocument" )
     429             :         {
     430           0 :             if (pInfo != 0 && g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE))
     431           0 :                 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_REGULAR ||
     432           0 :                                                g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_UNKNOWN ) );
     433             :             else
     434           0 :                 xRow->appendVoid( rProp );
     435             :         }
     436           0 :         else if ( rProp.Name == "IsFolder" )
     437             :         {
     438           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) )
     439           0 :                 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_DIRECTORY ));
     440             :             else
     441           0 :                 xRow->appendVoid( rProp );
     442             :         }
     443           0 :         else if ( rProp.Name == "Title" )
     444             :         {
     445           0 :             if (pInfo != 0 && g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
     446             :             {
     447           0 :                 const char *pName = g_file_info_get_display_name(pInfo);
     448           0 :                 xRow->appendString( rProp, OUString(pName, strlen(pName), RTL_TEXTENCODING_UTF8) );
     449             :             }
     450             :             else
     451           0 :                 xRow->appendVoid(rProp);
     452             :         }
     453           0 :         else if ( rProp.Name == "IsReadOnly" )
     454             :         {
     455           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) )
     456           0 :                 xRow->appendBoolean( rProp, !g_file_info_get_attribute_boolean( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) );
     457             :             else
     458           0 :                 xRow->appendVoid( rProp );
     459             :         }
     460           0 :         else if ( rProp.Name == "DateCreated" )
     461             :         {
     462           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CREATED ) )
     463           0 :                 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CREATED)) );
     464             :             else
     465           0 :                 xRow->appendVoid( rProp );
     466             :         }
     467           0 :         else if ( rProp.Name == "DateModified" )
     468             :         {
     469           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo,  G_FILE_ATTRIBUTE_TIME_CHANGED ) )
     470           0 :                 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED)) );
     471             :             else
     472           0 :                 xRow->appendVoid( rProp );
     473             :         }
     474           0 :         else if ( rProp.Name == "Size" )
     475             :         {
     476           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE) )
     477           0 :                 xRow->appendLong( rProp, ( g_file_info_get_size( pInfo ) ));
     478             :             else
     479           0 :                 xRow->appendVoid( rProp );
     480             :         }
     481           0 :         else if ( rProp.Name == "IsVolume" )
     482             :         {
     483             :             //What do we use this for ?
     484           0 :             xRow->appendBoolean( rProp, false );
     485             :         }
     486           0 :         else if ( rProp.Name == "IsCompactDisc" )
     487             :         {
     488           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT ) )
     489           0 :                 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT) );
     490             :             else
     491           0 :                 xRow->appendVoid( rProp );
     492             :         }
     493           0 :         else if ( rProp.Name == "IsRemoveable" )
     494             :         {
     495           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) )
     496           0 :                 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) );
     497             :             else
     498           0 :                 xRow->appendVoid( rProp );
     499             :         }
     500           0 :         else if ( rProp.Name == "IsFloppy" )
     501             :         {
     502           0 :             xRow->appendBoolean( rProp, false );
     503             :         }
     504           0 :         else if ( rProp.Name == "IsHidden" )
     505             :         {
     506           0 :             if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) )
     507           0 :                 xRow->appendBoolean( rProp, ( g_file_info_get_is_hidden ( pInfo ) ) );
     508             :             else
     509           0 :                 xRow->appendVoid( rProp );
     510             :         }
     511           0 :         else if ( rProp.Name == "CreatableContentsInfo" )
     512             :         {
     513           0 :             xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
     514             :         }
     515             :         else
     516             :         {
     517             :             SAL_WARN(
     518             :                 "ucb.ucp.gio",
     519             :                 "Looking for unsupported property " << rProp.Name);
     520             :         }
     521             :     }
     522             : 
     523           0 :     return uno::Reference< sdbc::XRow >( xRow.get() );
     524             : }
     525             : 
     526           0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
     527             :                 const uno::Sequence< beans::Property >& rProperties,
     528             :                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     529             : {
     530           0 :     GFileInfo *pInfo = getGFileInfo(xEnv);
     531           0 :     return getPropertyValuesFromGFileInfo(pInfo, m_xContext, xEnv, rProperties);
     532             : }
     533             : 
     534             : static lang::IllegalAccessException
     535           0 : getReadOnlyException( const uno::Reference< uno::XInterface >& rContext )
     536             : {
     537           0 :     return lang::IllegalAccessException ("Property is read-only!", rContext );
     538             : }
     539             : 
     540           0 : void Content::queryChildren( ContentRefList& rChildren )
     541             : {
     542             :     // Obtain a list with a snapshot of all currently instanciated contents
     543             :     // from provider and extract the contents which are direct children
     544             :     // of this content.
     545             : 
     546           0 :     ucbhelper::ContentRefList aAllContents;
     547           0 :     m_xProvider->queryExistingContents( aAllContents );
     548             : 
     549           0 :     OUString aURL = m_xIdentifier->getContentIdentifier();
     550           0 :     sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
     551             : 
     552           0 :     if ( nURLPos != ( aURL.getLength() - 1 ) )
     553           0 :         aURL += "/";
     554             : 
     555           0 :     sal_Int32 nLen = aURL.getLength();
     556             : 
     557           0 :     ucbhelper::ContentRefList::const_iterator it  = aAllContents.begin();
     558           0 :     ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
     559             : 
     560           0 :     while ( it != end )
     561             :     {
     562           0 :         ucbhelper::ContentImplHelperRef xChild = (*it);
     563           0 :         OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
     564             : 
     565             :         // Is aURL a prefix of aChildURL?
     566           0 :         if ( ( aChildURL.getLength() > nLen ) && ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
     567             :         {
     568           0 :             sal_Int32 nPos = nLen;
     569           0 :             nPos = aChildURL.indexOf( '/', nPos );
     570             : 
     571           0 :             if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) )
     572             :             {
     573             :                 // No further slashes / only a final slash. It's a child!
     574           0 :                 rChildren.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content * >(xChild.get() ) ) );
     575             :             }
     576             :         }
     577           0 :         ++it;
     578           0 :     }
     579           0 : }
     580             : 
     581           0 : sal_Bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
     582             : {
     583           0 :     if ( !xNewId.is() )
     584           0 :         return sal_False;
     585             : 
     586           0 :     uno::Reference< ucb::XContent > xThis = this;
     587             : 
     588           0 :     if ( mbTransient )
     589             :     {
     590           0 :         m_xIdentifier = xNewId;
     591           0 :         return sal_False;
     592             :     }
     593             : 
     594           0 :     OUString aOldURL = m_xIdentifier->getContentIdentifier();
     595             : 
     596             :     // Exchange own identitity.
     597           0 :     if ( exchange( xNewId ) )
     598             :     {
     599             :         // Process instanciated children...
     600           0 :         ContentRefList aChildren;
     601           0 :         queryChildren( aChildren );
     602             : 
     603           0 :         ContentRefList::const_iterator it  = aChildren.begin();
     604           0 :         ContentRefList::const_iterator end = aChildren.end();
     605             : 
     606           0 :         while ( it != end )
     607             :         {
     608           0 :             ContentRef xChild = (*it);
     609             : 
     610             :             // Create new content identifier for the child...
     611           0 :             uno::Reference< ucb::XContentIdentifier > xOldChildId = xChild->getIdentifier();
     612           0 :             OUString aOldChildURL = xOldChildId->getContentIdentifier();
     613             :             OUString aNewChildURL = aOldChildURL.replaceAt(
     614           0 :                 0, aOldURL.getLength(), xNewId->getContentIdentifier() );
     615             : 
     616             :             uno::Reference< ucb::XContentIdentifier > xNewChildId
     617           0 :                 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
     618             : 
     619           0 :             if ( !xChild->exchangeIdentity( xNewChildId ) )
     620           0 :                 return sal_False;
     621             : 
     622           0 :             ++it;
     623           0 :          }
     624           0 :          return sal_True;
     625             :     }
     626             : 
     627           0 :     return sal_False;
     628             : }
     629             : 
     630           0 : uno::Sequence< uno::Any > Content::setPropertyValues(
     631             :     const uno::Sequence< beans::PropertyValue >& rValues,
     632             :     const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     633             : {
     634           0 :     GError *pError=NULL;
     635           0 :     GFileInfo *pNewInfo=NULL;
     636           0 :     GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
     637           0 :     if (pInfo)
     638           0 :         pNewInfo = g_file_info_dup(pInfo);
     639             :     else
     640             :     {
     641           0 :         if (!mbTransient)
     642           0 :             ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
     643             :         else
     644             :         {
     645           0 :             if (pError)
     646           0 :                 g_error_free(pError);
     647           0 :             pNewInfo = g_file_info_new();
     648             :         }
     649             :     }
     650             : 
     651           0 :     sal_Int32 nCount = rValues.getLength();
     652             : 
     653           0 :     beans::PropertyChangeEvent aEvent;
     654           0 :     aEvent.Source = static_cast< cppu::OWeakObject * >( this );
     655           0 :     aEvent.Further = sal_False;
     656           0 :     aEvent.PropertyHandle = -1;
     657             : 
     658           0 :     sal_Int32 nChanged = 0, nTitlePos = -1;
     659           0 :     const char *newName = NULL;
     660           0 :     uno::Sequence< beans::PropertyChangeEvent > aChanges(nCount);
     661             : 
     662           0 :     uno::Sequence< uno::Any > aRet( nCount );
     663           0 :     const beans::PropertyValue* pValues = rValues.getConstArray();
     664           0 :     for ( sal_Int32 n = 0; n < nCount; ++n )
     665             :     {
     666           0 :         const beans::PropertyValue& rValue = pValues[ n ];
     667             : #if OSL_DEBUG_LEVEL > 1
     668             :         g_warning("Set prop '%s'", OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
     669             : #endif
     670           0 :         if ( rValue.Name == "ContentType" ||
     671           0 :              rValue.Name == "MediaType" ||
     672           0 :              rValue.Name == "IsDocument" ||
     673           0 :              rValue.Name == "IsFolder" ||
     674           0 :              rValue.Name == "Size" ||
     675           0 :              rValue.Name == "CreatableContentsInfo" )
     676             :         {
     677           0 :             aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
     678             :         }
     679           0 :         else if ( rValue.Name == "Title" )
     680             :         {
     681           0 :             OUString aNewTitle;
     682           0 :             if (!( rValue.Value >>= aNewTitle ))
     683             :             {
     684           0 :                 aRet[ n ] <<= beans::IllegalTypeException
     685             :                     ( OUString("Property value has wrong type!"),
     686           0 :                       static_cast< cppu::OWeakObject * >( this ) );
     687           0 :                 continue;
     688             :             }
     689             : 
     690           0 :             if ( aNewTitle.getLength() <= 0 )
     691             :             {
     692           0 :                 aRet[ n ] <<= lang::IllegalArgumentException
     693             :                     ( OUString("Empty title not allowed!"),
     694           0 :                       static_cast< cppu::OWeakObject * >( this ), -1 );
     695           0 :                 continue;
     696             : 
     697             :             }
     698             : 
     699           0 :             OString sNewTitle = OUStringToOString(aNewTitle, RTL_TEXTENCODING_UTF8);
     700           0 :             newName = sNewTitle.getStr();
     701           0 :             const char *oldName = g_file_info_get_name( pInfo);
     702             : 
     703           0 :             if (!newName || !oldName || strcmp(newName, oldName))
     704             :             {
     705             : #if OSL_DEBUG_LEVEL > 1
     706             :                 g_warning ("Set new name to '%s'", newName);
     707             : #endif
     708             : 
     709           0 :                 aEvent.PropertyName = "Title";
     710           0 :                 if (oldName)
     711           0 :                     aEvent.OldValue = uno::makeAny(OUString(oldName, strlen(oldName), RTL_TEXTENCODING_UTF8));
     712           0 :                 aEvent.NewValue = uno::makeAny(aNewTitle);
     713           0 :                 aChanges.getArray()[ nChanged ] = aEvent;
     714           0 :                 nTitlePos = nChanged++;
     715             : 
     716           0 :                 g_file_info_set_name(pNewInfo, newName);
     717           0 :             }
     718             :         }
     719             :         else
     720             :         {
     721             : #ifdef DEBUG
     722             :             fprintf(stderr, "Unknown property %s\n", OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
     723             : #endif
     724           0 :             aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
     725             :             //TODO
     726             :         }
     727             :     }
     728             : 
     729           0 :     if (nChanged)
     730             :     {
     731           0 :         bool bOk = true;
     732           0 :         if (!mbTransient)
     733             :         {
     734           0 :             if ((bOk = doSetFileInfo(pNewInfo)))
     735             :             {
     736           0 :                 for (sal_Int32 i = 0; i < nChanged; ++i)
     737           0 :                     aRet[ i ] <<= getBadArgExcept();
     738             :             }
     739             :         }
     740             : 
     741           0 :         if (bOk)
     742             :         {
     743           0 :             if (nTitlePos > -1)
     744             :             {
     745           0 :                 OUString aNewURL = getParentURL();
     746           0 :                 aNewURL += OUString( newName, strlen(newName), RTL_TEXTENCODING_UTF8 );
     747             :                 uno::Reference< ucb::XContentIdentifier > xNewId
     748           0 :                     = new ::ucbhelper::ContentIdentifier( aNewURL );
     749             : 
     750           0 :                 if (!exchangeIdentity( xNewId ) )
     751             :                 {
     752           0 :                     aRet[ nTitlePos ] <<= uno::Exception
     753             :                         ( OUString("Exchange failed!"),
     754           0 :                           static_cast< cppu::OWeakObject * >( this ) );
     755           0 :                 }
     756             :             }
     757             : 
     758           0 :             if (!mbTransient) //Discard and refetch
     759             :             {
     760           0 :                 g_object_unref(mpInfo);
     761           0 :                 mpInfo = NULL;
     762             :             }
     763             : 
     764           0 :             if (mpInfo)
     765             :             {
     766           0 :                 g_file_info_copy_into(pNewInfo, mpInfo);
     767           0 :                 g_object_unref(pNewInfo);
     768             :             }
     769             :             else
     770           0 :                 mpInfo = pNewInfo;
     771             : 
     772           0 :             if (mpFile) //Discard and refetch
     773             :             {
     774           0 :                 g_object_unref(mpFile);
     775           0 :                 mpFile = NULL;
     776             :             }
     777             :         }
     778             : 
     779           0 :         aChanges.realloc( nChanged );
     780           0 :         notifyPropertiesChange( aChanges );
     781             :     }
     782             : 
     783           0 :     return aRet;
     784             : }
     785             : 
     786           0 : bool Content::doSetFileInfo(GFileInfo *pNewInfo)
     787             : {
     788           0 :     g_assert (!mbTransient);
     789             : 
     790           0 :     bool bOk = true;
     791           0 :     GFile *pFile = getGFile();
     792           0 :     if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
     793           0 :         bOk = false;
     794           0 :     return bOk;
     795             : }
     796             : 
     797             : const int TRANSFER_BUFFER_SIZE = 65536;
     798             : 
     799           0 : void Content::copyData( uno::Reference< io::XInputStream > xIn,
     800             :     uno::Reference< io::XOutputStream > xOut )
     801             : {
     802           0 :     uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
     803             : 
     804           0 :     g_return_if_fail( xIn.is() && xOut.is() );
     805             : 
     806           0 :     while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
     807           0 :         xOut->writeBytes( theData );
     808             : 
     809           0 :     xOut->closeOutput();
     810             : }
     811             : 
     812           0 : sal_Bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
     813             :     const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
     814             : {
     815           0 :     if ( !xSink.is() )
     816           0 :         return sal_False;
     817             : 
     818           0 :     uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
     819           0 :     uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
     820             : 
     821           0 :     if ( !xOut.is() && !xDataSink.is() )
     822           0 :         return sal_False;
     823             : 
     824           0 :     GError *pError=NULL;
     825           0 :     GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
     826           0 :     if (!pStream)
     827           0 :        convertToException(pError, static_cast< cppu::OWeakObject * >(this));
     828             : 
     829           0 :     uno::Reference< io::XInputStream > xIn = new ::gio::InputStream(pStream);
     830           0 :     if ( !xIn.is() )
     831           0 :         return sal_False;
     832             : 
     833           0 :     if ( xOut.is() )
     834           0 :         copyData( xIn, xOut );
     835             : 
     836           0 :     if ( xDataSink.is() )
     837           0 :         xDataSink->setInputStream( xIn );
     838             : 
     839           0 :     return sal_True;
     840             : }
     841             : 
     842           0 : uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
     843             :     const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     844             :     throw( uno::Exception )
     845             : {
     846           0 :     bool bIsFolder = isFolder(xEnv);
     847             : 
     848           0 :     if (!g_file_query_exists(getGFile(), NULL))
     849             :     {
     850           0 :         uno::Sequence< uno::Any > aArgs( 1 );
     851           0 :         aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
     852             :         uno::Any aErr = uno::makeAny(
     853             :             ucb::InteractiveAugmentedIOException(OUString(), static_cast< cppu::OWeakObject * >( this ),
     854             :                 task::InteractionClassification_ERROR,
     855             :                 bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
     856           0 :         );
     857             : 
     858           0 :         ucbhelper::cancelCommandExecution(aErr, xEnv);
     859             :     }
     860             : 
     861           0 :     uno::Any aRet;
     862             : 
     863             :     sal_Bool bOpenFolder = (
     864           0 :         ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
     865           0 :         ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
     866           0 :         ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
     867           0 :      );
     868             : 
     869           0 :     if ( bOpenFolder && bIsFolder )
     870             :     {
     871             :         uno::Reference< ucb::XDynamicResultSet > xSet
     872           0 :             = new DynamicResultSet( m_xContext, this, rOpenCommand, xEnv );
     873           0 :         aRet <<= xSet;
     874             :     }
     875           0 :     else if ( rOpenCommand.Sink.is() )
     876             :     {
     877           0 :         if (
     878           0 :             ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
     879           0 :             ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
     880             :            )
     881             :         {
     882             :             ucbhelper::cancelCommandExecution(
     883             :                 uno::makeAny ( ucb::UnsupportedOpenModeException
     884             :                     ( OUString(), static_cast< cppu::OWeakObject * >( this ),
     885             :                       sal_Int16( rOpenCommand.Mode ) ) ),
     886           0 :                     xEnv );
     887             :         }
     888             : 
     889           0 :         if ( !feedSink( rOpenCommand.Sink, xEnv ) )
     890             :         {
     891             :             // Note: rOpenCommand.Sink may contain an XStream
     892             :             //       implementation. Support for this type of
     893             :             //       sink is optional...
     894             : #ifdef DEBUG
     895             :             g_warning ("Failed to load data from '%s'",
     896             :                 OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
     897             : #endif
     898             : 
     899             :             ucbhelper::cancelCommandExecution(
     900             :                 uno::makeAny (ucb::UnsupportedDataSinkException
     901             :                     ( OUString(), static_cast< cppu::OWeakObject * >( this ),
     902             :                       rOpenCommand.Sink ) ),
     903           0 :                     xEnv );
     904             :         }
     905             :     }
     906             :     else
     907           0 :         g_warning ("Open falling through ...");
     908           0 :     return aRet;
     909             : }
     910             : 
     911           0 : uno::Any SAL_CALL Content::execute(
     912             :         const ucb::Command& aCommand,
     913             :         sal_Int32 /*CommandId*/,
     914             :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     915             :     throw( uno::Exception,
     916             :            ucb::CommandAbortedException,
     917             :            uno::RuntimeException, std::exception )
     918             : {
     919             : #if OSL_DEBUG_LEVEL > 1
     920             :     fprintf(stderr, "Content::execute %s\n", OUStringToOString(aCommand.Name, RTL_TEXTENCODING_UTF8).getStr());
     921             : #endif
     922           0 :     uno::Any aRet;
     923             : 
     924           0 :     if ( aCommand.Name == "getPropertyValues" )
     925             :     {
     926           0 :         uno::Sequence< beans::Property > Properties;
     927           0 :         if ( !( aCommand.Argument >>= Properties ) )
     928           0 :             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     929           0 :         aRet <<= getPropertyValues( Properties, xEnv );
     930             :     }
     931           0 :     else if ( aCommand.Name == "getPropertySetInfo" )
     932           0 :         aRet <<= getPropertySetInfo( xEnv, false );
     933           0 :     else if ( aCommand.Name == "getCommandInfo" )
     934           0 :         aRet <<= getCommandInfo( xEnv, false );
     935           0 :     else if ( aCommand.Name == "open" )
     936             :     {
     937           0 :         ucb::OpenCommandArgument2 aOpenCommand;
     938           0 :         if ( !( aCommand.Argument >>= aOpenCommand ) )
     939           0 :             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     940           0 :         aRet = open( aOpenCommand, xEnv );
     941             :     }
     942           0 :     else if ( aCommand.Name == "transfer" )
     943             :     {
     944           0 :         ucb::TransferInfo transferArgs;
     945           0 :         if ( !( aCommand.Argument >>= transferArgs ) )
     946           0 :             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     947           0 :         transfer( transferArgs, xEnv );
     948             :     }
     949           0 :     else if ( aCommand.Name == "setPropertyValues" )
     950             :     {
     951           0 :         uno::Sequence< beans::PropertyValue > aProperties;
     952           0 :         if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
     953           0 :             ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     954           0 :         aRet <<= setPropertyValues( aProperties, xEnv );
     955             :     }
     956           0 :     else if (aCommand.Name == "createNewContent"
     957           0 :              && isFolder( xEnv ) )
     958             :     {
     959           0 :         ucb::ContentInfo arg;
     960           0 :         if ( !( aCommand.Argument >>= arg ) )
     961           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     962           0 :         aRet <<= createNewContent( arg );
     963             :     }
     964           0 :     else if ( aCommand.Name == "insert" )
     965             :     {
     966           0 :         ucb::InsertCommandArgument arg;
     967           0 :         if ( !( aCommand.Argument >>= arg ) )
     968           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     969           0 :         insert( arg.Data, arg.ReplaceExisting, xEnv );
     970             :     }
     971           0 :     else if ( aCommand.Name == "delete" )
     972             :     {
     973           0 :         sal_Bool bDeletePhysical = sal_False;
     974           0 :         aCommand.Argument >>= bDeletePhysical;
     975             : 
     976             :         //If no delete physical, try and trashcan it, if that doesn't work go
     977             :         //ahead and try and delete it anyway
     978           0 :         if (!bDeletePhysical && !g_file_trash(getGFile(), NULL, NULL))
     979           0 :                 bDeletePhysical = true;
     980             : 
     981           0 :         if (bDeletePhysical)
     982             :         {
     983           0 :             GError *pError = NULL;
     984           0 :             if (!g_file_delete( getGFile(), NULL, &pError))
     985           0 :                 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
     986             :         }
     987             : 
     988           0 :         destroy( bDeletePhysical );
     989             :     }
     990             :     else
     991             :     {
     992             : #ifdef DEBUG
     993             :         fprintf(stderr, "UNKNOWN COMMAND\n");
     994             :         //TODO
     995             : #endif
     996             : 
     997             :         ucbhelper::cancelCommandExecution
     998             :             ( uno::makeAny( ucb::UnsupportedCommandException
     999             :               ( OUString(),
    1000             :                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1001           0 :               xEnv );
    1002             :     }
    1003             : 
    1004           0 :     return aRet;
    1005             : }
    1006             : 
    1007           0 : void Content::destroy( sal_Bool bDeletePhysical )
    1008             :     throw( uno::Exception )
    1009             : {
    1010           0 :     uno::Reference< ucb::XContent > xThis = this;
    1011             : 
    1012           0 :     deleted();
    1013             : 
    1014           0 :     ::gio::Content::ContentRefList aChildren;
    1015           0 :     queryChildren( aChildren );
    1016             : 
    1017           0 :     ContentRefList::const_iterator it  = aChildren.begin();
    1018           0 :     ContentRefList::const_iterator end = aChildren.end();
    1019             : 
    1020           0 :     while ( it != end )
    1021             :     {
    1022           0 :         (*it)->destroy( bDeletePhysical );
    1023           0 :         ++it;
    1024           0 :     }
    1025           0 : }
    1026             : 
    1027           0 : void Content::insert(const uno::Reference< io::XInputStream > &xInputStream,
    1028             :     sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment > &xEnv )
    1029             :         throw( uno::Exception )
    1030             : {
    1031           0 :     GError *pError = NULL;
    1032           0 :     GFileInfo *pInfo = getGFileInfo(xEnv);
    1033             : 
    1034           0 :     if ( pInfo &&
    1035           0 :          g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
    1036           0 :          g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY )
    1037             :     {
    1038             : #if OSL_DEBUG_LEVEL > 1
    1039             :         g_warning ("Make directory");
    1040             : #endif
    1041           0 :         if( !g_file_make_directory( getGFile(), NULL, &pError))
    1042           0 :             ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
    1043           0 :         return;
    1044             :     }
    1045             : 
    1046           0 :     if ( !xInputStream.is() )
    1047             :     {
    1048             :         ucbhelper::cancelCommandExecution( uno::makeAny
    1049             :             ( ucb::MissingInputStreamException
    1050             :               ( OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
    1051           0 :             xEnv );
    1052             :     }
    1053             : 
    1054           0 :     GFileOutputStream* pOutStream = NULL;
    1055           0 :     if ( bReplaceExisting )
    1056             :     {
    1057           0 :         if (!(pOutStream = g_file_replace(getGFile(), NULL, false, G_FILE_CREATE_PRIVATE, NULL, &pError)))
    1058           0 :             ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
    1059             :     }
    1060             :     else
    1061             :     {
    1062           0 :         if (!(pOutStream = g_file_create (getGFile(), G_FILE_CREATE_PRIVATE, NULL, &pError)))
    1063           0 :             ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
    1064             :     }
    1065             : 
    1066           0 :     uno::Reference < io::XOutputStream > xOutput = new ::gio::OutputStream(pOutStream);
    1067           0 :     copyData( xInputStream, xOutput );
    1068             : 
    1069           0 :     if (mbTransient)
    1070             :     {
    1071           0 :         mbTransient = false;
    1072           0 :         inserted();
    1073           0 :     }
    1074             : }
    1075             : 
    1076             : const GFileCopyFlags DEFAULT_COPYDATA_FLAGS =
    1077             :     static_cast<GFileCopyFlags>(G_FILE_COPY_OVERWRITE|G_FILE_COPY_TARGET_DEFAULT_PERMS);
    1078             : 
    1079           0 : void Content::transfer( const ucb::TransferInfo& aTransferInfo, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1080             :     throw( uno::Exception )
    1081             : {
    1082           0 :     OUString sDest = m_xIdentifier->getContentIdentifier();
    1083           0 :     if (!sDest.endsWith("/")) {
    1084           0 :         sDest += "/";
    1085             :     }
    1086           0 :     if (aTransferInfo.NewTitle.getLength())
    1087           0 :         sDest += aTransferInfo.NewTitle;
    1088             :     else
    1089           0 :         sDest += OUString::createFromAscii(g_file_get_basename(getGFile()));
    1090             : 
    1091           0 :     GFile *pDest = g_file_new_for_uri(OUStringToOString(sDest, RTL_TEXTENCODING_UTF8).getStr());
    1092           0 :     GFile *pSource = g_file_new_for_uri(OUStringToOString(aTransferInfo.SourceURL, RTL_TEXTENCODING_UTF8).getStr());
    1093             : 
    1094           0 :     gboolean bSuccess = false;
    1095           0 :     GError *pError = NULL;
    1096           0 :     if (aTransferInfo.MoveData)
    1097           0 :         bSuccess = g_file_move(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
    1098             :     else
    1099           0 :         bSuccess = g_file_copy(pSource, pDest, DEFAULT_COPYDATA_FLAGS, NULL, NULL, 0, &pError);
    1100           0 :     g_object_unref(pSource);
    1101           0 :     g_object_unref(pDest);
    1102           0 :     if (!bSuccess)
    1103           0 :         ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
    1104           0 : }
    1105             : 
    1106           0 : uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
    1107             :     const uno::Reference< ucb::XCommandEnvironment >& xEnv)
    1108             :             throw( uno::RuntimeException )
    1109             : {
    1110           0 :     if ( isFolder( xEnv ) )
    1111             :     {
    1112           0 :         uno::Sequence< ucb::ContentInfo > seq(2);
    1113             : 
    1114             :         // Minimum set of props we really need
    1115           0 :         uno::Sequence< beans::Property > props( 1 );
    1116           0 :         props[0] = beans::Property(
    1117             :             OUString("Title"),
    1118             :             -1,
    1119           0 :             getCppuType( static_cast< OUString* >( 0 ) ),
    1120           0 :             beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
    1121             : 
    1122             :         // file
    1123           0 :         seq[0].Type       = OUString( GIO_FILE_TYPE );
    1124           0 :         seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
    1125           0 :                               ucb::ContentInfoAttribute::KIND_DOCUMENT );
    1126           0 :         seq[0].Properties = props;
    1127             : 
    1128             :         // folder
    1129           0 :         seq[1].Type       = OUString( GIO_FOLDER_TYPE );
    1130           0 :         seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
    1131           0 :         seq[1].Properties = props;
    1132             : 
    1133           0 :         return seq;
    1134             :     }
    1135             :     else
    1136             :     {
    1137           0 :         return uno::Sequence< ucb::ContentInfo >();
    1138             :     }
    1139             : }
    1140             : 
    1141           0 : uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
    1142             :             throw( uno::RuntimeException, std::exception )
    1143             : {
    1144           0 :     return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
    1145             : }
    1146             : 
    1147             : uno::Reference< ucb::XContent >
    1148           0 :     SAL_CALL Content::createNewContent( const ucb::ContentInfo& Info )
    1149             :         throw( uno::RuntimeException, std::exception )
    1150             : {
    1151             :     bool create_document;
    1152             :     const char *name;
    1153             : 
    1154           0 :     if ( Info.Type == GIO_FILE_TYPE )
    1155           0 :         create_document = true;
    1156           0 :     else if ( Info.Type == GIO_FOLDER_TYPE )
    1157           0 :         create_document = false;
    1158             :     else
    1159             :     {
    1160             : #ifdef DEBUG
    1161             :         g_warning( "Failed to create new content '%s'", OUStringToOString(Info.Type,
    1162             :             RTL_TEXTENCODING_UTF8).getStr() );
    1163             : #endif
    1164           0 :         return uno::Reference< ucb::XContent >();
    1165             :     }
    1166             : 
    1167             : #if OSL_DEBUG_LEVEL > 1
    1168             :     g_warning( "createNewContent (%d)", (int) create_document );
    1169             : #endif
    1170             : 
    1171           0 :     OUString aURL = m_xIdentifier->getContentIdentifier();
    1172             : 
    1173           0 :     if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
    1174           0 :             aURL += "/";
    1175             : 
    1176           0 :     name = create_document ? "[New_Content]" : "[New_Collection]";
    1177           0 :     aURL += OUString::createFromAscii( name );
    1178             : 
    1179           0 :     uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(aURL));
    1180             : 
    1181             :     try
    1182             :     {
    1183           0 :         return new ::gio::Content( m_xContext, m_pProvider, xId, !create_document );
    1184           0 :     } catch ( ucb::ContentCreationException & )
    1185             :     {
    1186           0 :             return uno::Reference< ucb::XContent >();
    1187           0 :     }
    1188             : }
    1189             : 
    1190           0 : uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
    1191             :     throw( uno::RuntimeException, std::exception )
    1192             : {
    1193           0 :     if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
    1194             :     {
    1195             :         static cppu::OTypeCollection aFolderCollection
    1196           0 :             (CPPU_TYPE_REF( lang::XTypeProvider ),
    1197           0 :              CPPU_TYPE_REF( lang::XServiceInfo ),
    1198           0 :              CPPU_TYPE_REF( lang::XComponent ),
    1199           0 :              CPPU_TYPE_REF( ucb::XContent ),
    1200           0 :              CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1201           0 :              CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1202           0 :              CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1203           0 :              CPPU_TYPE_REF( beans::XPropertyContainer ),
    1204           0 :              CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1205           0 :              CPPU_TYPE_REF( container::XChild ),
    1206           0 :              CPPU_TYPE_REF( ucb::XContentCreator ) );
    1207           0 :         return aFolderCollection.getTypes();
    1208             :     }
    1209             :     else
    1210             :     {
    1211             :         static cppu::OTypeCollection aFileCollection
    1212           0 :             (CPPU_TYPE_REF( lang::XTypeProvider ),
    1213           0 :              CPPU_TYPE_REF( lang::XServiceInfo ),
    1214           0 :              CPPU_TYPE_REF( lang::XComponent ),
    1215           0 :              CPPU_TYPE_REF( ucb::XContent ),
    1216           0 :              CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1217           0 :              CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1218           0 :              CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1219           0 :              CPPU_TYPE_REF( beans::XPropertyContainer ),
    1220           0 :              CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1221           0 :              CPPU_TYPE_REF( container::XChild ) );
    1222             : 
    1223           0 :         return aFileCollection.getTypes();
    1224             :     }
    1225             : }
    1226             : 
    1227           0 : uno::Sequence< beans::Property > Content::getProperties(
    1228             :     const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
    1229             : {
    1230             :     static const beans::Property aGenericProperties[] =
    1231             :     {
    1232             :         beans::Property( OUString(  "IsDocument"  ),
    1233           0 :             -1, getCppuBooleanType(),
    1234             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1235             :         beans::Property( OUString(  "IsFolder"  ),
    1236           0 :             -1, getCppuBooleanType(),
    1237             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1238             :         beans::Property( OUString(  "Title"  ),
    1239           0 :             -1, getCppuType( static_cast< const OUString * >( 0 ) ),
    1240             :             beans::PropertyAttribute::BOUND ),
    1241             :         beans::Property( OUString(  "IsReadOnly"  ),
    1242           0 :             -1, getCppuBooleanType(),
    1243             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1244             :         beans::Property( OUString(  "DateCreated"  ),
    1245           0 :             -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
    1246             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1247             :         beans::Property( OUString(  "DateModified"  ),
    1248           0 :             -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
    1249             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1250             :         beans::Property( OUString(  "Size"  ),
    1251           0 :             -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
    1252             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1253             :         beans::Property( OUString(  "IsVolume"  ),
    1254           0 :             -1, getCppuBooleanType(),
    1255             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1256             :         beans::Property( OUString(  "IsCompactDisc"  ),
    1257           0 :             -1, getCppuBooleanType(),
    1258             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1259             :         beans::Property( OUString(  "IsRemoveable"  ),
    1260           0 :             -1, getCppuBooleanType(),
    1261             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1262             :         beans::Property( OUString(  "IsHidden"  ),
    1263           0 :             -1, getCppuBooleanType(),
    1264             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1265             :         beans::Property( OUString(  "CreatableContentsInfo"  ),
    1266           0 :             -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
    1267             :             beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
    1268           0 :     };
    1269             : 
    1270           0 :     const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
    1271           0 :     return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
    1272             : }
    1273             : 
    1274           0 : uno::Sequence< ucb::CommandInfo > Content::getCommands( const uno::Reference< ucb::XCommandEnvironment > & xEnv)
    1275             : {
    1276             :     static const ucb::CommandInfo aCommandInfoTable[] =
    1277             :     {
    1278             :         // Required commands
    1279             :         ucb::CommandInfo
    1280             :         ( OUString(  "getCommandInfo"  ),
    1281           0 :           -1, getCppuVoidType() ),
    1282             :         ucb::CommandInfo
    1283             :         ( OUString(  "getPropertySetInfo"  ),
    1284           0 :           -1, getCppuVoidType() ),
    1285             :         ucb::CommandInfo
    1286             :         ( OUString(  "getPropertyValues"  ),
    1287           0 :           -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
    1288             :         ucb::CommandInfo
    1289             :         ( OUString(  "setPropertyValues"  ),
    1290           0 :           -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
    1291             : 
    1292             :         // Optional standard commands
    1293             :         ucb::CommandInfo
    1294             :         ( OUString(  "delete"  ),
    1295           0 :           -1, getCppuBooleanType() ),
    1296             :         ucb::CommandInfo
    1297             :         ( OUString(  "insert"  ),
    1298           0 :           -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
    1299             :         ucb::CommandInfo
    1300             :         ( OUString(  "open"  ),
    1301           0 :           -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
    1302             : 
    1303             :         // Folder Only, omitted if not a folder
    1304             :         ucb::CommandInfo
    1305             :         ( OUString(  "transfer"  ),
    1306           0 :           -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
    1307             :         ucb::CommandInfo
    1308             :         ( OUString(  "createNewContent"  ),
    1309           0 :           -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
    1310           0 :     };
    1311             : 
    1312           0 :     const int nProps = sizeof (aCommandInfoTable) / sizeof (aCommandInfoTable[0]);
    1313           0 :     return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 2);
    1314             : }
    1315             : 
    1316           0 : XTYPEPROVIDER_COMMON_IMPL( Content );
    1317             : 
    1318           0 : void SAL_CALL Content::acquire() throw()
    1319             : {
    1320           0 :     ContentImplHelper::acquire();
    1321           0 : }
    1322             : 
    1323           0 : void SAL_CALL Content::release() throw()
    1324             : {
    1325           0 :     ContentImplHelper::release();
    1326           0 : }
    1327             : 
    1328           0 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException, std::exception )
    1329             : {
    1330           0 :     uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
    1331           0 :     return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
    1332             : }
    1333             : 
    1334           0 : OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException, std::exception )
    1335             : {
    1336           0 :        return OUString("com.sun.star.comp.GIOContent");
    1337             : }
    1338             : 
    1339           0 : uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
    1340             :        throw( uno::RuntimeException, std::exception )
    1341             : {
    1342           0 :        uno::Sequence< OUString > aSNS( 1 );
    1343           0 :        aSNS.getArray()[ 0 ] = "com.sun.star.ucb.GIOContent";
    1344           0 :        return aSNS;
    1345             : }
    1346             : 
    1347             : }
    1348             : 
    1349             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10