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

Generated by: LCOV version 1.10