Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / gio / gio_content.cxx
blobb675f25109bba919e82fe54f372a3dfc25d9d052
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <string.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sal/macros.h>
24 #include <osl/time.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"
78 #include <stdio.h>
80 using namespace com::sun::star;
82 namespace gio
85 Content::Content(
86 const uno::Reference< uno::XComponentContext >& rxContext,
87 ContentProvider* pProvider,
88 const uno::Reference< ucb::XContentIdentifier >& Identifier)
89 throw ( ucb::ContentCreationException )
90 : ContentImplHelper( rxContext, pProvider, Identifier ),
91 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());
95 #endif
98 Content::Content(
99 const uno::Reference< uno::XComponentContext >& rxContext,
100 ContentProvider* pProvider,
101 const uno::Reference< ucb::XContentIdentifier >& Identifier,
102 sal_Bool bIsFolder)
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());
109 #endif
110 mpInfo = g_file_info_new();
111 g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
114 Content::~Content()
116 if (mpInfo) g_object_unref(mpInfo);
117 if (mpFile) g_object_unref(mpFile);
120 rtl::OUString Content::getParentURL()
122 rtl::OUString sURL;
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);
128 g_free(pPath);
130 return sURL;
133 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
134 throw( uno::RuntimeException )
136 //TODO
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) \
149 do { \
150 if (bThrow) throw aExcept;\
151 aRet = uno::makeAny( aExcept );\
152 } while(0)
154 uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
156 uno::Any aRet;
158 gint eCode = pError->code;
159 rtl::OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
160 g_error_free(pError);
162 rtl::OUString sName;
163 rtl::OUString sHost;
165 uno::Sequence< uno::Any > aArgs( 1 );
166 aArgs[ 0 ] <<= sName;
168 switch (eCode)
170 case G_IO_ERROR_FAILED:
171 { io::IOException aExcept(sMessage, rContext);
172 EXCEPT(aExcept); }
173 break;
174 case G_IO_ERROR_NOT_MOUNTED:
175 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
176 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
177 EXCEPT(aExcept); }
178 break;
179 case G_IO_ERROR_NOT_FOUND:
180 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
181 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
182 EXCEPT(aExcept); }
183 break;
184 case G_IO_ERROR_EXISTS:
185 { ucb::NameClashException aExcept(sMessage, rContext,
186 task::InteractionClassification_ERROR, sName);
187 EXCEPT(aExcept); }
188 break;
189 case G_IO_ERROR_INVALID_ARGUMENT:
190 { lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
191 EXCEPT(aExcept); }
192 break;
193 case G_IO_ERROR_PERMISSION_DENIED:
194 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
195 task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
196 EXCEPT(aExcept); }
197 break;
198 case G_IO_ERROR_IS_DIRECTORY:
199 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
200 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
201 EXCEPT(aExcept); }
202 break;
203 case G_IO_ERROR_NOT_REGULAR_FILE:
204 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
205 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
206 EXCEPT(aExcept); }
207 break;
208 case G_IO_ERROR_NOT_DIRECTORY:
209 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
210 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
211 EXCEPT(aExcept); }
212 break;
213 case G_IO_ERROR_FILENAME_TOO_LONG:
214 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
215 task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
216 EXCEPT(aExcept); }
217 break;
218 case G_IO_ERROR_PENDING:
219 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
220 task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
221 EXCEPT(aExcept); }
222 break;
223 case G_IO_ERROR_CLOSED:
224 case G_IO_ERROR_CANCELLED:
225 case G_IO_ERROR_TOO_MANY_LINKS:
226 case G_IO_ERROR_WRONG_ETAG:
227 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
228 task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
229 EXCEPT(aExcept); }
230 break;
231 case G_IO_ERROR_NOT_SUPPORTED:
232 case G_IO_ERROR_CANT_CREATE_BACKUP:
233 case G_IO_ERROR_WOULD_MERGE:
234 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
235 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
236 EXCEPT(aExcept); }
237 break;
238 case G_IO_ERROR_NO_SPACE:
239 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
240 task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
241 EXCEPT(aExcept); }
242 break;
243 case G_IO_ERROR_INVALID_FILENAME:
244 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
245 task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
246 EXCEPT(aExcept); }
247 break;
248 case G_IO_ERROR_READ_ONLY:
249 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
250 task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
251 EXCEPT(aExcept); }
252 break;
253 case G_IO_ERROR_TIMED_OUT:
254 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
255 task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
256 EXCEPT(aExcept); }
257 break;
258 case G_IO_ERROR_WOULD_RECURSE:
259 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
260 task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
261 EXCEPT(aExcept); }
262 break;
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);
267 EXCEPT(aExcept); }
268 break;
269 case G_IO_ERROR_HOST_NOT_FOUND:
270 { ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
271 task::InteractionClassification_ERROR, sHost);
272 EXCEPT(aExcept);}
273 break;
274 default:
275 case G_IO_ERROR_ALREADY_MOUNTED:
276 case G_IO_ERROR_NOT_EMPTY:
277 case G_IO_ERROR_NOT_SYMBOLIC_LINK:
278 case G_IO_ERROR_NOT_MOUNTABLE_FILE:
279 case G_IO_ERROR_FAILED_HANDLED:
280 { ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
281 task::InteractionClassification_ERROR);
282 EXCEPT(aExcept);}
283 break;
285 return aRet;
288 uno::Any Content::mapGIOError( GError *pError )
290 if (!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) );
303 class MountOperation
305 GMainLoop *mpLoop;
306 GMountOperation *mpAuthentication;
307 GError *mpError;
308 static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
309 public:
310 MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
311 ~MountOperation();
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);
332 return mpError;
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
357 if (!*ppError)
358 mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError);
362 return mpInfo;
365 GFile* Content::getGFile()
367 if (!mpFile)
368 mpFile = g_file_new_for_uri(rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
369 return mpFile;
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)
380 TimeValue tv;
381 tv.Nanosec = 0;
382 tv.Seconds = t;
383 oslDateTime dt;
385 if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
386 return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
387 dt.Day, dt.Month, dt.Year);
388 else
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 );
399 sal_Int32 nProps;
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 ) );
414 else
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 ));
421 else
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) );
431 else
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) );
438 else
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)) );
445 else
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)) );
452 else
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 ) ));
459 else
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) );
471 else
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 ) );
478 else
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 ) ) );
489 else
490 xRow->appendVoid( rProp );
492 else if ( rProp.Name == "CreatableContentsInfo" )
494 xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
496 #ifdef DEBUG
497 else
499 fprintf(stderr, "Looking for unsupported property %s\n",
500 rtl::OUStringToOString(rProp.Name, RTL_TEXTENCODING_UTF8).getStr());
502 #endif
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);
514 if (!pInfo)
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
530 // of this content.
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();
546 while ( it != 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() ) ) );
563 ++it;
567 sal_Bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
569 if ( !xNewId.is() )
570 return sal_False;
572 uno::Reference< ucb::XContent > xThis = this;
574 if ( mbTransient )
576 m_xIdentifier = xNewId;
577 return sal_False;
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();
592 while ( it != 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 ) )
606 return sal_False;
608 ++it;
610 return sal_True;
613 return sal_False;
616 uno::Sequence< uno::Any > Content::setPropertyValues(
617 const uno::Sequence< beans::PropertyValue >& rValues,
618 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
620 GError *pError=NULL;
621 GFileInfo *pNewInfo=NULL;
622 GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
623 if (pInfo)
624 pNewInfo = g_file_info_dup(pInfo);
625 else
627 if (!mbTransient)
628 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
629 else
631 if (pError)
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());
655 #endif
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 ) );
673 continue;
676 if ( aNewTitle.getLength() <= 0 )
678 aRet[ n ] <<= lang::IllegalArgumentException
679 ( rtl::OUString("Empty title not allowed!"),
680 static_cast< cppu::OWeakObject * >( this ), -1 );
681 continue;
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);
693 #endif
695 aEvent.PropertyName = rtl::OUString("Title");
696 if (oldName)
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);
705 else
707 #ifdef DEBUG
708 fprintf(stderr, "Unknown property %s\n", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
709 #endif
710 aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
711 //TODO
715 if (nChanged)
717 bool bOk = true;
718 if (!mbTransient)
720 if ((bOk = doSetFileInfo(pNewInfo)))
722 for (sal_Int32 i = 0; i < nChanged; ++i)
723 aRet[ i ] <<= getBadArgExcept();
727 if (bOk)
729 if (nTitlePos > -1)
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);
747 mpInfo = NULL;
750 if (mpInfo)
752 g_file_info_copy_into(pNewInfo, mpInfo);
753 g_object_unref(pNewInfo);
755 else
756 mpInfo = pNewInfo;
758 if (mpFile) //Discard and refetch
760 g_object_unref(mpFile);
761 mpFile = NULL;
765 aChanges.realloc( nChanged );
766 notifyPropertiesChange( aChanges );
769 return aRet;
772 bool Content::doSetFileInfo(GFileInfo *pNewInfo)
774 g_assert (!mbTransient);
776 bool bOk = true;
777 GFile *pFile = getGFile();
778 if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
779 bOk = false;
780 return bOk;
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 );
795 xOut->closeOutput();
798 sal_Bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
799 const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
801 if ( !xSink.is() )
802 return sal_False;
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() )
808 return sal_False;
810 GError *pError=NULL;
811 GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
812 if (!pStream)
813 convertToException(pError, static_cast< cppu::OWeakObject * >(this));
815 uno::Reference< io::XInputStream > xIn = new ::gio::InputStream(pStream);
816 if ( !xIn.is() )
817 return sal_False;
819 if ( xOut.is() )
820 copyData( xIn, xOut );
822 if ( xDataSink.is() )
823 xDataSink->setInputStream( xIn );
825 return sal_True;
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);
847 uno::Any aRet;
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 );
859 aRet <<= xSet;
861 else if ( rOpenCommand.Sink.is() )
863 if (
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 ) ) ),
872 xEnv );
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...
880 #ifdef DEBUG
881 g_warning ("Failed to load data from '%s'",
882 rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
883 #endif
885 ucbhelper::cancelCommandExecution(
886 uno::makeAny (ucb::UnsupportedDataSinkException
887 ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
888 rOpenCommand.Sink ) ),
889 xEnv );
892 else
893 g_warning ("Open falling through ...");
894 return aRet;
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());
907 #endif
908 uno::Any aRet;
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;
967 if (bDeletePhysical)
969 GError *pError = NULL;
970 if (!g_file_delete( getGFile(), NULL, &pError))
971 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
974 destroy( bDeletePhysical );
976 else
978 #ifdef DEBUG
979 fprintf(stderr, "UNKNOWN COMMAND\n");
980 //TODO
981 #endif
983 ucbhelper::cancelCommandExecution
984 ( uno::makeAny( ucb::UnsupportedCommandException
985 ( rtl::OUString(),
986 static_cast< cppu::OWeakObject * >( this ) ) ),
987 xEnv );
990 return aRet;
993 void Content::destroy( sal_Bool bDeletePhysical )
994 throw( uno::Exception )
996 uno::Reference< ucb::XContent > xThis = this;
998 deleted();
1000 ::gio::Content::ContentRefList aChildren;
1001 queryChildren( aChildren );
1003 ContentRefList::const_iterator it = aChildren.begin();
1004 ContentRefList::const_iterator end = aChildren.end();
1006 while ( it != end )
1008 (*it)->destroy( bDeletePhysical );
1009 ++it;
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);
1020 if ( pInfo &&
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");
1026 #endif
1027 if( !g_file_make_directory( getGFile(), NULL, &pError))
1028 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1029 return;
1032 if ( !xInputStream.is() )
1034 ucbhelper::cancelCommandExecution( uno::makeAny
1035 ( ucb::MissingInputStreamException
1036 ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
1037 xEnv );
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);
1046 else
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 );
1055 if (mbTransient)
1057 mbTransient = sal_False;
1058 inserted();
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;
1071 else
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);
1081 else
1082 bSuccess = g_file_copy(pSource, pDest, DEFAULT_COPYDATA_FLAGS, NULL, NULL, 0, &pError);
1083 g_object_unref(pSource);
1084 g_object_unref(pDest);
1085 if (!bSuccess)
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 );
1105 // file
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;
1111 // folder
1112 seq[1].Type = rtl::OUString( GIO_FOLDER_TYPE );
1113 seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
1114 seq[1].Properties = props;
1116 return seq;
1118 else
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;
1135 const char *name;
1137 if ( Info.Type == GIO_FILE_TYPE )
1138 create_document = true;
1139 else if ( Info.Type == GIO_FOLDER_TYPE )
1140 create_document = false;
1141 else
1143 #ifdef DEBUG
1144 g_warning( "Failed to create new content '%s'", rtl::OUStringToOString(Info.Type,
1145 RTL_TEXTENCODING_UTF8).getStr() );
1146 #endif
1147 return uno::Reference< ucb::XContent >();
1150 #if OSL_DEBUG_LEVEL > 1
1151 g_warning( "createNewContent (%d)", (int) create_document );
1152 #endif
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();
1192 else
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
1262 ucb::CommandInfo
1263 ( rtl::OUString( "getCommandInfo" ),
1264 -1, getCppuVoidType() ),
1265 ucb::CommandInfo
1266 ( rtl::OUString( "getPropertySetInfo" ),
1267 -1, getCppuVoidType() ),
1268 ucb::CommandInfo
1269 ( rtl::OUString( "getPropertyValues" ),
1270 -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
1271 ucb::CommandInfo
1272 ( rtl::OUString( "setPropertyValues" ),
1273 -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
1275 // Optional standard commands
1276 ucb::CommandInfo
1277 ( rtl::OUString( "delete" ),
1278 -1, getCppuBooleanType() ),
1279 ucb::CommandInfo
1280 ( rtl::OUString( "insert" ),
1281 -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
1282 ucb::CommandInfo
1283 ( rtl::OUString( "open" ),
1284 -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
1286 // Folder Only, omitted if not a folder
1287 ucb::CommandInfo
1288 ( rtl::OUString( "transfer" ),
1289 -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
1290 ucb::CommandInfo
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");
1327 return aSNS;
1332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */