merge the formfield patch from ooo-build
[ooovba.git] / ucb / source / ucp / gio / gio_content.cxx
blobfa6d8f74c898089bb684731e58797fd7c67a0b31
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gio_content.cxx,v $
10 * $Revision: 1.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <string.h>
32 #include <unistd.h>
33 #include <sys/types.h>
35 #include <osl/time.h>
37 #include <osl/diagnose.h>
38 #include <osl/doublecheckedlocking.h>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <com/sun/star/beans/PropertyAttribute.hpp>
42 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
43 #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
44 #include <com/sun/star/io/XActiveDataSink.hpp>
45 #include <com/sun/star/io/XOutputStream.hpp>
46 #include <com/sun/star/lang/IllegalAccessException.hpp>
47 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
48 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
49 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
50 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
51 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
52 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
53 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
54 #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
55 #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
56 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
57 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
58 #include <com/sun/star/ucb/NameClash.hpp>
59 #include <com/sun/star/ucb/NameClashException.hpp>
60 #include <com/sun/star/ucb/OpenMode.hpp>
61 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
62 #include <com/sun/star/ucb/XCommandInfo.hpp>
63 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
64 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
65 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
66 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
67 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
68 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
69 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
70 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
71 #include <com/sun/star/ucb/NameClashException.hpp>
72 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
73 #include <com/sun/star/ucb/XContentCreator.hpp>
75 #include <ucbhelper/contentidentifier.hxx>
76 #include <ucbhelper/propertyvalueset.hxx>
77 #include <ucbhelper/interactionrequest.hxx>
78 #include <ucbhelper/cancelcommandexecution.hxx>
80 #include <osl/conditn.hxx>
82 #include "gio_content.hxx"
83 #include "gio_provider.hxx"
84 #include "gio_resultset.hxx"
85 #include "gio_inputstream.hxx"
86 #include "gio_outputstream.hxx"
87 #include "gio_mount.hxx"
89 #include <stdio.h>
91 using namespace com::sun::star;
93 namespace gio
96 Content::Content(
97 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
98 ContentProvider* pProvider,
99 const uno::Reference< ucb::XContentIdentifier >& Identifier)
100 throw ( ucb::ContentCreationException )
101 : ContentImplHelper( rxSMgr, pProvider, Identifier ),
102 m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(false)
104 #ifdef DEBUG
105 fprintf(stderr, "New Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
106 #endif
109 Content::Content(
110 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
111 ContentProvider* pProvider,
112 const uno::Reference< ucb::XContentIdentifier >& Identifier,
113 sal_Bool bIsFolder)
114 throw ( ucb::ContentCreationException )
115 : ContentImplHelper( rxSMgr, pProvider, Identifier ),
116 m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(true)
118 #ifdef DEBUG
119 fprintf(stderr, "Create Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
120 #endif
121 mpInfo = g_file_info_new();
122 g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
125 Content::~Content()
127 if (mpInfo) g_object_unref(mpInfo);
128 if (mpFile) g_object_unref(mpFile);
131 rtl::OUString Content::getParentURL()
133 rtl::OUString sURL;
134 if (GFile* pFile = g_file_get_parent(getGFile()))
136 char* pPath = g_file_get_uri(pFile);
137 g_object_unref(pFile);
138 sURL = rtl::OUString::createFromAscii(pPath);
139 g_free(pPath);
141 return sURL;
144 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
145 throw( uno::RuntimeException )
147 //TODO
148 //stick a map from each CommandId to a new GCancellable and propogate
149 //it throughout the g_file_* calls
152 rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException )
154 return isFolder(uno::Reference< ucb::XCommandEnvironment >())
155 ? rtl::OUString::createFromAscii( GIO_FOLDER_TYPE )
156 : rtl::OUString::createFromAscii( GIO_FILE_TYPE );
159 #define EXCEPT(aExcept) \
160 do { \
161 if (bThrow) throw aExcept;\
162 aRet = uno::makeAny( aExcept );\
163 } while(0)
165 uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
167 uno::Any aRet;
169 gint eCode = pError->code;
170 rtl::OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
171 g_error_free(pError);
173 rtl::OUString sName;
174 rtl::OUString sHost;
176 uno::Sequence< uno::Any > aArgs( 1 );
177 aArgs[ 0 ] <<= sName;
179 switch (eCode)
181 case G_IO_ERROR_FAILED:
182 { io::IOException aExcept(sMessage, rContext);
183 EXCEPT(aExcept); }
184 break;
185 case G_IO_ERROR_NOT_MOUNTED:
186 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
187 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
188 EXCEPT(aExcept); }
189 break;
190 case G_IO_ERROR_NOT_FOUND:
191 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
192 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
193 EXCEPT(aExcept); }
194 break;
195 case G_IO_ERROR_EXISTS:
196 { ucb::NameClashException aExcept(sMessage, rContext,
197 task::InteractionClassification_ERROR, sName);
198 EXCEPT(aExcept); }
199 break;
200 case G_IO_ERROR_INVALID_ARGUMENT:
201 { lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
202 EXCEPT(aExcept); }
203 break;
204 case G_IO_ERROR_PERMISSION_DENIED:
205 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
206 task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
207 EXCEPT(aExcept); }
208 break;
209 case G_IO_ERROR_IS_DIRECTORY:
210 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
211 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
212 EXCEPT(aExcept); }
213 break;
214 case G_IO_ERROR_NOT_REGULAR_FILE:
215 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
216 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
217 EXCEPT(aExcept); }
218 break;
219 case G_IO_ERROR_NOT_DIRECTORY:
220 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
221 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
222 EXCEPT(aExcept); }
223 break;
224 case G_IO_ERROR_FILENAME_TOO_LONG:
225 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
226 task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
227 EXCEPT(aExcept); }
228 break;
229 case G_IO_ERROR_PENDING:
230 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
231 task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
232 EXCEPT(aExcept); }
233 break;
234 case G_IO_ERROR_CLOSED:
235 case G_IO_ERROR_CANCELLED:
236 case G_IO_ERROR_TOO_MANY_LINKS:
237 case G_IO_ERROR_WRONG_ETAG:
238 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
239 task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
240 EXCEPT(aExcept); }
241 break;
242 case G_IO_ERROR_NOT_SUPPORTED:
243 case G_IO_ERROR_CANT_CREATE_BACKUP:
244 case G_IO_ERROR_WOULD_MERGE:
245 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
246 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
247 EXCEPT(aExcept); }
248 break;
249 case G_IO_ERROR_NO_SPACE:
250 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
251 task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
252 EXCEPT(aExcept); }
253 break;
254 case G_IO_ERROR_INVALID_FILENAME:
255 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
256 task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
257 EXCEPT(aExcept); }
258 break;
259 case G_IO_ERROR_READ_ONLY:
260 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
261 task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
262 EXCEPT(aExcept); }
263 break;
264 case G_IO_ERROR_TIMED_OUT:
265 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
266 task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
267 EXCEPT(aExcept); }
268 break;
269 case G_IO_ERROR_WOULD_RECURSE:
270 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
271 task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
272 EXCEPT(aExcept); }
273 break;
274 case G_IO_ERROR_BUSY:
275 case G_IO_ERROR_WOULD_BLOCK:
276 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
277 task::InteractionClassification_ERROR, ucb::IOErrorCode_LOCKING_VIOLATION, aArgs);
278 EXCEPT(aExcept); }
279 break;
280 case G_IO_ERROR_HOST_NOT_FOUND:
281 { ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
282 task::InteractionClassification_ERROR, sHost);
283 EXCEPT(aExcept);}
284 break;
285 default:
286 case G_IO_ERROR_ALREADY_MOUNTED:
287 case G_IO_ERROR_NOT_EMPTY:
288 case G_IO_ERROR_NOT_SYMBOLIC_LINK:
289 case G_IO_ERROR_NOT_MOUNTABLE_FILE:
290 case G_IO_ERROR_FAILED_HANDLED:
291 { ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
292 task::InteractionClassification_ERROR);
293 EXCEPT(aExcept);}
294 break;
296 return aRet;
299 uno::Any Content::mapGIOError( GError *pError )
301 if (!pError)
302 return getBadArgExcept();
304 return convertToException(pError, static_cast< cppu::OWeakObject * >(this), false);
307 uno::Any Content::getBadArgExcept()
309 return uno::makeAny( lang::IllegalArgumentException(
310 rtl::OUString::createFromAscii( "Wrong argument type!" ),
311 static_cast< cppu::OWeakObject * >( this ), -1) );
314 class MountOperation
316 GMainLoop *mpLoop;
317 GMountOperation *mpAuthentication;
318 GError *mpError;
319 static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
320 public:
321 MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
322 ~MountOperation();
323 GError *Mount(GFile *pFile);
326 MountOperation::MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv) : mpError(NULL)
328 mpLoop = g_main_loop_new(NULL, FALSE);
329 mpAuthentication = ooo_mount_operation_new(xEnv);
332 void MountOperation::Completed(GObject *source, GAsyncResult *res, gpointer user_data)
334 MountOperation *pThis = (MountOperation*)user_data;
335 g_file_mount_enclosing_volume_finish(G_FILE(source), res, &(pThis->mpError));
336 g_main_loop_quit(pThis->mpLoop);
339 GError *MountOperation::Mount(GFile *pFile)
341 g_file_mount_enclosing_volume(pFile, G_MOUNT_MOUNT_NONE, mpAuthentication, NULL, MountOperation::Completed, this);
342 g_main_loop_run(mpLoop);
343 return mpError;
346 MountOperation::~MountOperation()
348 g_object_unref(mpAuthentication);
349 g_main_loop_unref(mpLoop);
352 GFileInfo* Content::getGFileInfo(const uno::Reference< ucb::XCommandEnvironment >& xEnv, GError **ppError)
354 /*If we don't have it already, and we're not a "pre-creation" content then query for the info"*/
355 if (!mpInfo && !mbTransient)
357 if (!(mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError)))
359 //Try and mount if unmounted
360 if (ppError && (*ppError)->code == G_IO_ERROR_NOT_MOUNTED)
362 g_error_free(*ppError);
364 MountOperation aMounter(xEnv);
365 *ppError = aMounter.Mount(getGFile());
367 //No Mount error, reattempt query
368 if (!*ppError)
369 mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError);
373 return mpInfo;
376 GFile* Content::getGFile()
378 if (!mpFile)
379 mpFile = g_file_new_for_uri(rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
380 return mpFile;
383 bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv)
385 GFileInfo *pInfo = getGFileInfo(xEnv);
386 return pInfo && (g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY);
389 static util::DateTime getDateFromUnix (time_t t)
391 TimeValue tv;
392 tv.Nanosec = 0;
393 tv.Seconds = t;
394 oslDateTime dt;
396 if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
397 return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
398 dt.Day, dt.Month, dt.Year);
399 else
400 return util::DateTime();
403 uno::Reference< sdbc::XRow > Content::getPropertyValuesFromGFileInfo(GFileInfo *pInfo,
404 const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
405 const uno::Sequence< beans::Property >& rProperties)
407 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rSMgr );
409 sal_Int32 nProps;
410 const beans::Property* pProps;
412 nProps = rProperties.getLength();
413 pProps = rProperties.getConstArray();
415 for( sal_Int32 n = 0; n < nProps; ++n )
417 const beans::Property& rProp = pProps[ n ];
419 if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
421 if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE))
422 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_REGULAR ||
423 g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_UNKNOWN ) );
424 else
425 xRow->appendVoid( rProp );
427 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
429 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) )
430 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_DIRECTORY ));
431 else
432 xRow->appendVoid( rProp );
434 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
436 if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
438 const char *pName = g_file_info_get_display_name(pInfo);
439 xRow->appendString( rProp, rtl::OUString(pName, strlen(pName), RTL_TEXTENCODING_UTF8) );
441 else
442 xRow->appendVoid( rProp );
444 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) )
446 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) )
447 xRow->appendBoolean( rProp, !g_file_info_get_attribute_boolean( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) );
448 else
449 xRow->appendVoid( rProp );
451 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
453 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CREATED ) )
454 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CREATED)) );
455 else
456 xRow->appendVoid( rProp );
458 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
460 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED ) )
461 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED)) );
462 else
463 xRow->appendVoid( rProp );
465 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
467 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE) )
468 xRow->appendLong( rProp, ( g_file_info_get_size( pInfo ) ));
469 else
470 xRow->appendVoid( rProp );
472 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) )
474 //What do we use this for ?
475 xRow->appendBoolean( rProp, sal_False );
477 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisc" ) ) )
479 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT ) )
480 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT) );
481 else
482 xRow->appendVoid( rProp );
484 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsRemoveable" ) ) )
486 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) )
487 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) );
488 else
489 xRow->appendVoid( rProp );
491 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFloppy" ) ) )
493 xRow->appendBoolean( rProp, sal_False );
495 else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
497 if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) )
498 xRow->appendBoolean( rProp, ( g_file_info_get_is_hidden ( pInfo ) ) );
499 else
500 xRow->appendVoid( rProp );
502 #ifdef DEBUG
503 else
505 fprintf(stderr, "Looking for unsupported property %s\n",
506 rtl::OUStringToOString(rProp.Name, RTL_TEXTENCODING_UTF8).getStr());
508 #endif
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 GError *pError = NULL;
519 GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
520 if (!pInfo)
521 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
523 return getPropertyValuesFromGFileInfo(pInfo, m_xSMgr, rProperties);
526 static lang::IllegalAccessException
527 getReadOnlyException( const uno::Reference< uno::XInterface >& rContext )
529 return lang::IllegalAccessException ( rtl::OUString::createFromAscii( "Property is read-only!" ), rContext );
532 void Content::queryChildren( ContentRefList& rChildren )
534 // Obtain a list with a snapshot of all currently instanciated contents
535 // from provider and extract the contents which are direct children
536 // of this content.
538 ucbhelper::ContentRefList aAllContents;
539 m_xProvider->queryExistingContents( aAllContents );
541 rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
542 sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
544 if ( nURLPos != ( aURL.getLength() - 1 ) )
545 aURL += rtl::OUString::createFromAscii( "/" );
547 sal_Int32 nLen = aURL.getLength();
549 ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
550 ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
552 while ( it != end )
554 ucbhelper::ContentImplHelperRef xChild = (*it);
555 rtl::OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
557 // Is aURL a prefix of aChildURL?
558 if ( ( aChildURL.getLength() > nLen ) && ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
560 sal_Int32 nPos = nLen;
561 nPos = aChildURL.indexOf( '/', nPos );
563 if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) )
565 // No further slashes / only a final slash. It's a child!
566 rChildren.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content * >(xChild.get() ) ) );
569 ++it;
573 sal_Bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
575 if ( !xNewId.is() )
576 return sal_False;
578 uno::Reference< ucb::XContent > xThis = this;
580 if ( mbTransient )
582 m_xIdentifier = xNewId;
583 return sal_False;
586 rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
588 // Exchange own identitity.
589 if ( exchange( xNewId ) )
591 // Process instanciated children...
592 ContentRefList aChildren;
593 queryChildren( aChildren );
595 ContentRefList::const_iterator it = aChildren.begin();
596 ContentRefList::const_iterator end = aChildren.end();
598 while ( it != end )
600 ContentRef xChild = (*it);
602 // Create new content identifier for the child...
603 uno::Reference< ucb::XContentIdentifier > xOldChildId = xChild->getIdentifier();
604 rtl::OUString aOldChildURL = xOldChildId->getContentIdentifier();
605 rtl::OUString aNewChildURL = aOldChildURL.replaceAt(
606 0, aOldURL.getLength(), xNewId->getContentIdentifier() );
608 uno::Reference< ucb::XContentIdentifier > xNewChildId
609 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL );
611 if ( !xChild->exchangeIdentity( xNewChildId ) )
612 return sal_False;
614 ++it;
616 return sal_True;
619 return sal_False;
622 uno::Sequence< uno::Any > Content::setPropertyValues(
623 const uno::Sequence< beans::PropertyValue >& rValues,
624 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
626 GError *pError=NULL;
627 GFileInfo *pNewInfo=NULL;
628 GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
629 if (pInfo)
630 pNewInfo = g_file_info_dup(pInfo);
631 else
633 if (!mbTransient)
634 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
635 else
637 if (pError)
638 g_error_free(pError);
639 pNewInfo = g_file_info_new();
643 sal_Int32 nCount = rValues.getLength();
645 beans::PropertyChangeEvent aEvent;
646 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
647 aEvent.Further = sal_False;
648 aEvent.PropertyHandle = -1;
650 sal_Int32 nChanged = 0, nTitlePos = -1;
651 const char *newName = NULL;
652 uno::Sequence< beans::PropertyChangeEvent > aChanges(nCount);
654 uno::Sequence< uno::Any > aRet( nCount );
655 const beans::PropertyValue* pValues = rValues.getConstArray();
656 for ( sal_Int32 n = 0; n < nCount; ++n )
658 const beans::PropertyValue& rValue = pValues[ n ];
659 #ifdef DEBUG
660 g_warning("Set prop '%s'", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
661 #endif
662 if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
663 rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
664 rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
665 rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
666 rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
668 aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
670 else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
672 rtl::OUString aNewTitle;
673 if (!( rValue.Value >>= aNewTitle ))
675 aRet[ n ] <<= beans::IllegalTypeException
676 ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
677 static_cast< cppu::OWeakObject * >( this ) );
678 continue;
681 if ( aNewTitle.getLength() <= 0 )
683 aRet[ n ] <<= lang::IllegalArgumentException
684 ( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
685 static_cast< cppu::OWeakObject * >( this ), -1 );
686 continue;
690 rtl::OString sNewTitle = OUStringToOString(aNewTitle, RTL_TEXTENCODING_UTF8);
691 newName = sNewTitle.getStr();
692 const char *oldName = g_file_info_get_name( pInfo);
694 if (!newName || !oldName || strcmp(newName, oldName))
696 #ifdef DEBUG
697 g_warning ("Set new name to '%s'", newName);
698 #endif
700 aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
701 if (oldName)
702 aEvent.OldValue = uno::makeAny(rtl::OUString(oldName, strlen(oldName), RTL_TEXTENCODING_UTF8));
703 aEvent.NewValue = uno::makeAny(aNewTitle);
704 aChanges.getArray()[ nChanged ] = aEvent;
705 nTitlePos = nChanged++;
707 g_file_info_set_name(pNewInfo, newName);
710 else
712 #ifdef DEBUG
713 fprintf(stderr, "Unknown property %s\n", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
714 #endif
715 aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
716 //TODO
720 if (nChanged)
722 bool bOk = true;
723 if (!mbTransient)
725 if ((bOk = doSetFileInfo(pNewInfo)))
727 for (sal_Int32 i = 0; i < nChanged; ++i)
728 aRet[ i ] <<= getBadArgExcept();
732 if (bOk)
734 if (nTitlePos > -1)
736 rtl::OUString aNewURL = getParentURL();
737 aNewURL += rtl::OUString( newName, strlen(newName), RTL_TEXTENCODING_UTF8 );
738 uno::Reference< ucb::XContentIdentifier > xNewId
739 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL );
741 if (!exchangeIdentity( xNewId ) )
743 aRet[ nTitlePos ] <<= uno::Exception
744 ( rtl::OUString::createFromAscii( "Exchange failed!" ),
745 static_cast< cppu::OWeakObject * >( this ) );
749 if (!mbTransient) //Discard and refetch
751 g_object_unref(mpInfo);
752 mpInfo = NULL;
755 if (mpInfo)
757 g_file_info_copy_into(pNewInfo, mpInfo);
758 g_object_unref(pNewInfo);
760 else
761 mpInfo = pNewInfo;
763 if (mpFile) //Discard and refetch
765 g_object_unref(mpFile);
766 mpFile = NULL;
770 aChanges.realloc( nChanged );
771 notifyPropertiesChange( aChanges );
774 return aRet;
777 bool Content::doSetFileInfo(GFileInfo *pNewInfo)
779 g_assert (!mbTransient);
781 bool bOk = true;
782 GFile *pFile = getGFile();
783 if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
784 bOk = false;
785 return bOk;
788 const int TRANSFER_BUFFER_SIZE = 65536;
790 void Content::copyData( uno::Reference< io::XInputStream > xIn,
791 uno::Reference< io::XOutputStream > xOut )
793 uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
795 g_return_if_fail( xIn.is() && xOut.is() );
797 while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
798 xOut->writeBytes( theData );
800 xOut->closeOutput();
803 sal_Bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
804 const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
806 if ( !xSink.is() )
807 return sal_False;
809 uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
810 uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
812 if ( !xOut.is() && !xDataSink.is() )
813 return sal_False;
815 GError *pError=NULL;
816 GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
817 if (!pStream)
818 convertToException(pError, static_cast< cppu::OWeakObject * >(this));
820 uno::Reference< io::XInputStream > xIn = new ::gio::InputStream(pStream);
821 if ( !xIn.is() )
822 return sal_False;
824 if ( xOut.is() )
825 copyData( xIn, xOut );
827 if ( xDataSink.is() )
828 xDataSink->setInputStream( xIn );
830 return sal_True;
833 uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
834 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
835 throw( uno::Exception )
837 bool bIsFolder = isFolder(xEnv);
839 if (!g_file_query_exists(getGFile(), NULL))
841 uno::Sequence< uno::Any > aArgs( 1 );
842 aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
843 uno::Any aErr = uno::makeAny(
844 ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
845 task::InteractionClassification_ERROR,
846 bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
849 ucbhelper::cancelCommandExecution(aErr, xEnv);
852 uno::Any aRet;
854 sal_Bool bOpenFolder = (
855 ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
856 ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
857 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
860 if ( bOpenFolder && bIsFolder )
862 uno::Reference< ucb::XDynamicResultSet > xSet
863 = new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
864 aRet <<= xSet;
866 else if ( rOpenCommand.Sink.is() )
868 if (
869 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
870 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
873 ucbhelper::cancelCommandExecution(
874 uno::makeAny ( ucb::UnsupportedOpenModeException
875 ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
876 sal_Int16( rOpenCommand.Mode ) ) ),
877 xEnv );
880 if ( !feedSink( rOpenCommand.Sink, xEnv ) )
882 // Note: rOpenCommand.Sink may contain an XStream
883 // implementation. Support for this type of
884 // sink is optional...
885 #ifdef DEBUG
886 g_warning ("Failed to load data from '%s'",
887 rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
888 #endif
890 ucbhelper::cancelCommandExecution(
891 uno::makeAny (ucb::UnsupportedDataSinkException
892 ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
893 rOpenCommand.Sink ) ),
894 xEnv );
897 else
898 g_warning ("Open falling through ...");
899 return aRet;
902 uno::Any SAL_CALL Content::execute(
903 const ucb::Command& aCommand,
904 sal_Int32 /*CommandId*/,
905 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
906 throw( uno::Exception,
907 ucb::CommandAbortedException,
908 uno::RuntimeException )
910 #ifdef DEBUG
911 fprintf(stderr, "Content::execute %s\n", rtl::OUStringToOString(aCommand.Name, RTL_TEXTENCODING_UTF8).getStr());
912 #endif
913 uno::Any aRet;
915 if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ))
917 uno::Sequence< beans::Property > Properties;
918 if ( !( aCommand.Argument >>= Properties ) )
919 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
920 aRet <<= getPropertyValues( Properties, xEnv );
922 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ))
923 aRet <<= getPropertySetInfo( xEnv, sal_False );
924 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ))
925 aRet <<= getCommandInfo( xEnv, sal_False );
926 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "open" ) ))
928 ucb::OpenCommandArgument2 aOpenCommand;
929 if ( !( aCommand.Argument >>= aOpenCommand ) )
930 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
931 aRet = open( aOpenCommand, xEnv );
933 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "transfer" ) ))
935 ucb::TransferInfo transferArgs;
936 if ( !( aCommand.Argument >>= transferArgs ) )
937 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
938 transfer( transferArgs, xEnv );
940 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ))
942 uno::Sequence< beans::PropertyValue > aProperties;
943 if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
944 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
945 aRet <<= setPropertyValues( aProperties, xEnv );
947 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ))
949 ucb::InsertCommandArgument arg;
950 if ( !( aCommand.Argument >>= arg ) )
951 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
952 insert( arg.Data, arg.ReplaceExisting, xEnv );
954 else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ))
956 sal_Bool bDeletePhysical = sal_False;
957 aCommand.Argument >>= bDeletePhysical;
959 //If no delete physical, try and trashcan it, if that doesn't work go
960 //ahead and try and delete it anyway
961 if (!bDeletePhysical && !g_file_trash(getGFile(), NULL, NULL))
962 bDeletePhysical = true;
964 if (bDeletePhysical)
966 GError *pError = NULL;
967 if (!g_file_delete( getGFile(), NULL, &pError))
968 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
971 destroy( bDeletePhysical );
973 else
975 #ifdef DEBUG
976 fprintf(stderr, "UNKNOWN COMMAND\n");
977 //TODO
978 #endif
980 ucbhelper::cancelCommandExecution
981 ( uno::makeAny( ucb::UnsupportedCommandException
982 ( rtl::OUString(),
983 static_cast< cppu::OWeakObject * >( this ) ) ),
984 xEnv );
987 return aRet;
990 void Content::destroy( sal_Bool bDeletePhysical )
991 throw( uno::Exception )
993 uno::Reference< ucb::XContent > xThis = this;
995 deleted();
997 ::gio::Content::ContentRefList aChildren;
998 queryChildren( aChildren );
1000 ContentRefList::const_iterator it = aChildren.begin();
1001 ContentRefList::const_iterator end = aChildren.end();
1003 while ( it != end )
1005 (*it)->destroy( bDeletePhysical );
1006 ++it;
1010 void Content::insert(const uno::Reference< io::XInputStream > &xInputStream,
1011 sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment > &xEnv )
1012 throw( uno::Exception )
1014 GError *pError = NULL;
1015 GFileInfo *pInfo = getGFileInfo(xEnv);
1017 if ( g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
1018 g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY )
1020 #ifdef DEBUG
1021 g_warning ("Make directory");
1022 #endif
1023 if( !g_file_make_directory( getGFile(), NULL, &pError))
1024 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1025 return;
1028 if ( !xInputStream.is() )
1030 ucbhelper::cancelCommandExecution( uno::makeAny
1031 ( ucb::MissingInputStreamException
1032 ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
1033 xEnv );
1036 GFileOutputStream* pOutStream = NULL;
1037 if ( bReplaceExisting )
1039 if (!(pOutStream = g_file_replace(getGFile(), NULL, false, G_FILE_CREATE_PRIVATE, NULL, &pError)))
1040 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1042 else
1044 if (!(pOutStream = g_file_create (getGFile(), G_FILE_CREATE_PRIVATE, NULL, &pError)))
1045 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1048 uno::Reference < io::XOutputStream > xOutput = new ::gio::OutputStream(pOutStream);
1049 copyData( xInputStream, xOutput );
1051 if (mbTransient)
1053 mbTransient = sal_False;
1054 inserted();
1058 void Content::transfer( const ucb::TransferInfo& aTransferInfo, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1059 throw( uno::Exception )
1061 rtl::OUString sDest = m_xIdentifier->getContentIdentifier();
1062 if (aTransferInfo.NewTitle.getLength())
1063 sDest += aTransferInfo.NewTitle;
1064 else
1065 sDest += rtl::OUString::createFromAscii(g_file_get_basename(getGFile()));
1067 GFile *pDest = g_file_new_for_uri(rtl::OUStringToOString(sDest, RTL_TEXTENCODING_UTF8).getStr());
1068 GFile *pSource = g_file_new_for_uri(rtl::OUStringToOString(aTransferInfo.SourceURL, RTL_TEXTENCODING_UTF8).getStr());
1070 gboolean bSuccess = false;
1071 GError *pError = NULL;
1072 if (aTransferInfo.MoveData)
1073 bSuccess = g_file_move(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
1074 else
1075 bSuccess = g_file_copy(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
1076 g_object_unref(pSource);
1077 g_object_unref(pDest);
1078 if (!bSuccess)
1079 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1082 com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
1083 throw( com::sun::star::uno::RuntimeException )
1085 uno::Sequence< ucb::ContentInfo > seq(2);
1087 // Minimum set of props we really need
1088 uno::Sequence< beans::Property > props( 1 );
1089 props[0] = beans::Property(
1090 rtl::OUString::createFromAscii( "Title" ),
1092 getCppuType( static_cast< rtl::OUString* >( 0 ) ),
1093 beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
1095 // file
1096 seq[0].Type = rtl::OUString::createFromAscii( GIO_FILE_TYPE );
1097 seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
1098 ucb::ContentInfoAttribute::KIND_DOCUMENT );
1099 seq[0].Properties = props;
1101 // folder
1102 seq[1].Type = rtl::OUString::createFromAscii( GIO_FOLDER_TYPE );
1103 seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
1104 seq[1].Properties = props;
1106 return seq;
1109 com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
1110 SAL_CALL Content::createNewContent( const com::sun::star::ucb::ContentInfo& Info )
1111 throw( com::sun::star::uno::RuntimeException )
1113 bool create_document;
1114 const char *name;
1116 if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FILE_TYPE ) ) )
1117 create_document = true;
1118 else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FOLDER_TYPE ) ) )
1119 create_document = false;
1120 else
1122 #ifdef DEBUG
1123 g_warning( "Failed to create new content '%s'", rtl::OUStringToOString(Info.Type,
1124 RTL_TEXTENCODING_UTF8).getStr() );
1125 #endif
1126 return uno::Reference< ucb::XContent >();
1129 #ifdef DEBUG
1130 g_warning( "createNewContent (%d)", (int) create_document );
1131 #endif
1133 rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
1135 if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
1136 aURL += rtl::OUString::createFromAscii( "/" );
1138 name = create_document ? "[New_Content]" : "[New_Collection]";
1139 aURL += rtl::OUString::createFromAscii( name );
1141 uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(m_xSMgr, aURL));
1145 return new ::gio::Content( m_xSMgr, m_pProvider, xId, !create_document );
1146 } catch ( ucb::ContentCreationException & )
1148 return uno::Reference< ucb::XContent >();
1152 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
1153 throw( uno::RuntimeException )
1155 if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
1157 static cppu::OTypeCollection aFolderCollection
1158 (CPPU_TYPE_REF( lang::XTypeProvider ),
1159 CPPU_TYPE_REF( lang::XServiceInfo ),
1160 CPPU_TYPE_REF( lang::XComponent ),
1161 CPPU_TYPE_REF( ucb::XContent ),
1162 CPPU_TYPE_REF( ucb::XCommandProcessor ),
1163 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
1164 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
1165 CPPU_TYPE_REF( beans::XPropertyContainer ),
1166 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
1167 CPPU_TYPE_REF( container::XChild ),
1168 CPPU_TYPE_REF( ucb::XContentCreator ) );
1169 return aFolderCollection.getTypes();
1171 else
1173 static cppu::OTypeCollection aFileCollection
1174 (CPPU_TYPE_REF( lang::XTypeProvider ),
1175 CPPU_TYPE_REF( lang::XServiceInfo ),
1176 CPPU_TYPE_REF( lang::XComponent ),
1177 CPPU_TYPE_REF( ucb::XContent ),
1178 CPPU_TYPE_REF( ucb::XCommandProcessor ),
1179 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
1180 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
1181 CPPU_TYPE_REF( beans::XPropertyContainer ),
1182 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
1183 CPPU_TYPE_REF( container::XChild ) );
1185 return aFileCollection.getTypes();
1189 uno::Sequence< beans::Property > Content::getProperties(
1190 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
1192 static const beans::Property aGenericProperties[] =
1194 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
1195 -1, getCppuBooleanType(),
1196 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1197 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
1198 -1, getCppuBooleanType(),
1199 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1200 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
1201 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1202 beans::PropertyAttribute::BOUND ),
1203 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
1204 -1, getCppuBooleanType(),
1205 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1206 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
1207 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1208 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1209 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
1210 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1211 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1212 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
1213 -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
1214 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1215 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
1216 -1, getCppuBooleanType(),
1217 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1218 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisc" ) ),
1219 -1, getCppuBooleanType(),
1220 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1221 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemoveable" ) ),
1222 -1, getCppuBooleanType(),
1223 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1224 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
1225 -1, getCppuBooleanType(),
1226 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
1229 const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
1230 return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
1233 uno::Sequence< ucb::CommandInfo > Content::getCommands( const uno::Reference< ucb::XCommandEnvironment > & xEnv)
1235 static ucb::CommandInfo aDocumentCommandInfoTable[] =
1237 // Required commands
1238 ucb::CommandInfo
1239 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
1240 -1, getCppuVoidType() ),
1241 ucb::CommandInfo
1242 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
1243 -1, getCppuVoidType() ),
1244 ucb::CommandInfo
1245 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
1246 -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
1247 ucb::CommandInfo
1248 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
1249 -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
1251 // Optional standard commands
1252 ucb::CommandInfo
1253 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
1254 -1, getCppuBooleanType() ),
1255 ucb::CommandInfo
1256 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
1257 -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
1258 ucb::CommandInfo
1259 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
1260 -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
1262 // Folder Only, omitted if not a folder
1263 ucb::CommandInfo
1264 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
1265 -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) )
1268 const int nProps = sizeof (aDocumentCommandInfoTable) / sizeof (aDocumentCommandInfoTable[0]);
1269 return uno::Sequence< ucb::CommandInfo >(aDocumentCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 1);
1272 XTYPEPROVIDER_COMMON_IMPL( Content );
1274 void SAL_CALL Content::acquire() throw()
1276 ContentImplHelper::acquire();
1279 void SAL_CALL Content::release() throw()
1281 ContentImplHelper::release();
1284 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
1286 uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
1287 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
1290 rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException )
1292 return rtl::OUString::createFromAscii("com.sun.star.comp.GIOContent" );
1295 uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
1296 throw( uno::RuntimeException )
1298 uno::Sequence< rtl::OUString > aSNS( 1 );
1299 aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii("com.sun.star.ucb.GIOContent" );
1300 return aSNS;