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/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>
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>
66 #include <osl/conditn.hxx>
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"
77 using namespace com::sun::star
;
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 m_pProvider( pProvider
), mpFile (NULL
), mpInfo( NULL
), mbTransient(false)
90 #if OSL_DEBUG_LEVEL > 1
91 fprintf(stderr
, "New Content ('%s')\n", OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
96 const uno::Reference
< uno::XComponentContext
>& rxContext
,
97 ContentProvider
* pProvider
,
98 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
100 throw ( ucb::ContentCreationException
)
101 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
102 m_pProvider( pProvider
), mpFile (NULL
), mpInfo( NULL
), mbTransient(true)
104 #if OSL_DEBUG_LEVEL > 1
105 fprintf(stderr
, "Create Content ('%s')\n", OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
107 mpInfo
= g_file_info_new();
108 g_file_info_set_file_type(mpInfo
, bIsFolder
? G_FILE_TYPE_DIRECTORY
: G_FILE_TYPE_REGULAR
);
113 if (mpInfo
) g_object_unref(mpInfo
);
114 if (mpFile
) g_object_unref(mpFile
);
117 OUString
Content::getParentURL()
120 if (GFile
* pFile
= g_file_get_parent(getGFile()))
122 char* pPath
= g_file_get_uri(pFile
);
123 g_object_unref(pFile
);
124 sURL
= OUString::createFromAscii(pPath
);
130 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
131 throw( uno::RuntimeException
)
134 //stick a map from each CommandId to a new GCancellable and propogate
135 //it throughout the g_file_* calls
138 OUString SAL_CALL
Content::getContentType() throw( uno::RuntimeException
)
140 return isFolder(uno::Reference
< ucb::XCommandEnvironment
>())
141 ? OUString( GIO_FOLDER_TYPE
)
142 : OUString( GIO_FILE_TYPE
);
145 #define EXCEPT(aExcept) \
147 if (bThrow) throw aExcept;\
148 aRet = uno::makeAny( aExcept );\
151 uno::Any
convertToException(GError
*pError
, const uno::Reference
< uno::XInterface
>& rContext
, bool bThrow
)
155 gint eCode
= pError
->code
;
156 OUString
sMessage(pError
->message
, strlen(pError
->message
), RTL_TEXTENCODING_UTF8
);
157 g_error_free(pError
);
162 uno::Sequence
< uno::Any
> aArgs( 1 );
163 aArgs
[ 0 ] <<= sName
;
167 case G_IO_ERROR_FAILED
:
168 { io::IOException
aExcept(sMessage
, rContext
);
171 case G_IO_ERROR_NOT_MOUNTED
:
172 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
173 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_EXISTING_PATH
, aArgs
);
176 case G_IO_ERROR_NOT_FOUND
:
177 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
178 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_EXISTING
, aArgs
);
181 case G_IO_ERROR_EXISTS
:
182 { ucb::NameClashException
aExcept(sMessage
, rContext
,
183 task::InteractionClassification_ERROR
, sName
);
186 case G_IO_ERROR_INVALID_ARGUMENT
:
187 { lang::IllegalArgumentException
aExcept(sMessage
, rContext
, -1 );
190 case G_IO_ERROR_PERMISSION_DENIED
:
191 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
192 task::InteractionClassification_ERROR
, ucb::IOErrorCode_ACCESS_DENIED
, aArgs
);
195 case G_IO_ERROR_IS_DIRECTORY
:
196 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
197 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_FILE
, aArgs
);
200 case G_IO_ERROR_NOT_REGULAR_FILE
:
201 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
202 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_FILE
, aArgs
);
205 case G_IO_ERROR_NOT_DIRECTORY
:
206 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
207 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NO_DIRECTORY
, aArgs
);
210 case G_IO_ERROR_FILENAME_TOO_LONG
:
211 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
212 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NAME_TOO_LONG
, aArgs
);
215 case G_IO_ERROR_PENDING
:
216 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
217 task::InteractionClassification_ERROR
, ucb::IOErrorCode_PENDING
, aArgs
);
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 task::InteractionClassification_ERROR
, ucb::IOErrorCode_GENERAL
, aArgs
);
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 task::InteractionClassification_ERROR
, ucb::IOErrorCode_NOT_SUPPORTED
, aArgs
);
235 case G_IO_ERROR_NO_SPACE
:
236 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
237 task::InteractionClassification_ERROR
, ucb::IOErrorCode_OUT_OF_DISK_SPACE
, aArgs
);
240 case G_IO_ERROR_INVALID_FILENAME
:
241 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
242 task::InteractionClassification_ERROR
, ucb::IOErrorCode_INVALID_CHARACTER
, aArgs
);
245 case G_IO_ERROR_READ_ONLY
:
246 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
247 task::InteractionClassification_ERROR
, ucb::IOErrorCode_WRITE_PROTECTED
, aArgs
);
250 case G_IO_ERROR_TIMED_OUT
:
251 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
252 task::InteractionClassification_ERROR
, ucb::IOErrorCode_DEVICE_NOT_READY
, aArgs
);
255 case G_IO_ERROR_WOULD_RECURSE
:
256 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
257 task::InteractionClassification_ERROR
, ucb::IOErrorCode_RECURSIVE
, aArgs
);
260 case G_IO_ERROR_BUSY
:
261 case G_IO_ERROR_WOULD_BLOCK
:
262 { ucb::InteractiveAugmentedIOException
aExcept(sMessage
, rContext
,
263 task::InteractionClassification_ERROR
, ucb::IOErrorCode_LOCKING_VIOLATION
, aArgs
);
266 case G_IO_ERROR_HOST_NOT_FOUND
:
267 { ucb::InteractiveNetworkResolveNameException
aExcept(sMessage
, rContext
,
268 task::InteractionClassification_ERROR
, sHost
);
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 task::InteractionClassification_ERROR
);
285 uno::Any
Content::mapGIOError( GError
*pError
)
288 return getBadArgExcept();
290 return convertToException(pError
, static_cast< cppu::OWeakObject
* >(this), false);
293 uno::Any
Content::getBadArgExcept()
295 return uno::makeAny( lang::IllegalArgumentException(
296 OUString("Wrong argument type!"),
297 static_cast< cppu::OWeakObject
* >( this ), -1) );
303 GMountOperation
*mpAuthentication
;
305 static void Completed(GObject
*source
, GAsyncResult
*res
, gpointer user_data
);
307 MountOperation(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
);
309 GError
*Mount(GFile
*pFile
);
312 MountOperation::MountOperation(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
) : mpError(NULL
)
314 mpLoop
= g_main_loop_new(NULL
, FALSE
);
315 mpAuthentication
= ooo_mount_operation_new(xEnv
);
318 void MountOperation::Completed(GObject
*source
, GAsyncResult
*res
, gpointer user_data
)
320 MountOperation
*pThis
= (MountOperation
*)user_data
;
321 g_file_mount_enclosing_volume_finish(G_FILE(source
), res
, &(pThis
->mpError
));
322 g_main_loop_quit(pThis
->mpLoop
);
325 GError
*MountOperation::Mount(GFile
*pFile
)
327 g_file_mount_enclosing_volume(pFile
, G_MOUNT_MOUNT_NONE
, mpAuthentication
, NULL
, MountOperation::Completed
, this);
328 g_main_loop_run(mpLoop
);
332 MountOperation::~MountOperation()
334 g_object_unref(mpAuthentication
);
335 g_main_loop_unref(mpLoop
);
338 GFileInfo
* Content::getGFileInfo(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
, GError
**ppError
)
341 if (mpInfo
== 0 && !mbTransient
) {
342 for (bool retried
= false;; retried
= true) {
343 mpInfo
= g_file_query_info(
344 getGFile(), "*", G_FILE_QUERY_INFO_NONE
, 0, &err
);
349 if (err
->code
!= G_IO_ERROR_NOT_MOUNTED
|| retried
) {
354 "G_IO_ERROR_NOT_MOUNTED \"" << err
->message
355 << "\", trying to mount");
357 err
= MountOperation(xEnv
).Mount(getGFile());
365 } else if (err
!= 0) {
366 SAL_WARN("ucb.ucp.gio", "ignoring GError \"" << err
->message
<< "\"");
372 GFile
* Content::getGFile()
375 mpFile
= g_file_new_for_uri(OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
379 bool Content::isFolder(const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
381 GFileInfo
*pInfo
= getGFileInfo(xEnv
);
382 return pInfo
&& (g_file_info_get_file_type(pInfo
) == G_FILE_TYPE_DIRECTORY
);
385 static util::DateTime
getDateFromUnix (time_t t
)
392 if ( osl_getDateTimeFromTimeValue( &tv
, &dt
) )
393 return util::DateTime( 0, dt
.Seconds
, dt
.Minutes
, dt
.Hours
,
394 dt
.Day
, dt
.Month
, dt
.Year
, false);
396 return util::DateTime();
399 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
)
404 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
= new ::ucbhelper::PropertyValueSet( rxContext
);
407 const beans::Property
* pProps
;
409 nProps
= rProperties
.getLength();
410 pProps
= rProperties
.getConstArray();
412 for( sal_Int32 n
= 0; n
< nProps
; ++n
)
414 const beans::Property
& rProp
= pProps
[ n
];
416 if ( rProp
.Name
== "IsDocument" )
418 if (pInfo
!= 0 && g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
))
419 xRow
->appendBoolean( rProp
, ( g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_REGULAR
||
420 g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_UNKNOWN
) );
422 xRow
->appendVoid( rProp
);
424 else if ( rProp
.Name
== "IsFolder" )
426 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
) )
427 xRow
->appendBoolean( rProp
, ( g_file_info_get_file_type( pInfo
) == G_FILE_TYPE_DIRECTORY
));
429 xRow
->appendVoid( rProp
);
431 else if ( rProp
.Name
== "Title" )
433 if (pInfo
!= 0 && g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
))
435 const char *pName
= g_file_info_get_display_name(pInfo
);
436 xRow
->appendString( rProp
, OUString(pName
, strlen(pName
), RTL_TEXTENCODING_UTF8
) );
439 xRow
->appendVoid(rProp
);
441 else if ( rProp
.Name
== "IsReadOnly" )
443 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
) )
444 xRow
->appendBoolean( rProp
, !g_file_info_get_attribute_boolean( pInfo
, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
) );
446 xRow
->appendVoid( rProp
);
448 else if ( rProp
.Name
== "DateCreated" )
450 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_TIME_CREATED
) )
451 xRow
->appendTimestamp( rProp
, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo
, G_FILE_ATTRIBUTE_TIME_CREATED
)) );
453 xRow
->appendVoid( rProp
);
455 else if ( rProp
.Name
== "DateModified" )
457 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_TIME_CHANGED
) )
458 xRow
->appendTimestamp( rProp
, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo
, G_FILE_ATTRIBUTE_TIME_CHANGED
)) );
460 xRow
->appendVoid( rProp
);
462 else if ( rProp
.Name
== "Size" )
464 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_SIZE
) )
465 xRow
->appendLong( rProp
, ( g_file_info_get_size( pInfo
) ));
467 xRow
->appendVoid( rProp
);
469 else if ( rProp
.Name
== "IsVolume" )
471 //What do we use this for ?
472 xRow
->appendBoolean( rProp
, sal_False
);
474 else if ( rProp
.Name
== "IsCompactDisc" )
476 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
) )
477 xRow
->appendBoolean( rProp
, g_file_info_get_attribute_boolean(pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
) );
479 xRow
->appendVoid( rProp
);
481 else if ( rProp
.Name
== "IsRemoveable" )
483 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
) )
484 xRow
->appendBoolean( rProp
, g_file_info_get_attribute_boolean(pInfo
, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
) );
486 xRow
->appendVoid( rProp
);
488 else if ( rProp
.Name
== "IsFloppy" )
490 xRow
->appendBoolean( rProp
, sal_False
);
492 else if ( rProp
.Name
== "IsHidden" )
494 if (pInfo
!= 0 && g_file_info_has_attribute( pInfo
, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN
) )
495 xRow
->appendBoolean( rProp
, ( g_file_info_get_is_hidden ( pInfo
) ) );
497 xRow
->appendVoid( rProp
);
499 else if ( rProp
.Name
== "CreatableContentsInfo" )
501 xRow
->appendObject( rProp
, uno::makeAny( queryCreatableContentsInfo( xEnv
) ) );
507 "Looking for unsupported property " << rProp
.Name
);
511 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
514 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
515 const uno::Sequence
< beans::Property
>& rProperties
,
516 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
518 GFileInfo
*pInfo
= getGFileInfo(xEnv
);
519 return getPropertyValuesFromGFileInfo(pInfo
, m_xContext
, xEnv
, rProperties
);
522 static lang::IllegalAccessException
523 getReadOnlyException( const uno::Reference
< uno::XInterface
>& rContext
)
525 return lang::IllegalAccessException ( OUString("Property is read-only!"), rContext
);
528 void Content::queryChildren( ContentRefList
& rChildren
)
530 // Obtain a list with a snapshot of all currently instanciated contents
531 // from provider and extract the contents which are direct children
534 ucbhelper::ContentRefList aAllContents
;
535 m_xProvider
->queryExistingContents( aAllContents
);
537 OUString aURL
= m_xIdentifier
->getContentIdentifier();
538 sal_Int32 nURLPos
= aURL
.lastIndexOf( '/' );
540 if ( nURLPos
!= ( aURL
.getLength() - 1 ) )
541 aURL
+= OUString("/");
543 sal_Int32 nLen
= aURL
.getLength();
545 ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
546 ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
550 ucbhelper::ContentImplHelperRef xChild
= (*it
);
551 OUString aChildURL
= xChild
->getIdentifier()->getContentIdentifier();
553 // Is aURL a prefix of aChildURL?
554 if ( ( aChildURL
.getLength() > nLen
) && ( aChildURL
.compareTo( aURL
, nLen
) == 0 ) )
556 sal_Int32 nPos
= nLen
;
557 nPos
= aChildURL
.indexOf( '/', nPos
);
559 if ( ( nPos
== -1 ) || ( nPos
== ( aChildURL
.getLength() - 1 ) ) )
561 // No further slashes / only a final slash. It's a child!
562 rChildren
.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content
* >(xChild
.get() ) ) );
569 sal_Bool
Content::exchangeIdentity( const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
574 uno::Reference
< ucb::XContent
> xThis
= this;
578 m_xIdentifier
= xNewId
;
582 OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
584 // Exchange own identitity.
585 if ( exchange( xNewId
) )
587 // Process instanciated children...
588 ContentRefList aChildren
;
589 queryChildren( aChildren
);
591 ContentRefList::const_iterator it
= aChildren
.begin();
592 ContentRefList::const_iterator end
= aChildren
.end();
596 ContentRef xChild
= (*it
);
598 // Create new content identifier for the child...
599 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
= xChild
->getIdentifier();
600 OUString aOldChildURL
= xOldChildId
->getContentIdentifier();
601 OUString aNewChildURL
= aOldChildURL
.replaceAt(
602 0, aOldURL
.getLength(), xNewId
->getContentIdentifier() );
604 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
605 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
607 if ( !xChild
->exchangeIdentity( xNewChildId
) )
618 uno::Sequence
< uno::Any
> Content::setPropertyValues(
619 const uno::Sequence
< beans::PropertyValue
>& rValues
,
620 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
623 GFileInfo
*pNewInfo
=NULL
;
624 GFileInfo
*pInfo
= getGFileInfo(xEnv
, &pError
);
626 pNewInfo
= g_file_info_dup(pInfo
);
630 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
634 g_error_free(pError
);
635 pNewInfo
= g_file_info_new();
639 sal_Int32 nCount
= rValues
.getLength();
641 beans::PropertyChangeEvent aEvent
;
642 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
643 aEvent
.Further
= sal_False
;
644 aEvent
.PropertyHandle
= -1;
646 sal_Int32 nChanged
= 0, nTitlePos
= -1;
647 const char *newName
= NULL
;
648 uno::Sequence
< beans::PropertyChangeEvent
> aChanges(nCount
);
650 uno::Sequence
< uno::Any
> aRet( nCount
);
651 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
652 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
654 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());
658 if ( rValue
.Name
== "ContentType" ||
659 rValue
.Name
== "MediaType" ||
660 rValue
.Name
== "IsDocument" ||
661 rValue
.Name
== "IsFolder" ||
662 rValue
.Name
== "Size" ||
663 rValue
.Name
== "CreatableContentsInfo" )
665 aRet
[ n
] <<= getReadOnlyException( static_cast< cppu::OWeakObject
* >(this) );
667 else if ( rValue
.Name
== "Title" )
670 if (!( rValue
.Value
>>= aNewTitle
))
672 aRet
[ n
] <<= beans::IllegalTypeException
673 ( OUString("Property value has wrong type!"),
674 static_cast< cppu::OWeakObject
* >( this ) );
678 if ( aNewTitle
.getLength() <= 0 )
680 aRet
[ n
] <<= lang::IllegalArgumentException
681 ( OUString("Empty title not allowed!"),
682 static_cast< cppu::OWeakObject
* >( this ), -1 );
687 OString sNewTitle
= OUStringToOString(aNewTitle
, RTL_TEXTENCODING_UTF8
);
688 newName
= sNewTitle
.getStr();
689 const char *oldName
= g_file_info_get_name( pInfo
);
691 if (!newName
|| !oldName
|| strcmp(newName
, oldName
))
693 #if OSL_DEBUG_LEVEL > 1
694 g_warning ("Set new name to '%s'", newName
);
697 aEvent
.PropertyName
= OUString("Title");
699 aEvent
.OldValue
= uno::makeAny(OUString(oldName
, strlen(oldName
), RTL_TEXTENCODING_UTF8
));
700 aEvent
.NewValue
= uno::makeAny(aNewTitle
);
701 aChanges
.getArray()[ nChanged
] = aEvent
;
702 nTitlePos
= nChanged
++;
704 g_file_info_set_name(pNewInfo
, newName
);
710 fprintf(stderr
, "Unknown property %s\n", OUStringToOString(rValue
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
712 aRet
[ n
] <<= getReadOnlyException( static_cast< cppu::OWeakObject
* >(this) );
722 if ((bOk
= doSetFileInfo(pNewInfo
)))
724 for (sal_Int32 i
= 0; i
< nChanged
; ++i
)
725 aRet
[ i
] <<= getBadArgExcept();
733 OUString aNewURL
= getParentURL();
734 aNewURL
+= OUString( newName
, strlen(newName
), RTL_TEXTENCODING_UTF8
);
735 uno::Reference
< ucb::XContentIdentifier
> xNewId
736 = new ::ucbhelper::ContentIdentifier( aNewURL
);
738 if (!exchangeIdentity( xNewId
) )
740 aRet
[ nTitlePos
] <<= uno::Exception
741 ( OUString("Exchange failed!"),
742 static_cast< cppu::OWeakObject
* >( this ) );
746 if (!mbTransient
) //Discard and refetch
748 g_object_unref(mpInfo
);
754 g_file_info_copy_into(pNewInfo
, mpInfo
);
755 g_object_unref(pNewInfo
);
760 if (mpFile
) //Discard and refetch
762 g_object_unref(mpFile
);
767 aChanges
.realloc( nChanged
);
768 notifyPropertiesChange( aChanges
);
774 bool Content::doSetFileInfo(GFileInfo
*pNewInfo
)
776 g_assert (!mbTransient
);
779 GFile
*pFile
= getGFile();
780 if(!g_file_set_attributes_from_info(pFile
, pNewInfo
, G_FILE_QUERY_INFO_NONE
, NULL
, NULL
))
785 const int TRANSFER_BUFFER_SIZE
= 65536;
787 void Content::copyData( uno::Reference
< io::XInputStream
> xIn
,
788 uno::Reference
< io::XOutputStream
> xOut
)
790 uno::Sequence
< sal_Int8
> theData( TRANSFER_BUFFER_SIZE
);
792 g_return_if_fail( xIn
.is() && xOut
.is() );
794 while ( xIn
->readBytes( theData
, TRANSFER_BUFFER_SIZE
) > 0 )
795 xOut
->writeBytes( theData
);
800 sal_Bool
Content::feedSink( uno::Reference
< uno::XInterface
> xSink
,
801 const uno::Reference
< ucb::XCommandEnvironment
>& /*xEnv*/ )
806 uno::Reference
< io::XOutputStream
> xOut
= uno::Reference
< io::XOutputStream
>(xSink
, uno::UNO_QUERY
);
807 uno::Reference
< io::XActiveDataSink
> xDataSink
= uno::Reference
< io::XActiveDataSink
>(xSink
, uno::UNO_QUERY
);
809 if ( !xOut
.is() && !xDataSink
.is() )
813 GFileInputStream
*pStream
= g_file_read(getGFile(), NULL
, &pError
);
815 convertToException(pError
, static_cast< cppu::OWeakObject
* >(this));
817 uno::Reference
< io::XInputStream
> xIn
= new ::gio::InputStream(pStream
);
822 copyData( xIn
, xOut
);
824 if ( xDataSink
.is() )
825 xDataSink
->setInputStream( xIn
);
830 uno::Any
Content::open(const ucb::OpenCommandArgument2
& rOpenCommand
,
831 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
832 throw( uno::Exception
)
834 bool bIsFolder
= isFolder(xEnv
);
836 if (!g_file_query_exists(getGFile(), NULL
))
838 uno::Sequence
< uno::Any
> aArgs( 1 );
839 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
)
846 ucbhelper::cancelCommandExecution(aErr
, xEnv
);
851 sal_Bool bOpenFolder
= (
852 ( rOpenCommand
.Mode
== ucb::OpenMode::ALL
) ||
853 ( rOpenCommand
.Mode
== ucb::OpenMode::FOLDERS
) ||
854 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENTS
)
857 if ( bOpenFolder
&& bIsFolder
)
859 uno::Reference
< ucb::XDynamicResultSet
> xSet
860 = new DynamicResultSet( m_xContext
, this, rOpenCommand
, xEnv
);
863 else if ( rOpenCommand
.Sink
.is() )
866 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
867 ( rOpenCommand
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
)
870 ucbhelper::cancelCommandExecution(
871 uno::makeAny ( ucb::UnsupportedOpenModeException
872 ( OUString(), static_cast< cppu::OWeakObject
* >( this ),
873 sal_Int16( rOpenCommand
.Mode
) ) ),
877 if ( !feedSink( rOpenCommand
.Sink
, xEnv
) )
879 // Note: rOpenCommand.Sink may contain an XStream
880 // implementation. Support for this type of
881 // sink is optional...
883 g_warning ("Failed to load data from '%s'",
884 OUStringToOString(m_xIdentifier
->getContentIdentifier(), RTL_TEXTENCODING_UTF8
).getStr());
887 ucbhelper::cancelCommandExecution(
888 uno::makeAny (ucb::UnsupportedDataSinkException
889 ( OUString(), static_cast< cppu::OWeakObject
* >( this ),
890 rOpenCommand
.Sink
) ),
895 g_warning ("Open falling through ...");
899 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
)
907 #if OSL_DEBUG_LEVEL > 1
908 fprintf(stderr
, "Content::execute %s\n", OUStringToOString(aCommand
.Name
, RTL_TEXTENCODING_UTF8
).getStr());
912 if ( aCommand
.Name
== "getPropertyValues" )
914 uno::Sequence
< beans::Property
> Properties
;
915 if ( !( aCommand
.Argument
>>= Properties
) )
916 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
917 aRet
<<= getPropertyValues( Properties
, xEnv
);
919 else if ( aCommand
.Name
== "getPropertySetInfo" )
920 aRet
<<= getPropertySetInfo( xEnv
, sal_False
);
921 else if ( aCommand
.Name
== "getCommandInfo" )
922 aRet
<<= getCommandInfo( xEnv
, sal_False
);
923 else if ( aCommand
.Name
== "open" )
925 ucb::OpenCommandArgument2 aOpenCommand
;
926 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
927 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
928 aRet
= open( aOpenCommand
, xEnv
);
930 else if ( aCommand
.Name
== "transfer" )
932 ucb::TransferInfo transferArgs
;
933 if ( !( aCommand
.Argument
>>= transferArgs
) )
934 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
935 transfer( transferArgs
, xEnv
);
937 else if ( aCommand
.Name
== "setPropertyValues" )
939 uno::Sequence
< beans::PropertyValue
> aProperties
;
940 if ( !( aCommand
.Argument
>>= aProperties
) || !aProperties
.getLength() )
941 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
942 aRet
<<= setPropertyValues( aProperties
, xEnv
);
944 else if (aCommand
.Name
== "createNewContent"
945 && isFolder( xEnv
) )
947 ucb::ContentInfo arg
;
948 if ( !( aCommand
.Argument
>>= arg
) )
949 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
950 aRet
<<= createNewContent( arg
);
952 else if ( aCommand
.Name
== "insert" )
954 ucb::InsertCommandArgument arg
;
955 if ( !( aCommand
.Argument
>>= arg
) )
956 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv
);
957 insert( arg
.Data
, arg
.ReplaceExisting
, xEnv
);
959 else if ( aCommand
.Name
== "delete" )
961 sal_Bool bDeletePhysical
= sal_False
;
962 aCommand
.Argument
>>= bDeletePhysical
;
964 //If no delete physical, try and trashcan it, if that doesn't work go
965 //ahead and try and delete it anyway
966 if (!bDeletePhysical
&& !g_file_trash(getGFile(), NULL
, NULL
))
967 bDeletePhysical
= true;
971 GError
*pError
= NULL
;
972 if (!g_file_delete( getGFile(), NULL
, &pError
))
973 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
976 destroy( bDeletePhysical
);
981 fprintf(stderr
, "UNKNOWN COMMAND\n");
985 ucbhelper::cancelCommandExecution
986 ( uno::makeAny( ucb::UnsupportedCommandException
988 static_cast< cppu::OWeakObject
* >( this ) ) ),
995 void Content::destroy( sal_Bool bDeletePhysical
)
996 throw( uno::Exception
)
998 uno::Reference
< ucb::XContent
> xThis
= this;
1002 ::gio::Content::ContentRefList aChildren
;
1003 queryChildren( aChildren
);
1005 ContentRefList::const_iterator it
= aChildren
.begin();
1006 ContentRefList::const_iterator end
= aChildren
.end();
1010 (*it
)->destroy( bDeletePhysical
);
1015 void Content::insert(const uno::Reference
< io::XInputStream
> &xInputStream
,
1016 sal_Bool bReplaceExisting
, const uno::Reference
< ucb::XCommandEnvironment
> &xEnv
)
1017 throw( uno::Exception
)
1019 GError
*pError
= NULL
;
1020 GFileInfo
*pInfo
= getGFileInfo(xEnv
);
1023 g_file_info_has_attribute(pInfo
, G_FILE_ATTRIBUTE_STANDARD_TYPE
) &&
1024 g_file_info_get_file_type(pInfo
) == G_FILE_TYPE_DIRECTORY
)
1026 #if OSL_DEBUG_LEVEL > 1
1027 g_warning ("Make directory");
1029 if( !g_file_make_directory( getGFile(), NULL
, &pError
))
1030 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1034 if ( !xInputStream
.is() )
1036 ucbhelper::cancelCommandExecution( uno::makeAny
1037 ( ucb::MissingInputStreamException
1038 ( OUString(), static_cast< cppu::OWeakObject
* >( this ) ) ),
1042 GFileOutputStream
* pOutStream
= NULL
;
1043 if ( bReplaceExisting
)
1045 if (!(pOutStream
= g_file_replace(getGFile(), NULL
, false, G_FILE_CREATE_PRIVATE
, NULL
, &pError
)))
1046 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1050 if (!(pOutStream
= g_file_create (getGFile(), G_FILE_CREATE_PRIVATE
, NULL
, &pError
)))
1051 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1054 uno::Reference
< io::XOutputStream
> xOutput
= new ::gio::OutputStream(pOutStream
);
1055 copyData( xInputStream
, xOutput
);
1059 mbTransient
= sal_False
;
1064 const GFileCopyFlags DEFAULT_COPYDATA_FLAGS
=
1065 static_cast<GFileCopyFlags
>(G_FILE_COPY_OVERWRITE
|G_FILE_COPY_TARGET_DEFAULT_PERMS
);
1067 void Content::transfer( const ucb::TransferInfo
& aTransferInfo
, const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1068 throw( uno::Exception
)
1070 OUString sDest
= m_xIdentifier
->getContentIdentifier();
1071 if (!sDest
.endsWith("/")) {
1074 if (aTransferInfo
.NewTitle
.getLength())
1075 sDest
+= aTransferInfo
.NewTitle
;
1077 sDest
+= OUString::createFromAscii(g_file_get_basename(getGFile()));
1079 GFile
*pDest
= g_file_new_for_uri(OUStringToOString(sDest
, RTL_TEXTENCODING_UTF8
).getStr());
1080 GFile
*pSource
= g_file_new_for_uri(OUStringToOString(aTransferInfo
.SourceURL
, RTL_TEXTENCODING_UTF8
).getStr());
1082 gboolean bSuccess
= false;
1083 GError
*pError
= NULL
;
1084 if (aTransferInfo
.MoveData
)
1085 bSuccess
= g_file_move(pSource
, pDest
, G_FILE_COPY_OVERWRITE
, NULL
, NULL
, 0, &pError
);
1087 bSuccess
= g_file_copy(pSource
, pDest
, DEFAULT_COPYDATA_FLAGS
, NULL
, NULL
, 0, &pError
);
1088 g_object_unref(pSource
);
1089 g_object_unref(pDest
);
1091 ucbhelper::cancelCommandExecution(mapGIOError(pError
), xEnv
);
1094 uno::Sequence
< ucb::ContentInfo
> Content::queryCreatableContentsInfo(
1095 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1096 throw( uno::RuntimeException
)
1098 if ( isFolder( xEnv
) )
1100 uno::Sequence
< ucb::ContentInfo
> seq(2);
1102 // Minimum set of props we really need
1103 uno::Sequence
< beans::Property
> props( 1 );
1104 props
[0] = beans::Property(
1107 getCppuType( static_cast< OUString
* >( 0 ) ),
1108 beans::PropertyAttribute::MAYBEVOID
| beans::PropertyAttribute::BOUND
);
1111 seq
[0].Type
= OUString( GIO_FILE_TYPE
);
1112 seq
[0].Attributes
= ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
|
1113 ucb::ContentInfoAttribute::KIND_DOCUMENT
);
1114 seq
[0].Properties
= props
;
1117 seq
[1].Type
= OUString( GIO_FOLDER_TYPE
);
1118 seq
[1].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
1119 seq
[1].Properties
= props
;
1125 return uno::Sequence
< ucb::ContentInfo
>();
1129 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
Content::queryCreatableContentsInfo()
1130 throw( uno::RuntimeException
)
1132 return queryCreatableContentsInfo( uno::Reference
< ucb::XCommandEnvironment
>() );
1135 uno::Reference
< ucb::XContent
>
1136 SAL_CALL
Content::createNewContent( const ucb::ContentInfo
& Info
)
1137 throw( uno::RuntimeException
)
1139 bool create_document
;
1142 if ( Info
.Type
== GIO_FILE_TYPE
)
1143 create_document
= true;
1144 else if ( Info
.Type
== GIO_FOLDER_TYPE
)
1145 create_document
= false;
1149 g_warning( "Failed to create new content '%s'", OUStringToOString(Info
.Type
,
1150 RTL_TEXTENCODING_UTF8
).getStr() );
1152 return uno::Reference
< ucb::XContent
>();
1155 #if OSL_DEBUG_LEVEL > 1
1156 g_warning( "createNewContent (%d)", (int) create_document
);
1159 OUString aURL
= m_xIdentifier
->getContentIdentifier();
1161 if ( ( aURL
.lastIndexOf( '/' ) + 1 ) != aURL
.getLength() )
1162 aURL
+= OUString("/");
1164 name
= create_document
? "[New_Content]" : "[New_Collection]";
1165 aURL
+= OUString::createFromAscii( name
);
1167 uno::Reference
< ucb::XContentIdentifier
> xId(new ::ucbhelper::ContentIdentifier(aURL
));
1171 return new ::gio::Content( m_xContext
, m_pProvider
, xId
, !create_document
);
1172 } catch ( ucb::ContentCreationException
& )
1174 return uno::Reference
< ucb::XContent
>();
1178 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
1179 throw( uno::RuntimeException
)
1181 if ( isFolder( uno::Reference
< ucb::XCommandEnvironment
>() ) )
1183 static cppu::OTypeCollection aFolderCollection
1184 (CPPU_TYPE_REF( lang::XTypeProvider
),
1185 CPPU_TYPE_REF( lang::XServiceInfo
),
1186 CPPU_TYPE_REF( lang::XComponent
),
1187 CPPU_TYPE_REF( ucb::XContent
),
1188 CPPU_TYPE_REF( ucb::XCommandProcessor
),
1189 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
1190 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
1191 CPPU_TYPE_REF( beans::XPropertyContainer
),
1192 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
1193 CPPU_TYPE_REF( container::XChild
),
1194 CPPU_TYPE_REF( ucb::XContentCreator
) );
1195 return aFolderCollection
.getTypes();
1199 static cppu::OTypeCollection aFileCollection
1200 (CPPU_TYPE_REF( lang::XTypeProvider
),
1201 CPPU_TYPE_REF( lang::XServiceInfo
),
1202 CPPU_TYPE_REF( lang::XComponent
),
1203 CPPU_TYPE_REF( ucb::XContent
),
1204 CPPU_TYPE_REF( ucb::XCommandProcessor
),
1205 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
1206 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
1207 CPPU_TYPE_REF( beans::XPropertyContainer
),
1208 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
1209 CPPU_TYPE_REF( container::XChild
) );
1211 return aFileCollection
.getTypes();
1215 uno::Sequence
< beans::Property
> Content::getProperties(
1216 const uno::Reference
< ucb::XCommandEnvironment
> & /*xEnv*/ )
1218 static const beans::Property aGenericProperties
[] =
1220 beans::Property( OUString( "IsDocument" ),
1221 -1, getCppuBooleanType(),
1222 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1223 beans::Property( OUString( "IsFolder" ),
1224 -1, getCppuBooleanType(),
1225 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1226 beans::Property( OUString( "Title" ),
1227 -1, getCppuType( static_cast< const OUString
* >( 0 ) ),
1228 beans::PropertyAttribute::BOUND
),
1229 beans::Property( OUString( "IsReadOnly" ),
1230 -1, getCppuBooleanType(),
1231 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1232 beans::Property( OUString( "DateCreated" ),
1233 -1, getCppuType( static_cast< const util::DateTime
* >( 0 ) ),
1234 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1235 beans::Property( OUString( "DateModified" ),
1236 -1, getCppuType( static_cast< const util::DateTime
* >( 0 ) ),
1237 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1238 beans::Property( OUString( "Size" ),
1239 -1, getCppuType( static_cast< const sal_Int64
* >( 0 ) ),
1240 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1241 beans::Property( OUString( "IsVolume" ),
1242 -1, getCppuBooleanType(),
1243 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1244 beans::Property( OUString( "IsCompactDisc" ),
1245 -1, getCppuBooleanType(),
1246 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1247 beans::Property( OUString( "IsRemoveable" ),
1248 -1, getCppuBooleanType(),
1249 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1250 beans::Property( OUString( "IsHidden" ),
1251 -1, getCppuBooleanType(),
1252 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
),
1253 beans::Property( OUString( "CreatableContentsInfo" ),
1254 -1, getCppuType( static_cast< const uno::Sequence
< ucb::ContentInfo
> * >( 0 ) ),
1255 beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY
)
1258 const int nProps
= sizeof (aGenericProperties
) / sizeof (aGenericProperties
[0]);
1259 return uno::Sequence
< beans::Property
> ( aGenericProperties
, nProps
);
1262 uno::Sequence
< ucb::CommandInfo
> Content::getCommands( const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1264 static ucb::CommandInfo aCommandInfoTable
[] =
1266 // Required commands
1268 ( OUString( "getCommandInfo" ),
1269 -1, getCppuVoidType() ),
1271 ( OUString( "getPropertySetInfo" ),
1272 -1, getCppuVoidType() ),
1274 ( OUString( "getPropertyValues" ),
1275 -1, getCppuType( static_cast<uno::Sequence
< beans::Property
> * >( 0 ) ) ),
1277 ( OUString( "setPropertyValues" ),
1278 -1, getCppuType( static_cast<uno::Sequence
< beans::PropertyValue
> * >( 0 ) ) ),
1280 // Optional standard commands
1282 ( OUString( "delete" ),
1283 -1, getCppuBooleanType() ),
1285 ( OUString( "insert" ),
1286 -1, getCppuType( static_cast<ucb::InsertCommandArgument
* >( 0 ) ) ),
1288 ( OUString( "open" ),
1289 -1, getCppuType( static_cast<ucb::OpenCommandArgument2
* >( 0 ) ) ),
1291 // Folder Only, omitted if not a folder
1293 ( OUString( "transfer" ),
1294 -1, getCppuType( static_cast<ucb::TransferInfo
* >( 0 ) ) ),
1296 ( OUString( "createNewContent" ),
1297 -1, getCppuType( static_cast<ucb::ContentInfo
* >( 0 ) ) )
1300 const int nProps
= sizeof (aCommandInfoTable
) / sizeof (aCommandInfoTable
[0]);
1301 return uno::Sequence
< ucb::CommandInfo
>(aCommandInfoTable
, isFolder(xEnv
) ? nProps
: nProps
- 2);
1304 XTYPEPROVIDER_COMMON_IMPL( Content
);
1306 void SAL_CALL
Content::acquire() throw()
1308 ContentImplHelper::acquire();
1311 void SAL_CALL
Content::release() throw()
1313 ContentImplHelper::release();
1316 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
) throw ( uno::RuntimeException
)
1318 uno::Any aRet
= cppu::queryInterface( rType
, static_cast< ucb::XContentCreator
* >( this ) );
1319 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface(rType
);
1322 OUString SAL_CALL
Content::getImplementationName() throw( uno::RuntimeException
)
1324 return OUString("com.sun.star.comp.GIOContent");
1327 uno::Sequence
< OUString
> SAL_CALL
Content::getSupportedServiceNames()
1328 throw( uno::RuntimeException
)
1330 uno::Sequence
< OUString
> aSNS( 1 );
1331 aSNS
.getArray()[ 0 ] = OUString("com.sun.star.ucb.GIOContent");
1337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */