LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/ucb/source/ucp/gio - gio_content.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 85 603 14.1 %
Date: 2013-07-09 Functions: 15 46 32.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10