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

Generated by: LCOV version 1.11