1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <sys/types.h>
23 #include <sal/macros.h>
26 #include <osl/diagnose.h>
27 #include <osl/doublecheckedlocking.h>
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/InteractiveAugmentedIOException.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/InteractiveNetworkWriteException.hpp>
47 #include <com/sun/star/ucb/NameClash.hpp>
48 #include <com/sun/star/ucb/NameClashException.hpp>
49 #include <com/sun/star/ucb/OpenMode.hpp>
50 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
51 #include <com/sun/star/ucb/XCommandInfo.hpp>
52 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
53 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
54 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
55 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
56 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
57 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
58 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
59 #include <com/sun/star/ucb/NameClashException.hpp>
60 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
61 #include <com/sun/star/ucb/XContentCreator.hpp>
63 #include <comphelper/processfactory.hxx>
64 #include <ucbhelper/contentidentifier.hxx>
65 #include <ucbhelper/propertyvalueset.hxx>
66 #include <ucbhelper/interactionrequest.hxx>
67 #include <ucbhelper/cancelcommandexecution.hxx>
69 #include <osl/conditn.hxx>
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"
80 using namespace com::sun::star
;
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 m_pProvider( pProvider
), mpFile (NULL
), mpInfo( NULL
), mbTransient(false)
93 #if OSL_DEBUG_LEVEL > 1
94 fprintf(stderr
, "New Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
99 const uno::Reference
< uno::XComponentContext
>& rxContext
,
100 ContentProvider
* pProvider
,
101 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
103 throw ( ucb::ContentCreationException
)
104 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
105 m_pProvider( pProvider
), mpFile (NULL
), mpInfo( NULL
), mbTransient(true)
107 #if OSL_DEBUG_LEVEL > 1
108 fprintf(stderr
, "Create Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
110 mpInfo
= g_file_info_new();
111 g_file_info_set_file_type(mpInfo
, bIsFolder
? G_FILE_TYPE_DIRECTORY
: G_FILE_TYPE_REGULAR
);
116 if (mpInfo
) g_object_unref(mpInfo
);
117 if (mpFile
) g_object_unref(mpFile
);
120 rtl::OUString
Content::getParentURL()
123 if (GFile
* pFile
= g_file_get_parent(getGFile()))
125 char* pPath
= g_file_get_uri(pFile
);
126 g_object_unref(pFile
);
127 sURL
= rtl::OUString::createFromAscii(pPath
);
133 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
134 throw( uno::RuntimeException
)
137 //stick a map from each CommandId to a new GCancellable and propogate
138 //it throughout the g_file_* calls
141 rtl::OUString SAL_CALL
Content::getContentType() throw( uno::RuntimeException
)
143 return isFolder(uno::Reference
< ucb::XCommandEnvironment
>())
144 ? rtl::OUString( GIO_FOLDER_TYPE
)
145 : rtl::OUString( GIO_FILE_TYPE
);
148 #define EXCEPT(aExcept) \
150 if (bThrow) throw aExcept;\
151 aRet = uno::makeAny( aExcept );\
154 uno::Any
convertToException(GError
*pError
, const uno::Reference
< uno::XInterface
>& rContext
, bool bThrow
)
158 gint eCode
= pError
->code
;
159 rtl::OUString
sMessage(pError
->message
, strlen(pError
->message
), RTL_TEXTENCODING_UTF8
);
160 g_error_free(pError
);
165 uno::Sequence
< uno::Any
> aArgs( 1 );
166 aArgs
[ 0 ] <<= sName
;
170 case G_IO_ERROR_FAILED
:
171 { io::IOException
aExcept(sMessage
, rContext
);
174 case G_IO_ERROR_NOT_MOUNTED
:
175 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
176 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_EXISTING_PATH
, aArgs
);
179 case G_IO_ERROR_NOT_FOUND
:
180 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
181 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_EXISTING
, aArgs
);
184 case G_IO_ERROR_EXISTS
:
185 { ucb::NameClashException
aExcept(sMessage
, rContext
,
186 task::InteractionClassification_ERROR
, sName
);
189 case G_IO_ERROR_INVALID_ARGUMENT
:
190 { lang::IllegalArgumentException
aExcept(sMessage
, rContext
, -1 );
193 case G_IO_ERROR_PERMISSION_DENIED
:
194 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
195 task::InteractionClassification_ERROR
, ucb::IOErrorCode_ACCESS_DENIED
, aArgs
);
198 case G_IO_ERROR_IS_DIRECTORY
:
199 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
200 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_FILE
, aArgs
);
203 case G_IO_ERROR_NOT_REGULAR_FILE
:
204 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
205 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_FILE
, aArgs
);
208 case G_IO_ERROR_NOT_DIRECTORY
:
209 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
210 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_DIRECTORY
, aArgs
);
213 case G_IO_ERROR_FILENAME_TOO_LONG
:
214 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
215 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NAME_TOO_LONG
, aArgs
);
218 case G_IO_ERROR_PENDING
:
219 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
220 task::InteractionClassification_ERROR
, ucb::IOErrorCode_PENDING
, aArgs
);
223 case G_IO_ERROR_CLOSED
:
224 case G_IO_ERROR_CANCELLED
:
225 case G_IO_ERROR_TOO_MANY_LINKS
:
226 case G_IO_ERROR_WRONG_ETAG
:
227 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
228 task::InteractionClassification_ERROR
, ucb::IOErrorCode_GENERAL
, aArgs
);
231 case G_IO_ERROR_NOT_SUPPORTED
:
232 case G_IO_ERROR_CANT_CREATE_BACKUP
:
233 case G_IO_ERROR_WOULD_MERGE
:
234 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
235 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_SUPPORTED
, aArgs
);
238 case G_IO_ERROR_NO_SPACE
:
239 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
240 task::InteractionClassification_ERROR
, ucb::IOErrorCode_OUT_OF_DISK_SPACE
, aArgs
);
243 case G_IO_ERROR_INVALID_FILENAME
:
244 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
245 task::InteractionClassification_ERROR
, ucb::IOErrorCode_INVALID_CHARACTER
, aArgs
);
248 case G_IO_ERROR_READ_ONLY
:
249 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
250 task::InteractionClassification_ERROR
, ucb::IOErrorCode_WRITE_PROTECTED
, aArgs
);
253 case G_IO_ERROR_TIMED_OUT
:
254 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
255 task::InteractionClassification_ERROR
, ucb::IOErrorCode_DEVICE_NOT_READY
, aArgs
);
258 case G_IO_ERROR_WOULD_RECURSE
:
259 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
260 task::InteractionClassification_ERROR
, ucb::IOErrorCode_RECURSIVE
, aArgs
);
263 case G_IO_ERROR_BUSY
:
264 case G_IO_ERROR_WOULD_BLOCK
:
265 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
266 task::InteractionClassification_ERROR
, ucb::IOErrorCode_LOCKING_VIOLATION
, aArgs
);
269 case G_IO_ERROR_HOST_NOT_FOUND
:
270 { ucb::InteractiveNetworkResolveNameException
aExcept(sMessage
, rContext
,
271 task::InteractionClassification_ERROR
, sHost
);
275 case G_IO_ERROR_ALREADY_MOUNTED
:
276 case G_IO_ERROR_NOT_EMPTY
:
277 case G_IO_ERROR_NOT_SYMBOLIC_LINK
:
278 case G_IO_ERROR_NOT_MOUNTABLE_FILE
:
279 case G_IO_ERROR_FAILED_HANDLED
:
280 { ucb::InteractiveNetworkGeneralException
aExcept(sMessage
, rContext
,
281 task::InteractionClassification_ERROR
);
288 uno::Any
Content::mapGIOError( GError
*pError
)
291 return getBadArgExcept();
293 return convertToException(pError
, static_cast< cppu::OWeakObject
* >(this), false);
296 uno::Any
Content::getBadArgExcept()
298 return uno::makeAny( lang::IllegalArgumentException(
299 rtl::OUString("Wrong argument type!"),
300 static_cast< cppu::OWeakObject
* >( this ), -1) );
306 GMountOperation
*mpAuthentication
;
308 static void Completed(GObject
*source
, GAsyncResult
*res
, gpointer user_data
);
310 MountOperation(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
);
312 GError
*Mount(GFile
*pFile
);
315 MountOperation::MountOperation(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
) : mpError(NULL
)
317 mpLoop
= g_main_loop_new(NULL
, FALSE
);
318 mpAuthentication
= ooo_mount_operation_new(xEnv
);
321 void MountOperation::Completed(GObject
*source
, GAsyncResult
*res
, gpointer user_data
)
323 MountOperation
*pThis
= (MountOperation
*)user_data
;
324 g_file_mount_enclosing_volume_finish(G_FILE(source
), res
, &(pThis
->mpError
));
325 g_main_loop_quit(pThis
->mpLoop
);
328 GError
*MountOperation::Mount(GFile
*pFile
)
330 g_file_mount_enclosing_volume(pFile
, G_MOUNT_MOUNT_NONE
, mpAuthentication
, NULL
, MountOperation::Completed
, this);
331 g_main_loop_run(mpLoop
);
335 MountOperation::~MountOperation()
337 g_object_unref(mpAuthentication
);
338 g_main_loop_unref(mpLoop
);
341 GFileInfo
* Content::getGFileInfo(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
, GError
**ppError
)
343 /*If we don't have it already, and we're not a "pre-creation" content then query for the info"*/
344 if (!mpInfo
&& !mbTransient
)
346 if (!(mpInfo
= g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE
, NULL
, ppError
)))
348 //Try and mount if unmounted
349 if (ppError
&& (*ppError
)->code
== G_IO_ERROR_NOT_MOUNTED
)
351 g_error_free(*ppError
);
353 MountOperation
aMounter(xEnv
);
354 *ppError
= aMounter
.Mount(getGFile());
356 //No Mount error, reattempt query
358 mpInfo
= g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE
, NULL
, ppError
);
365 GFile
* Content::getGFile()
368 mpFile
= g_file_new_for_uri(rtl::OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
372 bool Content::isFolder(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
374 GFileInfo
*pInfo
= getGFileInfo(xEnv
);
375 return pInfo
&& (g_file_info_get_file_type(pInfo
) == G_FILE_TYPE_DIRECTORY
);
378 static util::DateTime
getDateFromUnix (time_t t
)
385 if ( osl_getDateTimeFromTimeValue( &tv
, &dt
) )
386 return util::DateTime( 0, dt
.Seconds
, dt
.Minutes
, dt
.Hours
,
387 dt
.Day
, dt
.Month
, dt
.Year
);
389 return util::DateTime();
392 uno::Reference
< sdbc::XRow
> Content::getPropertyValuesFromGFileInfo(GFileInfo
*pInfo
,
393 const uno::Reference
< uno::XComponentContext
>& rxContext
,
394 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
,
395 const uno::Sequence
< beans::Property
>& rProperties
)
397 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
= new ::ucbhelper::PropertyValueSet( rxContext
);
400 const beans::Property
* pProps
;
402 nProps
= rProperties
.getLength();
403 pProps
= rProperties
.getConstArray();
405 for( sal_Int32 n
= 0; n
< nProps
; ++n
)
407 const beans::Property
& rProp
= pProps
[ n
];
409 if ( rProp
.Name
== "IsDocument" )
411 if (g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
))
412 xRow
->appendBoolean( rProp
, ( g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_REGULAR
||
413 g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_UNKNOWN
) );
415 xRow
->appendVoid( rProp
);
417 else if ( rProp
.Name
== "IsFolder" )
419 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
) )
420 xRow
->appendBoolean( rProp
, ( g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_DIRECTORY
));
422 xRow
->appendVoid( rProp
);
424 else if ( rProp
.Name
== "Title" )
426 if (g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
))
428 const char *pName
= g_file_info_get_display_name(pInfo
);
429 xRow
->appendString( rProp
, rtl::OUString(pName
, strlen(pName
), RTL_TEXTENCODING_UTF8
) );
432 xRow
->appendVoid( rProp
);
434 else if ( rProp
.Name
== "IsReadOnly" )
436 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
) )
437 xRow
->appendBoolean( rProp
, !g_file_info_get_attribute_boolean( pInfo
, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
) );
439 xRow
->appendVoid( rProp
);
441 else if ( rProp
.Name
== "DateCreated" )
443 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_TIME_CREATED
) )
444 xRow
->appendTimestamp( rProp
, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo
, G_FILE_ATTRIBUTE_TIME_CREATED
)) );
446 xRow
->appendVoid( rProp
);
448 else if ( rProp
.Name
== "DateModified" )
450 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_TIME_CHANGED
) )
451 xRow
->appendTimestamp( rProp
, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo
, G_FILE_ATTRIBUTE_TIME_CHANGED
)) );
453 xRow
->appendVoid( rProp
);
455 else if ( rProp
.Name
== "Size" )
457 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_SIZE
) )
458 xRow
->appendLong( rProp
, ( g_file_info_get_size( pInfo
) ));
460 xRow
->appendVoid( rProp
);
462 else if ( rProp
.Name
== "IsVolume" )
464 //What do we use this for ?
465 xRow
->appendBoolean( rProp
, sal_False
);
467 else if ( rProp
.Name
== "IsCompactDisc" )
469 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
) )
470 xRow
->appendBoolean( rProp
, g_file_info_get_attribute_boolean(pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
) );
472 xRow
->appendVoid( rProp
);
474 else if ( rProp
.Name
== "IsRemoveable" )
476 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
) )
477 xRow
->appendBoolean( rProp
, g_file_info_get_attribute_boolean(pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
) );
479 xRow
->appendVoid( rProp
);
481 else if ( rProp
.Name
== "IsFloppy" )
483 xRow
->appendBoolean( rProp
, sal_False
);
485 else if ( rProp
.Name
== "IsHidden" )
487 if( g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN
) )
488 xRow
->appendBoolean( rProp
, ( g_file_info_get_is_hidden ( pInfo
) ) );
490 xRow
->appendVoid( rProp
);
492 else if ( rProp
.Name
== "CreatableContentsInfo" )
494 xRow
->appendObject( rProp
, uno::makeAny( queryCreatableContentsInfo( xEnv
) ) );
499 fprintf(stderr
, "Looking for unsupported property %s\n",
500 rtl::OUStringToOString(rProp
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
505 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
508 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
509 const uno::Sequence
< beans::Property
>& rProperties
,
510 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
512 GError
*pError
= NULL
;
513 GFileInfo
*pInfo
= getGFileInfo(xEnv
, &pError
);
515 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
517 return getPropertyValuesFromGFileInfo(pInfo
, m_xContext
, xEnv
, rProperties
);
520 static lang::IllegalAccessException
521 getReadOnlyException( const uno::Reference
< uno::XInterface
>& rContext
)
523 return lang::IllegalAccessException ( rtl::OUString("Property is read-only!"), rContext
);
526 void Content::queryChildren( ContentRefList
& rChildren
)
528 // Obtain a list with a snapshot of all currently instanciated contents
529 // from provider and extract the contents which are direct children
532 ucbhelper::ContentRefList aAllContents
;
533 m_xProvider
->queryExistingContents( aAllContents
);
535 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
536 sal_Int32 nURLPos
= aURL
.lastIndexOf( '/' );
538 if ( nURLPos
!= ( aURL
.getLength() - 1 ) )
539 aURL
+= rtl::OUString("/");
541 sal_Int32 nLen
= aURL
.getLength();
543 ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
544 ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
548 ucbhelper::ContentImplHelperRef xChild
= (*it
);
549 rtl::OUString aChildURL
= xChild
->getIdentifier()->getContentIdentifier();
551 // Is aURL a prefix of aChildURL?
552 if ( ( aChildURL
.getLength() > nLen
) && ( aChildURL
.compareTo( aURL
, nLen
) == 0 ) )
554 sal_Int32 nPos
= nLen
;
555 nPos
= aChildURL
.indexOf( '/', nPos
);
557 if ( ( nPos
== -1 ) || ( nPos
== ( aChildURL
.getLength() - 1 ) ) )
559 // No further slashes / only a final slash. It's a child!
560 rChildren
.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content
* >(xChild
.get() ) ) );
567 sal_Bool
Content::exchangeIdentity( const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
572 uno::Reference
< ucb::XContent
> xThis
= this;
576 m_xIdentifier
= xNewId
;
580 rtl::OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
582 // Exchange own identitity.
583 if ( exchange( xNewId
) )
585 // Process instanciated children...
586 ContentRefList aChildren
;
587 queryChildren( aChildren
);
589 ContentRefList::const_iterator it
= aChildren
.begin();
590 ContentRefList::const_iterator end
= aChildren
.end();
594 ContentRef xChild
= (*it
);
596 // Create new content identifier for the child...
597 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
= xChild
->getIdentifier();
598 rtl::OUString aOldChildURL
= xOldChildId
->getContentIdentifier();
599 rtl::OUString aNewChildURL
= aOldChildURL
.replaceAt(
600 0, aOldURL
.getLength(), xNewId
->getContentIdentifier() );
602 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
603 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
605 if ( !xChild
->exchangeIdentity( xNewChildId
) )
616 uno::Sequence
< uno::Any
> Content::setPropertyValues(
617 const uno::Sequence
< beans::PropertyValue
>& rValues
,
618 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
621 GFileInfo
*pNewInfo
=NULL
;
622 GFileInfo
*pInfo
= getGFileInfo(xEnv
, &pError
);
624 pNewInfo
= g_file_info_dup(pInfo
);
628 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
632 g_error_free(pError
);
633 pNewInfo
= g_file_info_new();
637 sal_Int32 nCount
= rValues
.getLength();
639 beans::PropertyChangeEvent aEvent
;
640 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
641 aEvent
.Further
= sal_False
;
642 aEvent
.PropertyHandle
= -1;
644 sal_Int32 nChanged
= 0, nTitlePos
= -1;
645 const char *newName
= NULL
;
646 uno::Sequence
< beans::PropertyChangeEvent
> aChanges(nCount
);
648 uno::Sequence
< uno::Any
> aRet( nCount
);
649 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
650 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
652 const beans::PropertyValue
& rValue
= pValues
[ n
];
653 #if OSL_DEBUG_LEVEL > 1
654 g_warning("Set prop '%s'", rtl::OUStringToOString(rValue
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
656 if ( rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
657 rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
658 rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
659 rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
660 rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
661 rValue
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
663 aRet
[ n
] <<= getReadOnlyException( static_cast< cppu::OWeakObject
* >(this) );
665 else if ( rValue
.Name
== "Title" )
667 rtl::OUString aNewTitle
;
668 if (!( rValue
.Value
>>= aNewTitle
))
670 aRet
[ n
] <<= beans::IllegalTypeException
671 ( rtl::OUString("Property value has wrong type!"),
672 static_cast< cppu::OWeakObject
* >( this ) );
676 if ( aNewTitle
.getLength() <= 0 )
678 aRet
[ n
] <<= lang::IllegalArgumentException
679 ( rtl::OUString("Empty title not allowed!"),
680 static_cast< cppu::OWeakObject
* >( this ), -1 );
685 rtl::OString sNewTitle
= OUStringToOString(aNewTitle
, RTL_TEXTENCODING_UTF8
);
686 newName
= sNewTitle
.getStr();
687 const char *oldName
= g_file_info_get_name( pInfo
);
689 if (!newName
|| !oldName
|| strcmp(newName
, oldName
))
691 #if OSL_DEBUG_LEVEL > 1
692 g_warning ("Set new name to '%s'", newName
);
695 aEvent
.PropertyName
= rtl::OUString("Title");
697 aEvent
.OldValue
= uno::makeAny(rtl::OUString(oldName
, strlen(oldName
), RTL_TEXTENCODING_UTF8
));
698 aEvent
.NewValue
= uno::makeAny(aNewTitle
);
699 aChanges
.getArray()[ nChanged
] = aEvent
;
700 nTitlePos
= nChanged
++;
702 g_file_info_set_name(pNewInfo
, newName
);
708 fprintf(stderr
, "Unknown property %s\n", rtl::OUStringToOString(rValue
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
710 aRet
[ n
] <<= getReadOnlyException( static_cast< cppu::OWeakObject
* >(this) );
720 if ((bOk
= doSetFileInfo(pNewInfo
)))
722 for (sal_Int32 i
= 0; i
< nChanged
; ++i
)
723 aRet
[ i
] <<= getBadArgExcept();
731 rtl::OUString aNewURL
= getParentURL();
732 aNewURL
+= rtl::OUString( newName
, strlen(newName
), RTL_TEXTENCODING_UTF8
);
733 uno::Reference
< ucb::XContentIdentifier
> xNewId
734 = new ::ucbhelper::ContentIdentifier( aNewURL
);
736 if (!exchangeIdentity( xNewId
) )
738 aRet
[ nTitlePos
] <<= uno::Exception
739 ( rtl::OUString("Exchange failed!"),
740 static_cast< cppu::OWeakObject
* >( this ) );
744 if (!mbTransient
) //Discard and refetch
746 g_object_unref(mpInfo
);
752 g_file_info_copy_into(pNewInfo
, mpInfo
);
753 g_object_unref(pNewInfo
);
758 if (mpFile
) //Discard and refetch
760 g_object_unref(mpFile
);
765 aChanges
.realloc( nChanged
);
766 notifyPropertiesChange( aChanges
);
772 bool Content::doSetFileInfo(GFileInfo
*pNewInfo
)
774 g_assert (!mbTransient
);
777 GFile
*pFile
= getGFile();
778 if(!g_file_set_attributes_from_info(pFile
, pNewInfo
, G_FILE_QUERY_INFO_NONE
, NULL
, NULL
))
783 const int TRANSFER_BUFFER_SIZE
= 65536;
785 void Content::copyData( uno::Reference
< io::XInputStream
> xIn
,
786 uno::Reference
< io::XOutputStream
> xOut
)
788 uno::Sequence
< sal_Int8
> theData( TRANSFER_BUFFER_SIZE
);
790 g_return_if_fail( xIn
.is() && xOut
.is() );
792 while ( xIn
->readBytes( theData
, TRANSFER_BUFFER_SIZE
) > 0 )
793 xOut
->writeBytes( theData
);
798 sal_Bool
Content::feedSink( uno::Reference
< uno::XInterface
> xSink
,
799 const uno::Reference
< ucb::XCommandEnvironment
>& /*xEnv*/ )
804 uno::Reference
< io::XOutputStream
> xOut
= uno::Reference
< io::XOutputStream
>(xSink
, uno::UNO_QUERY
);
805 uno::Reference
< io::XActiveDataSink
> xDataSink
= uno::Reference
< io::XActiveDataSink
>(xSink
, uno::UNO_QUERY
);
807 if ( !xOut
.is() && !xDataSink
.is() )
811 GFileInputStream
*pStream
= g_file_read(getGFile(), NULL
, &pError
);
813 convertToException(pError
, static_cast< cppu::OWeakObject
* >(this));
815 uno::Reference
< io::XInputStream
> xIn
= new ::gio::InputStream(pStream
);
820 copyData( xIn
, xOut
);
822 if ( xDataSink
.is() )
823 xDataSink
->setInputStream( xIn
);
828 uno::Any
Content::open(const ucb::OpenCommandArgument2
& rOpenCommand
,
829 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
830 throw( uno::Exception
)
832 bool bIsFolder
= isFolder(xEnv
);
834 if (!g_file_query_exists(getGFile(), NULL
))
836 uno::Sequence
< uno::Any
> aArgs( 1 );
837 aArgs
[ 0 ] <<= m_xIdentifier
->getContentIdentifier();
838 uno::Any aErr
= uno::makeAny(
839 ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject
* >( this ),
840 task::InteractionClassification_ERROR
,
841 bIsFolder
? ucb::IOErrorCode_NOT_EXISTING_PATH
: ucb::IOErrorCode_NOT_EXISTING
, aArgs
)
844 ucbhelper::cancelCommandExecution(aErr
, xEnv
);
849 sal_Bool bOpenFolder
= (
850 ( rOpenCommand
.Mode
== ucb::OpenMode::ALL
) ||
851 ( rOpenCommand
.Mode
== ucb::OpenMode::FOLDERS
) ||
852 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENTS
)
855 if ( bOpenFolder
&& bIsFolder
)
857 uno::Reference
< ucb::XDynamicResultSet
> xSet
858 = new DynamicResultSet( m_xContext
, this, rOpenCommand
, xEnv
);
861 else if ( rOpenCommand
.Sink
.is() )
864 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
865 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
)
868 ucbhelper::cancelCommandExecution(
869 uno::makeAny ( ucb::UnsupportedOpenModeException
870 ( rtl::OUString(), static_cast< cppu::OWeakObject
* >( this ),
871 sal_Int16( rOpenCommand
.Mode
) ) ),
875 if ( !feedSink( rOpenCommand
.Sink
, xEnv
) )
877 // Note: rOpenCommand.Sink may contain an XStream
878 // implementation. Support for this type of
879 // sink is optional...
881 g_warning ("Failed to load data from '%s'",
882 rtl::OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
885 ucbhelper::cancelCommandExecution(
886 uno::makeAny (ucb::UnsupportedDataSinkException
887 ( rtl::OUString(), static_cast< cppu::OWeakObject
* >( this ),
888 rOpenCommand
.Sink
) ),
893 g_warning ("Open falling through ...");
897 uno::Any SAL_CALL
Content::execute(
898 const ucb::Command
& aCommand
,
899 sal_Int32
/*CommandId*/,
900 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
901 throw( uno::Exception
,
902 ucb::CommandAbortedException
,
903 uno::RuntimeException
)
905 #if OSL_DEBUG_LEVEL > 1
906 fprintf(stderr
, "Content::execute %s\n", rtl::OUStringToOString(aCommand
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
910 if ( aCommand
.Name
== "getPropertyValues" )
912 uno::Sequence
< beans::Property
> Properties
;
913 if ( !( aCommand
.Argument
>>= Properties
) )
914 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
915 aRet
<<= getPropertyValues( Properties
, xEnv
);
917 else if ( aCommand
.Name
== "getPropertySetInfo" )
918 aRet
<<= getPropertySetInfo( xEnv
, sal_False
);
919 else if ( aCommand
.Name
== "getCommandInfo" )
920 aRet
<<= getCommandInfo( xEnv
, sal_False
);
921 else if ( aCommand
.Name
== "open" )
923 ucb::OpenCommandArgument2 aOpenCommand
;
924 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
925 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
926 aRet
= open( aOpenCommand
, xEnv
);
928 else if ( aCommand
.Name
== "transfer" )
930 ucb::TransferInfo transferArgs
;
931 if ( !( aCommand
.Argument
>>= transferArgs
) )
932 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
933 transfer( transferArgs
, xEnv
);
935 else if ( aCommand
.Name
== "setPropertyValues" )
937 uno::Sequence
< beans::PropertyValue
> aProperties
;
938 if ( !( aCommand
.Argument
>>= aProperties
) || !aProperties
.getLength() )
939 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
940 aRet
<<= setPropertyValues( aProperties
, xEnv
);
942 else if (aCommand
.Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) )
943 && isFolder( xEnv
) )
945 ucb::ContentInfo arg
;
946 if ( !( aCommand
.Argument
>>= arg
) )
947 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
948 aRet
<<= createNewContent( arg
);
950 else if ( aCommand
.Name
== "insert" )
952 ucb::InsertCommandArgument arg
;
953 if ( !( aCommand
.Argument
>>= arg
) )
954 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
955 insert( arg
.Data
, arg
.ReplaceExisting
, xEnv
);
957 else if ( aCommand
.Name
== "delete" )
959 sal_Bool bDeletePhysical
= sal_False
;
960 aCommand
.Argument
>>= bDeletePhysical
;
962 //If no delete physical, try and trashcan it, if that doesn't work go
963 //ahead and try and delete it anyway
964 if (!bDeletePhysical
&& !g_file_trash(getGFile(), NULL
, NULL
))
965 bDeletePhysical
= true;
969 GError
*pError
= NULL
;
970 if (!g_file_delete( getGFile(), NULL
, &pError
))
971 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
974 destroy( bDeletePhysical
);
979 fprintf(stderr
, "UNKNOWN COMMAND\n");
983 ucbhelper::cancelCommandExecution
984 ( uno::makeAny( ucb::UnsupportedCommandException
986 static_cast< cppu::OWeakObject
* >( this ) ) ),
993 void Content::destroy( sal_Bool bDeletePhysical
)
994 throw( uno::Exception
)
996 uno::Reference
< ucb::XContent
> xThis
= this;
1000 ::gio::Content::ContentRefList aChildren
;
1001 queryChildren( aChildren
);
1003 ContentRefList::const_iterator it
= aChildren
.begin();
1004 ContentRefList::const_iterator end
= aChildren
.end();
1008 (*it
)->destroy( bDeletePhysical
);
1013 void Content::insert(const uno::Reference
< io::XInputStream
> &xInputStream
,
1014 sal_Bool bReplaceExisting
, const uno::Reference
< ucb::XCommandEnvironment
> &xEnv
)
1015 throw( uno::Exception
)
1017 GError
*pError
= NULL
;
1018 GFileInfo
*pInfo
= getGFileInfo(xEnv
);
1021 g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
) &&
1022 g_file_info_get_file_type(pInfo
) == G_FILE_TYPE_DIRECTORY
)
1024 #if OSL_DEBUG_LEVEL > 1
1025 g_warning ("Make directory");
1027 if( !g_file_make_directory( getGFile(), NULL
, &pError
))
1028 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1032 if ( !xInputStream
.is() )
1034 ucbhelper::cancelCommandExecution( uno::makeAny
1035 ( ucb::MissingInputStreamException
1036 ( rtl::OUString(), static_cast< cppu::OWeakObject
* >( this ) ) ),
1040 GFileOutputStream
* pOutStream
= NULL
;
1041 if ( bReplaceExisting
)
1043 if (!(pOutStream
= g_file_replace(getGFile(), NULL
, false, G_FILE_CREATE_PRIVATE
, NULL
, &pError
)))
1044 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1048 if (!(pOutStream
= g_file_create (getGFile(), G_FILE_CREATE_PRIVATE
, NULL
, &pError
)))
1049 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1052 uno::Reference
< io::XOutputStream
> xOutput
= new ::gio::OutputStream(pOutStream
);
1053 copyData( xInputStream
, xOutput
);
1057 mbTransient
= sal_False
;
1062 const GFileCopyFlags DEFAULT_COPYDATA_FLAGS
=
1063 static_cast<GFileCopyFlags
>(G_FILE_COPY_OVERWRITE
|G_FILE_COPY_TARGET_DEFAULT_PERMS
);
1065 void Content::transfer( const ucb::TransferInfo
& aTransferInfo
, const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1066 throw( uno::Exception
)
1068 rtl::OUString sDest
= m_xIdentifier
->getContentIdentifier();
1069 if (aTransferInfo
.NewTitle
.getLength())
1070 sDest
+= aTransferInfo
.NewTitle
;
1072 sDest
+= rtl::OUString::createFromAscii(g_file_get_basename(getGFile()));
1074 GFile
*pDest
= g_file_new_for_uri(rtl::OUStringToOString(sDest
, RTL_TEXTENCODING_UTF8
).getStr());
1075 GFile
*pSource
= g_file_new_for_uri(rtl::OUStringToOString(aTransferInfo
.SourceURL
, RTL_TEXTENCODING_UTF8
).getStr());
1077 gboolean bSuccess
= false;
1078 GError
*pError
= NULL
;
1079 if (aTransferInfo
.MoveData
)
1080 bSuccess
= g_file_move(pSource
, pDest
, G_FILE_COPY_OVERWRITE
, NULL
, NULL
, 0, &pError
);
1082 bSuccess
= g_file_copy(pSource
, pDest
, DEFAULT_COPYDATA_FLAGS
, NULL
, NULL
, 0, &pError
);
1083 g_object_unref(pSource
);
1084 g_object_unref(pDest
);
1086 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1089 uno::Sequence
< ucb::ContentInfo
> Content::queryCreatableContentsInfo(
1090 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1091 throw( uno::RuntimeException
)
1093 if ( isFolder( xEnv
) )
1095 uno::Sequence
< ucb::ContentInfo
> seq(2);
1097 // Minimum set of props we really need
1098 uno::Sequence
< beans::Property
> props( 1 );
1099 props
[0] = beans::Property(
1100 rtl::OUString("Title"),
1102 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
1103 beans::PropertyAttribute::MAYBEVOID
| beans::PropertyAttribute::BOUND
);
1106 seq
[0].Type
= rtl::OUString( GIO_FILE_TYPE
);
1107 seq
[0].Attributes
= ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
|
1108 ucb::ContentInfoAttribute::KIND_DOCUMENT
);
1109 seq
[0].Properties
= props
;
1112 seq
[1].Type
= rtl::OUString( GIO_FOLDER_TYPE
);
1113 seq
[1].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
1114 seq
[1].Properties
= props
;
1120 return uno::Sequence
< ucb::ContentInfo
>();
1124 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
Content::queryCreatableContentsInfo()
1125 throw( uno::RuntimeException
)
1127 return queryCreatableContentsInfo( uno::Reference
< ucb::XCommandEnvironment
>() );
1130 uno::Reference
< ucb::XContent
>
1131 SAL_CALL
Content::createNewContent( const ucb::ContentInfo
& Info
)
1132 throw( uno::RuntimeException
)
1134 bool create_document
;
1137 if ( Info
.Type
== GIO_FILE_TYPE
)
1138 create_document
= true;
1139 else if ( Info
.Type
== GIO_FOLDER_TYPE
)
1140 create_document
= false;
1144 g_warning( "Failed to create new content '%s'", rtl::OUStringToOString(Info
.Type
,
1145 RTL_TEXTENCODING_UTF8
).getStr() );
1147 return uno::Reference
< ucb::XContent
>();
1150 #if OSL_DEBUG_LEVEL > 1
1151 g_warning( "createNewContent (%d)", (int) create_document
);
1154 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
1156 if ( ( aURL
.lastIndexOf( '/' ) + 1 ) != aURL
.getLength() )
1157 aURL
+= rtl::OUString("/");
1159 name
= create_document
? "[New_Content]" : "[New_Collection]";
1160 aURL
+= rtl::OUString::createFromAscii( name
);
1162 uno::Reference
< ucb::XContentIdentifier
> xId(new ::ucbhelper::ContentIdentifier(aURL
));
1166 return new ::gio::Content( m_xContext
, m_pProvider
, xId
, !create_document
);
1167 } catch ( ucb::ContentCreationException
& )
1169 return uno::Reference
< ucb::XContent
>();
1173 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
1174 throw( uno::RuntimeException
)
1176 if ( isFolder( uno::Reference
< ucb::XCommandEnvironment
>() ) )
1178 static cppu::OTypeCollection aFolderCollection
1179 (CPPU_TYPE_REF( lang::XTypeProvider
),
1180 CPPU_TYPE_REF( lang::XServiceInfo
),
1181 CPPU_TYPE_REF( lang::XComponent
),
1182 CPPU_TYPE_REF( ucb::XContent
),
1183 CPPU_TYPE_REF( ucb::XCommandProcessor
),
1184 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
1185 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
1186 CPPU_TYPE_REF( beans::XPropertyContainer
),
1187 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
1188 CPPU_TYPE_REF( container::XChild
),
1189 CPPU_TYPE_REF( ucb::XContentCreator
) );
1190 return aFolderCollection
.getTypes();
1194 static cppu::OTypeCollection aFileCollection
1195 (CPPU_TYPE_REF( lang::XTypeProvider
),
1196 CPPU_TYPE_REF( lang::XServiceInfo
),
1197 CPPU_TYPE_REF( lang::XComponent
),
1198 CPPU_TYPE_REF( ucb::XContent
),
1199 CPPU_TYPE_REF( ucb::XCommandProcessor
),
1200 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
1201 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
1202 CPPU_TYPE_REF( beans::XPropertyContainer
),
1203 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
1204 CPPU_TYPE_REF( container::XChild
) );
1206 return aFileCollection
.getTypes();
1210 uno::Sequence
< beans::Property
> Content::getProperties(
1211 const uno::Reference
< ucb::XCommandEnvironment
> & /*xEnv*/ )
1213 static const beans::Property aGenericProperties
[] =
1215 beans::Property( rtl::OUString( "IsDocument" ),
1216 -1, getCppuBooleanType(),
1217 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1218 beans::Property( rtl::OUString( "IsFolder" ),
1219 -1, getCppuBooleanType(),
1220 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1221 beans::Property( rtl::OUString( "Title" ),
1222 -1, getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
1223 beans::PropertyAttribute::BOUND
),
1224 beans::Property( rtl::OUString( "IsReadOnly" ),
1225 -1, getCppuBooleanType(),
1226 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1227 beans::Property( rtl::OUString( "DateCreated" ),
1228 -1, getCppuType( static_cast< const util::DateTime
* >( 0 ) ),
1229 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1230 beans::Property( rtl::OUString( "DateModified" ),
1231 -1, getCppuType( static_cast< const util::DateTime
* >( 0 ) ),
1232 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1233 beans::Property( rtl::OUString( "Size" ),
1234 -1, getCppuType( static_cast< const sal_Int64
* >( 0 ) ),
1235 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1236 beans::Property( rtl::OUString( "IsVolume" ),
1237 -1, getCppuBooleanType(),
1238 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1239 beans::Property( rtl::OUString( "IsCompactDisc" ),
1240 -1, getCppuBooleanType(),
1241 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1242 beans::Property( rtl::OUString( "IsRemoveable" ),
1243 -1, getCppuBooleanType(),
1244 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1245 beans::Property( rtl::OUString( "IsHidden" ),
1246 -1, getCppuBooleanType(),
1247 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1248 beans::Property( rtl::OUString( "CreatableContentsInfo" ),
1249 -1, getCppuType( static_cast< const uno::Sequence
< ucb::ContentInfo
> * >( 0 ) ),
1250 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
)
1253 const int nProps
= sizeof (aGenericProperties
) / sizeof (aGenericProperties
[0]);
1254 return uno::Sequence
< beans::Property
> ( aGenericProperties
, nProps
);
1257 uno::Sequence
< ucb::CommandInfo
> Content::getCommands( const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1259 static ucb::CommandInfo aCommandInfoTable
[] =
1261 // Required commands
1263 ( rtl::OUString( "getCommandInfo" ),
1264 -1, getCppuVoidType() ),
1266 ( rtl::OUString( "getPropertySetInfo" ),
1267 -1, getCppuVoidType() ),
1269 ( rtl::OUString( "getPropertyValues" ),
1270 -1, getCppuType( static_cast<uno::Sequence
< beans::Property
> * >( 0 ) ) ),
1272 ( rtl::OUString( "setPropertyValues" ),
1273 -1, getCppuType( static_cast<uno::Sequence
< beans::PropertyValue
> * >( 0 ) ) ),
1275 // Optional standard commands
1277 ( rtl::OUString( "delete" ),
1278 -1, getCppuBooleanType() ),
1280 ( rtl::OUString( "insert" ),
1281 -1, getCppuType( static_cast<ucb::InsertCommandArgument
* >( 0 ) ) ),
1283 ( rtl::OUString( "open" ),
1284 -1, getCppuType( static_cast<ucb::OpenCommandArgument2
* >( 0 ) ) ),
1286 // Folder Only, omitted if not a folder
1288 ( rtl::OUString( "transfer" ),
1289 -1, getCppuType( static_cast<ucb::TransferInfo
* >( 0 ) ) ),
1291 ( rtl::OUString( "createNewContent" ),
1292 -1, getCppuType( static_cast<ucb::ContentInfo
* >( 0 ) ) )
1295 const int nProps
= sizeof (aCommandInfoTable
) / sizeof (aCommandInfoTable
[0]);
1296 return uno::Sequence
< ucb::CommandInfo
>(aCommandInfoTable
, isFolder(xEnv
) ? nProps
: nProps
- 2);
1299 XTYPEPROVIDER_COMMON_IMPL( Content
);
1301 void SAL_CALL
Content::acquire() throw()
1303 ContentImplHelper::acquire();
1306 void SAL_CALL
Content::release() throw()
1308 ContentImplHelper::release();
1311 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
) throw ( uno::RuntimeException
)
1313 uno::Any aRet
= cppu::queryInterface( rType
, static_cast< ucb::XContentCreator
* >( this ) );
1314 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface(rType
);
1317 rtl::OUString SAL_CALL
Content::getImplementationName() throw( uno::RuntimeException
)
1319 return rtl::OUString("com.sun.star.comp.GIOContent");
1322 uno::Sequence
< rtl::OUString
> SAL_CALL
Content::getSupportedServiceNames()
1323 throw( uno::RuntimeException
)
1325 uno::Sequence
< rtl::OUString
> aSNS( 1 );
1326 aSNS
.getArray()[ 0 ] = rtl::OUString("com.sun.star.ucb.GIOContent");
1332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */