fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucb / source / ucp / gio / gio_content.cxx
blob6a432f802ee5a27afd88e2822d5f8457fd19520e
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/lang/WrappedTargetRuntimeException.hpp>
37 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
38 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
39 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
40 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
41 #include <com/sun/star/ucb/InteractiveNetworkWriteException.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/NameClash.hpp>
47 #include <com/sun/star/ucb/NameClashException.hpp>
48 #include <com/sun/star/ucb/OpenMode.hpp>
49 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
50 #include <com/sun/star/ucb/XCommandInfo.hpp>
51 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
52 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
53 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
54 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
55 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
56 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
57 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
58 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
59 #include <com/sun/star/ucb/XContentCreator.hpp>
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/seekableinput.hxx>
63 #include <cppuhelper/exc_hlp.hxx>
64 #include <ucbhelper/contentidentifier.hxx>
65 #include <ucbhelper/propertyvalueset.hxx>
66 #include <ucbhelper/interactionrequest.hxx>
67 #include <ucbhelper/cancelcommandexecution.hxx>
68 #include <vcl/svapp.hxx>
70 #include <osl/conditn.hxx>
72 #include "gio_content.hxx"
73 #include "gio_provider.hxx"
74 #include "gio_resultset.hxx"
75 #include "gio_inputstream.hxx"
76 #include "gio_outputstream.hxx"
77 #include "gio_mount.hxx"
79 #include <stdio.h>
81 using namespace com::sun::star;
83 namespace gio
86 Content::Content(
87 const uno::Reference< uno::XComponentContext >& rxContext,
88 ContentProvider* pProvider,
89 const uno::Reference< ucb::XContentIdentifier >& Identifier)
90 throw ( ucb::ContentCreationException )
91 : ContentImplHelper( rxContext, pProvider, Identifier ),
92 m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(false)
94 SAL_INFO("ucb.ucp.gio", "New Content ('" << m_xIdentifier->getContentIdentifier() << "')\n");
97 Content::Content(
98 const uno::Reference< uno::XComponentContext >& rxContext,
99 ContentProvider* pProvider,
100 const uno::Reference< ucb::XContentIdentifier >& Identifier,
101 bool bIsFolder)
102 throw ( ucb::ContentCreationException )
103 : ContentImplHelper( rxContext, pProvider, Identifier ),
104 m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(true)
106 SAL_INFO("ucb.ucp.gio", "Create Content ('" << m_xIdentifier->getContentIdentifier() << "')\n");
107 mpInfo = g_file_info_new();
108 g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
111 Content::~Content()
113 if (mpInfo) g_object_unref(mpInfo);
114 if (mpFile) g_object_unref(mpFile);
117 OUString Content::getParentURL()
119 OUString sURL;
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);
125 g_free(pPath);
127 return sURL;
130 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
131 throw( uno::RuntimeException, std::exception )
133 //TODO
134 //stick a map from each CommandId to a new GCancellable and propagate
135 //it throughout the g_file_* calls
138 OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException, std::exception )
140 return isFolder(uno::Reference< ucb::XCommandEnvironment >())
141 ? OUString( GIO_FOLDER_TYPE )
142 : OUString( GIO_FILE_TYPE );
145 #define EXCEPT(aExcept) \
146 do { \
147 if (bThrow) throw aExcept;\
148 aRet = uno::makeAny( aExcept );\
149 } while(false)
151 uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
153 uno::Any aRet;
155 gint eCode = pError->code;
156 OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
157 g_error_free(pError);
159 OUString sName;
160 OUString sHost;
162 uno::Sequence< uno::Any > aArgs( 1 );
163 aArgs[ 0 ] <<= sName;
165 switch (eCode)
167 case G_IO_ERROR_FAILED:
168 { io::IOException aExcept(sMessage, rContext);
169 EXCEPT(aExcept); }
170 break;
171 case G_IO_ERROR_NOT_MOUNTED:
172 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
173 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
174 EXCEPT(aExcept); }
175 break;
176 case G_IO_ERROR_NOT_FOUND:
177 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
178 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
179 EXCEPT(aExcept); }
180 break;
181 case G_IO_ERROR_EXISTS:
182 { ucb::NameClashException aExcept(sMessage, rContext,
183 task::InteractionClassification_ERROR, sName);
184 EXCEPT(aExcept); }
185 break;
186 case G_IO_ERROR_INVALID_ARGUMENT:
187 { lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
188 EXCEPT(aExcept); }
189 break;
190 case G_IO_ERROR_PERMISSION_DENIED:
191 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
192 task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
193 EXCEPT(aExcept); }
194 break;
195 case G_IO_ERROR_IS_DIRECTORY:
196 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
197 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
198 EXCEPT(aExcept); }
199 break;
200 case G_IO_ERROR_NOT_REGULAR_FILE:
201 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
202 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
203 EXCEPT(aExcept); }
204 break;
205 case G_IO_ERROR_NOT_DIRECTORY:
206 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
207 task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
208 EXCEPT(aExcept); }
209 break;
210 case G_IO_ERROR_FILENAME_TOO_LONG:
211 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
212 task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
213 EXCEPT(aExcept); }
214 break;
215 case G_IO_ERROR_PENDING:
216 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
217 task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
218 EXCEPT(aExcept); }
219 break;
220 case G_IO_ERROR_CLOSED:
221 case G_IO_ERROR_CANCELLED:
222 case G_IO_ERROR_TOO_MANY_LINKS:
223 case G_IO_ERROR_WRONG_ETAG:
224 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
225 task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
226 EXCEPT(aExcept); }
227 break;
228 case G_IO_ERROR_NOT_SUPPORTED:
229 case G_IO_ERROR_CANT_CREATE_BACKUP:
230 case G_IO_ERROR_WOULD_MERGE:
231 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
232 task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
233 EXCEPT(aExcept); }
234 break;
235 case G_IO_ERROR_NO_SPACE:
236 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
237 task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
238 EXCEPT(aExcept); }
239 break;
240 case G_IO_ERROR_INVALID_FILENAME:
241 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
242 task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
243 EXCEPT(aExcept); }
244 break;
245 case G_IO_ERROR_READ_ONLY:
246 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
247 task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
248 EXCEPT(aExcept); }
249 break;
250 case G_IO_ERROR_TIMED_OUT:
251 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
252 task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
253 EXCEPT(aExcept); }
254 break;
255 case G_IO_ERROR_WOULD_RECURSE:
256 { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
257 task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
258 EXCEPT(aExcept); }
259 break;
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);
264 EXCEPT(aExcept); }
265 break;
266 case G_IO_ERROR_HOST_NOT_FOUND:
267 { ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
268 task::InteractionClassification_ERROR, sHost);
269 EXCEPT(aExcept);}
270 break;
271 default:
272 case G_IO_ERROR_ALREADY_MOUNTED:
273 case G_IO_ERROR_NOT_EMPTY:
274 case G_IO_ERROR_NOT_SYMBOLIC_LINK:
275 case G_IO_ERROR_NOT_MOUNTABLE_FILE:
276 case G_IO_ERROR_FAILED_HANDLED:
277 { ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
278 task::InteractionClassification_ERROR);
279 EXCEPT(aExcept);}
280 break;
282 return aRet;
285 void convertToIOException(GError *pError, const uno::Reference< uno::XInterface >& rContext)
286 throw( io::IOException, uno::RuntimeException, std::exception )
290 convertToException(pError, rContext);
292 catch (const io::IOException&)
294 throw;
296 catch (const uno::RuntimeException&)
298 throw;
300 catch (const uno::Exception& e)
302 css::uno::Any a(cppu::getCaughtException());
303 throw css::lang::WrappedTargetRuntimeException(
304 "wrapped Exception " + e.Message,
305 css::uno::Reference<css::uno::XInterface>(), a);
309 uno::Any Content::mapGIOError( GError *pError )
311 if (!pError)
312 return getBadArgExcept();
314 return convertToException(pError, static_cast< cppu::OWeakObject * >(this), false);
317 uno::Any Content::getBadArgExcept()
319 return uno::makeAny( lang::IllegalArgumentException(
320 OUString("Wrong argument type!"),
321 static_cast< cppu::OWeakObject * >( this ), -1) );
324 class MountOperation
326 GMainLoop *mpLoop;
327 GMountOperation *mpAuthentication;
328 GError *mpError;
329 static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
330 public:
331 MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
332 ~MountOperation();
333 GError *Mount(GFile *pFile);
336 MountOperation::MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv) : mpError(NULL)
338 mpLoop = g_main_loop_new(NULL, FALSE);
339 mpAuthentication = ooo_mount_operation_new(xEnv);
342 void MountOperation::Completed(GObject *source, GAsyncResult *res, gpointer user_data)
344 MountOperation *pThis = static_cast<MountOperation*>(user_data);
345 g_file_mount_enclosing_volume_finish(G_FILE(source), res, &(pThis->mpError));
346 g_main_loop_quit(pThis->mpLoop);
349 GError *MountOperation::Mount(GFile *pFile)
351 g_file_mount_enclosing_volume(pFile, G_MOUNT_MOUNT_NONE, mpAuthentication, NULL, MountOperation::Completed, this);
353 //HACK: At least the gdk_threads_set_lock_functions(GdkThreadsEnter,
354 // GdkThreadsLeave) call in vcl/unx/gtk/app/gtkinst.cxx will lead to
355 // GdkThreadsLeave unlock the SolarMutex down to zero at the end of
356 // g_main_loop_run, so we need ~SolarMutexReleaser to raise it back to
357 // the original value again:
358 SolarMutexReleaser rel;
359 g_main_loop_run(mpLoop);
361 return mpError;
364 MountOperation::~MountOperation()
366 g_object_unref(mpAuthentication);
367 g_main_loop_unref(mpLoop);
370 GFileInfo* Content::getGFileInfo(const uno::Reference< ucb::XCommandEnvironment >& xEnv, GError **ppError)
372 GError * err = 0;
373 if (mpInfo == 0 && !mbTransient) {
374 for (bool retried = false;; retried = true) {
375 mpInfo = g_file_query_info(
376 getGFile(), "*", G_FILE_QUERY_INFO_NONE, 0, &err);
377 if (mpInfo != 0) {
378 break;
380 assert(err != 0);
381 if (err->code != G_IO_ERROR_NOT_MOUNTED || retried) {
382 break;
384 SAL_INFO(
385 "ucb.ucp.gio",
386 "G_IO_ERROR_NOT_MOUNTED \"" << err->message
387 << "\", trying to mount");
388 g_error_free(err);
389 err = MountOperation(xEnv).Mount(getGFile());
390 if (err != 0) {
391 break;
395 if (ppError != 0) {
396 *ppError = err;
397 } else if (err != 0) {
398 SAL_WARN(
399 "ucb.ucp.gio",
400 "ignoring GError \"" << err->message << "\" for <"
401 << m_xIdentifier->getContentIdentifier() << ">");
402 g_error_free(err);
404 return mpInfo;
407 GFile* Content::getGFile()
409 if (!mpFile)
410 mpFile = g_file_new_for_uri(OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
411 return mpFile;
414 bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv)
416 GFileInfo *pInfo = getGFileInfo(xEnv);
417 return pInfo && (g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY);
420 static util::DateTime getDateFromUnix (time_t t)
422 TimeValue tv;
423 tv.Nanosec = 0;
424 tv.Seconds = t;
425 oslDateTime dt;
427 if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
428 return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
429 dt.Day, dt.Month, dt.Year, false);
430 else
431 return util::DateTime();
434 uno::Reference< sdbc::XRow > Content::getPropertyValuesFromGFileInfo(GFileInfo *pInfo,
435 const uno::Reference< uno::XComponentContext >& rxContext,
436 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
437 const uno::Sequence< beans::Property >& rProperties)
439 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rxContext );
441 sal_Int32 nProps;
442 const beans::Property* pProps;
444 nProps = rProperties.getLength();
445 pProps = rProperties.getConstArray();
447 for( sal_Int32 n = 0; n < nProps; ++n )
449 const beans::Property& rProp = pProps[ n ];
451 if ( rProp.Name == "IsDocument" )
453 if (pInfo != 0 && g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE))
454 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_REGULAR ||
455 g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_UNKNOWN ) );
456 else
457 xRow->appendVoid( rProp );
459 else if ( rProp.Name == "IsFolder" )
461 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) )
462 xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_DIRECTORY ));
463 else
464 xRow->appendVoid( rProp );
466 else if ( rProp.Name == "Title" )
468 if (pInfo != 0 && g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
470 const char *pName = g_file_info_get_display_name(pInfo);
471 xRow->appendString( rProp, OUString(pName, strlen(pName), RTL_TEXTENCODING_UTF8) );
473 else
474 xRow->appendVoid(rProp);
476 else if ( rProp.Name == "IsReadOnly" )
478 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) )
479 xRow->appendBoolean( rProp, !g_file_info_get_attribute_boolean( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) );
480 else
481 xRow->appendVoid( rProp );
483 else if ( rProp.Name == "DateCreated" )
485 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CREATED ) )
486 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CREATED)) );
487 else
488 xRow->appendVoid( rProp );
490 else if ( rProp.Name == "DateModified" )
492 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED ) )
493 xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED)) );
494 else
495 xRow->appendVoid( rProp );
497 else if ( rProp.Name == "Size" )
499 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE) )
500 xRow->appendLong( rProp, ( g_file_info_get_size( pInfo ) ));
501 else
502 xRow->appendVoid( rProp );
504 else if ( rProp.Name == "IsVolume" )
506 //What do we use this for ?
507 xRow->appendBoolean( rProp, false );
509 else if ( rProp.Name == "IsCompactDisc" )
511 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT ) )
512 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT) );
513 else
514 xRow->appendVoid( rProp );
516 else if ( rProp.Name == "IsRemoveable" )
518 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) )
519 xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) );
520 else
521 xRow->appendVoid( rProp );
523 else if ( rProp.Name == "IsFloppy" )
525 xRow->appendBoolean( rProp, false );
527 else if ( rProp.Name == "IsHidden" )
529 if (pInfo != 0 && g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) )
530 xRow->appendBoolean( rProp, ( g_file_info_get_is_hidden ( pInfo ) ) );
531 else
532 xRow->appendVoid( rProp );
534 else if ( rProp.Name == "CreatableContentsInfo" )
536 xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
538 else
540 SAL_WARN(
541 "ucb.ucp.gio",
542 "Looking for unsupported property " << rProp.Name);
546 return uno::Reference< sdbc::XRow >( xRow.get() );
549 uno::Reference< sdbc::XRow > Content::getPropertyValues(
550 const uno::Sequence< beans::Property >& rProperties,
551 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
553 GFileInfo *pInfo = getGFileInfo(xEnv);
554 return getPropertyValuesFromGFileInfo(pInfo, m_xContext, xEnv, rProperties);
557 static lang::IllegalAccessException
558 getReadOnlyException( const uno::Reference< uno::XInterface >& rContext )
560 return lang::IllegalAccessException ("Property is read-only!", rContext );
563 void Content::queryChildren( ContentRefList& rChildren )
565 // Obtain a list with a snapshot of all currently instantiated contents
566 // from provider and extract the contents which are direct children
567 // of this content.
569 ucbhelper::ContentRefList aAllContents;
570 m_xProvider->queryExistingContents( aAllContents );
572 OUString aURL = m_xIdentifier->getContentIdentifier();
573 sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
575 if ( nURLPos != ( aURL.getLength() - 1 ) )
576 aURL += "/";
578 sal_Int32 nLen = aURL.getLength();
580 ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
581 ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
583 while ( it != end )
585 ucbhelper::ContentImplHelperRef xChild = (*it);
586 OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
588 // Is aURL a prefix of aChildURL?
589 if ( ( aChildURL.getLength() > nLen ) && aChildURL.startsWith( aURL ) )
591 sal_Int32 nPos = nLen;
592 nPos = aChildURL.indexOf( '/', nPos );
594 if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) )
596 // No further slashes / only a final slash. It's a child!
597 rChildren.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content * >(xChild.get() ) ) );
600 ++it;
604 bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
606 if ( !xNewId.is() )
607 return false;
609 uno::Reference< ucb::XContent > xThis = this;
611 if ( mbTransient )
613 m_xIdentifier = xNewId;
614 return false;
617 OUString aOldURL = m_xIdentifier->getContentIdentifier();
619 // Exchange own identitity.
620 if ( exchange( xNewId ) )
622 // Process instantiated children...
623 ContentRefList aChildren;
624 queryChildren( aChildren );
626 ContentRefList::const_iterator it = aChildren.begin();
627 ContentRefList::const_iterator end = aChildren.end();
629 while ( it != end )
631 ContentRef xChild = (*it);
633 // Create new content identifier for the child...
634 uno::Reference< ucb::XContentIdentifier > xOldChildId = xChild->getIdentifier();
635 OUString aOldChildURL = xOldChildId->getContentIdentifier();
636 OUString aNewChildURL = aOldChildURL.replaceAt(
637 0, aOldURL.getLength(), xNewId->getContentIdentifier() );
639 uno::Reference< ucb::XContentIdentifier > xNewChildId
640 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
642 if ( !xChild->exchangeIdentity( xNewChildId ) )
643 return false;
645 ++it;
647 return true;
650 return false;
653 uno::Sequence< uno::Any > Content::setPropertyValues(
654 const uno::Sequence< beans::PropertyValue >& rValues,
655 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
657 GError *pError=NULL;
658 GFileInfo *pNewInfo=NULL;
659 GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
660 if (pInfo)
661 pNewInfo = g_file_info_dup(pInfo);
662 else
664 if (!mbTransient)
665 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
666 else
668 if (pError)
669 g_error_free(pError);
670 pNewInfo = g_file_info_new();
674 sal_Int32 nCount = rValues.getLength();
676 beans::PropertyChangeEvent aEvent;
677 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
678 aEvent.Further = sal_False;
679 aEvent.PropertyHandle = -1;
681 sal_Int32 nChanged = 0, nTitlePos = -1;
682 const char *newName = NULL;
683 uno::Sequence< beans::PropertyChangeEvent > aChanges(nCount);
685 uno::Sequence< uno::Any > aRet( nCount );
686 const beans::PropertyValue* pValues = rValues.getConstArray();
687 for ( sal_Int32 n = 0; n < nCount; ++n )
689 const beans::PropertyValue& rValue = pValues[ n ];
690 #if OSL_DEBUG_LEVEL > 1
691 g_warning("Set prop '%s'", OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
692 #endif
693 if ( rValue.Name == "ContentType" ||
694 rValue.Name == "MediaType" ||
695 rValue.Name == "IsDocument" ||
696 rValue.Name == "IsFolder" ||
697 rValue.Name == "Size" ||
698 rValue.Name == "CreatableContentsInfo" )
700 aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
702 else if ( rValue.Name == "Title" )
704 OUString aNewTitle;
705 if (!( rValue.Value >>= aNewTitle ))
707 aRet[ n ] <<= beans::IllegalTypeException
708 ( OUString("Property value has wrong type!"),
709 static_cast< cppu::OWeakObject * >( this ) );
710 continue;
713 if ( aNewTitle.getLength() <= 0 )
715 aRet[ n ] <<= lang::IllegalArgumentException
716 ( OUString("Empty title not allowed!"),
717 static_cast< cppu::OWeakObject * >( this ), -1 );
718 continue;
722 OString sNewTitle = OUStringToOString(aNewTitle, RTL_TEXTENCODING_UTF8);
723 newName = sNewTitle.getStr();
724 const char *oldName = g_file_info_get_name( pInfo);
726 if (!newName || !oldName || strcmp(newName, oldName))
728 #if OSL_DEBUG_LEVEL > 1
729 g_warning ("Set new name to '%s'", newName);
730 #endif
732 aEvent.PropertyName = "Title";
733 if (oldName)
734 aEvent.OldValue = uno::makeAny(OUString(oldName, strlen(oldName), RTL_TEXTENCODING_UTF8));
735 aEvent.NewValue = uno::makeAny(aNewTitle);
736 aChanges.getArray()[ nChanged ] = aEvent;
737 nTitlePos = nChanged++;
739 g_file_info_set_name(pNewInfo, newName);
742 else
744 SAL_WARN("ucb.ucp.gio", "Unknown property " << rValue.Name << "\n");
745 aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
746 //TODO
750 if (nChanged)
752 bool bOk = true;
753 if (!mbTransient)
755 if ((bOk = doSetFileInfo(pNewInfo)))
757 for (sal_Int32 i = 0; i < nChanged; ++i)
758 aRet[ i ] <<= getBadArgExcept();
762 if (bOk)
764 if (nTitlePos > -1)
766 OUString aNewURL = getParentURL();
767 aNewURL += OUString( newName, strlen(newName), RTL_TEXTENCODING_UTF8 );
768 uno::Reference< ucb::XContentIdentifier > xNewId
769 = new ::ucbhelper::ContentIdentifier( aNewURL );
771 if (!exchangeIdentity( xNewId ) )
773 aRet[ nTitlePos ] <<= uno::Exception
774 ( OUString("Exchange failed!"),
775 static_cast< cppu::OWeakObject * >( this ) );
779 if (!mbTransient) //Discard and refetch
781 g_object_unref(mpInfo);
782 mpInfo = NULL;
785 if (mpInfo)
787 g_file_info_copy_into(pNewInfo, mpInfo);
788 g_object_unref(pNewInfo);
790 else
791 mpInfo = pNewInfo;
793 if (mpFile) //Discard and refetch
795 g_object_unref(mpFile);
796 mpFile = NULL;
800 aChanges.realloc( nChanged );
801 notifyPropertiesChange( aChanges );
804 return aRet;
807 bool Content::doSetFileInfo(GFileInfo *pNewInfo)
809 g_assert (!mbTransient);
811 bool bOk = true;
812 GFile *pFile = getGFile();
813 if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
814 bOk = false;
815 return bOk;
818 const int TRANSFER_BUFFER_SIZE = 65536;
820 void Content::copyData( uno::Reference< io::XInputStream > xIn,
821 uno::Reference< io::XOutputStream > xOut )
823 uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
825 g_return_if_fail( xIn.is() && xOut.is() );
827 while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
828 xOut->writeBytes( theData );
830 xOut->closeOutput();
833 bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
834 const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
836 if ( !xSink.is() )
837 return false;
839 uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
840 uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
842 if ( !xOut.is() && !xDataSink.is() )
843 return false;
845 GError *pError=NULL;
846 GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
847 if (!pStream)
848 convertToException(pError, static_cast< cppu::OWeakObject * >(this));
850 uno::Reference< io::XInputStream > xIn(
851 new comphelper::OSeekableInputWrapper(
852 new ::gio::InputStream(pStream), m_xContext));
854 if ( xOut.is() )
855 copyData( xIn, xOut );
857 if ( xDataSink.is() )
858 xDataSink->setInputStream( xIn );
860 return true;
863 uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
864 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
865 throw( uno::Exception )
867 bool bIsFolder = isFolder(xEnv);
869 if (!g_file_query_exists(getGFile(), NULL))
871 uno::Sequence< uno::Any > aArgs( 1 );
872 aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
873 uno::Any aErr = uno::makeAny(
874 ucb::InteractiveAugmentedIOException(OUString(), static_cast< cppu::OWeakObject * >( this ),
875 task::InteractionClassification_ERROR,
876 bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
879 ucbhelper::cancelCommandExecution(aErr, xEnv);
882 uno::Any aRet;
884 bool bOpenFolder = (
885 ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
886 ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
887 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
890 if ( bOpenFolder && bIsFolder )
892 uno::Reference< ucb::XDynamicResultSet > xSet
893 = new DynamicResultSet( m_xContext, this, rOpenCommand, xEnv );
894 aRet <<= xSet;
896 else if ( rOpenCommand.Sink.is() )
898 if (
899 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
900 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
903 ucbhelper::cancelCommandExecution(
904 uno::makeAny ( ucb::UnsupportedOpenModeException
905 ( OUString(), static_cast< cppu::OWeakObject * >( this ),
906 sal_Int16( rOpenCommand.Mode ) ) ),
907 xEnv );
910 if ( !feedSink( rOpenCommand.Sink, xEnv ) )
912 // Note: rOpenCommand.Sink may contain an XStream
913 // implementation. Support for this type of
914 // sink is optional...
915 #ifdef DEBUG
916 g_warning ("Failed to load data from '%s'",
917 OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
918 #endif
920 ucbhelper::cancelCommandExecution(
921 uno::makeAny (ucb::UnsupportedDataSinkException
922 ( OUString(), static_cast< cppu::OWeakObject * >( this ),
923 rOpenCommand.Sink ) ),
924 xEnv );
927 else
928 g_warning ("Open falling through ...");
929 return aRet;
932 uno::Any SAL_CALL Content::execute(
933 const ucb::Command& aCommand,
934 sal_Int32 /*CommandId*/,
935 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
936 throw( uno::Exception,
937 ucb::CommandAbortedException,
938 uno::RuntimeException, std::exception )
940 SAL_INFO("ucb.ucp.gio", "Content::execute " << aCommand.Name << "\n");
941 uno::Any aRet;
943 if ( aCommand.Name == "getPropertyValues" )
945 uno::Sequence< beans::Property > Properties;
946 if ( !( aCommand.Argument >>= Properties ) )
947 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
948 aRet <<= getPropertyValues( Properties, xEnv );
950 else if ( aCommand.Name == "getPropertySetInfo" )
951 aRet <<= getPropertySetInfo( xEnv, false );
952 else if ( aCommand.Name == "getCommandInfo" )
953 aRet <<= getCommandInfo( xEnv, false );
954 else if ( aCommand.Name == "open" )
956 ucb::OpenCommandArgument2 aOpenCommand;
957 if ( !( aCommand.Argument >>= aOpenCommand ) )
958 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
959 aRet = open( aOpenCommand, xEnv );
961 else if ( aCommand.Name == "transfer" )
963 ucb::TransferInfo transferArgs;
964 if ( !( aCommand.Argument >>= transferArgs ) )
965 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
966 transfer( transferArgs, xEnv );
968 else if ( aCommand.Name == "setPropertyValues" )
970 uno::Sequence< beans::PropertyValue > aProperties;
971 if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
972 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
973 aRet <<= setPropertyValues( aProperties, xEnv );
975 else if (aCommand.Name == "createNewContent"
976 && isFolder( xEnv ) )
978 ucb::ContentInfo arg;
979 if ( !( aCommand.Argument >>= arg ) )
980 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
981 aRet <<= createNewContent( arg );
983 else if ( aCommand.Name == "insert" )
985 ucb::InsertCommandArgument arg;
986 if ( !( aCommand.Argument >>= arg ) )
987 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
988 insert( arg.Data, arg.ReplaceExisting, xEnv );
990 else if ( aCommand.Name == "delete" )
992 bool bDeletePhysical = false;
993 aCommand.Argument >>= bDeletePhysical;
995 //If no delete physical, try and trashcan it, if that doesn't work go
996 //ahead and try and delete it anyway
997 if (!bDeletePhysical && !g_file_trash(getGFile(), NULL, NULL))
998 bDeletePhysical = true;
1000 if (bDeletePhysical)
1002 GError *pError = NULL;
1003 if (!g_file_delete( getGFile(), NULL, &pError))
1004 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1007 destroy( bDeletePhysical );
1009 else
1011 SAL_WARN("ucb.ucp.gio", "Unknown command " << aCommand.Name << "\n");
1013 ucbhelper::cancelCommandExecution
1014 ( uno::makeAny( ucb::UnsupportedCommandException
1015 ( OUString(),
1016 static_cast< cppu::OWeakObject * >( this ) ) ),
1017 xEnv );
1020 return aRet;
1023 void Content::destroy( bool bDeletePhysical )
1024 throw( uno::Exception )
1026 uno::Reference< ucb::XContent > xThis = this;
1028 deleted();
1030 ::gio::Content::ContentRefList aChildren;
1031 queryChildren( aChildren );
1033 ContentRefList::const_iterator it = aChildren.begin();
1034 ContentRefList::const_iterator end = aChildren.end();
1036 while ( it != end )
1038 (*it)->destroy( bDeletePhysical );
1039 ++it;
1043 void Content::insert(const uno::Reference< io::XInputStream > &xInputStream,
1044 bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment > &xEnv )
1045 throw( uno::Exception )
1047 GError *pError = NULL;
1048 GFileInfo *pInfo = getGFileInfo(xEnv);
1050 if ( pInfo &&
1051 g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
1052 g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY )
1054 #if OSL_DEBUG_LEVEL > 1
1055 g_warning ("Make directory");
1056 #endif
1057 if( !g_file_make_directory( getGFile(), NULL, &pError))
1058 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1059 return;
1062 if ( !xInputStream.is() )
1064 ucbhelper::cancelCommandExecution( uno::makeAny
1065 ( ucb::MissingInputStreamException
1066 ( OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
1067 xEnv );
1070 GFileOutputStream* pOutStream = NULL;
1071 if ( bReplaceExisting )
1073 if (!(pOutStream = g_file_replace(getGFile(), NULL, false, G_FILE_CREATE_PRIVATE, NULL, &pError)))
1074 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1076 else
1078 if (!(pOutStream = g_file_create (getGFile(), G_FILE_CREATE_PRIVATE, NULL, &pError)))
1079 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1082 uno::Reference < io::XOutputStream > xOutput = new ::gio::OutputStream(pOutStream);
1083 copyData( xInputStream, xOutput );
1085 if (mbTransient)
1087 mbTransient = false;
1088 inserted();
1092 const GFileCopyFlags DEFAULT_COPYDATA_FLAGS =
1093 static_cast<GFileCopyFlags>(G_FILE_COPY_OVERWRITE|G_FILE_COPY_TARGET_DEFAULT_PERMS);
1095 void Content::transfer( const ucb::TransferInfo& aTransferInfo, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1096 throw( uno::Exception )
1098 OUString sDest = m_xIdentifier->getContentIdentifier();
1099 if (!sDest.endsWith("/")) {
1100 sDest += "/";
1102 if (aTransferInfo.NewTitle.getLength())
1103 sDest += aTransferInfo.NewTitle;
1104 else
1105 sDest += OUString::createFromAscii(g_file_get_basename(getGFile()));
1107 GFile *pDest = g_file_new_for_uri(OUStringToOString(sDest, RTL_TEXTENCODING_UTF8).getStr());
1108 GFile *pSource = g_file_new_for_uri(OUStringToOString(aTransferInfo.SourceURL, RTL_TEXTENCODING_UTF8).getStr());
1110 gboolean bSuccess = false;
1111 GError *pError = NULL;
1112 if (aTransferInfo.MoveData)
1113 bSuccess = g_file_move(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
1114 else
1115 bSuccess = g_file_copy(pSource, pDest, DEFAULT_COPYDATA_FLAGS, NULL, NULL, 0, &pError);
1116 g_object_unref(pSource);
1117 g_object_unref(pDest);
1118 if (!bSuccess)
1119 ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
1122 uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
1123 const uno::Reference< ucb::XCommandEnvironment >& xEnv)
1124 throw( uno::RuntimeException )
1126 if ( isFolder( xEnv ) )
1128 uno::Sequence< ucb::ContentInfo > seq(2);
1130 // Minimum set of props we really need
1131 uno::Sequence< beans::Property > props( 1 );
1132 props[0] = beans::Property(
1133 OUString("Title"),
1135 cppu::UnoType<OUString>::get(),
1136 beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
1138 // file
1139 seq[0].Type = GIO_FILE_TYPE;
1140 seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
1141 ucb::ContentInfoAttribute::KIND_DOCUMENT );
1142 seq[0].Properties = props;
1144 // folder
1145 seq[1].Type = GIO_FOLDER_TYPE;
1146 seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
1147 seq[1].Properties = props;
1149 return seq;
1151 else
1153 return uno::Sequence< ucb::ContentInfo >();
1157 uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
1158 throw( uno::RuntimeException, std::exception )
1160 return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
1163 uno::Reference< ucb::XContent >
1164 SAL_CALL Content::createNewContent( const ucb::ContentInfo& Info )
1165 throw( uno::RuntimeException, std::exception )
1167 bool create_document;
1168 const char *name;
1170 if ( Info.Type == GIO_FILE_TYPE )
1171 create_document = true;
1172 else if ( Info.Type == GIO_FOLDER_TYPE )
1173 create_document = false;
1174 else
1176 #ifdef DEBUG
1177 g_warning( "Failed to create new content '%s'", OUStringToOString(Info.Type,
1178 RTL_TEXTENCODING_UTF8).getStr() );
1179 #endif
1180 return uno::Reference< ucb::XContent >();
1183 #if OSL_DEBUG_LEVEL > 1
1184 g_warning( "createNewContent (%d)", (int) create_document );
1185 #endif
1187 OUString aURL = m_xIdentifier->getContentIdentifier();
1189 if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
1190 aURL += "/";
1192 name = create_document ? "[New_Content]" : "[New_Collection]";
1193 aURL += OUString::createFromAscii( name );
1195 uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(aURL));
1199 return new ::gio::Content( m_xContext, m_pProvider, xId, !create_document );
1200 } catch ( ucb::ContentCreationException & )
1202 return uno::Reference< ucb::XContent >();
1206 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
1207 throw( uno::RuntimeException, std::exception )
1209 if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
1211 static cppu::OTypeCollection aFolderCollection
1212 (CPPU_TYPE_REF( lang::XTypeProvider ),
1213 CPPU_TYPE_REF( lang::XServiceInfo ),
1214 CPPU_TYPE_REF( lang::XComponent ),
1215 CPPU_TYPE_REF( ucb::XContent ),
1216 CPPU_TYPE_REF( ucb::XCommandProcessor ),
1217 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
1218 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
1219 CPPU_TYPE_REF( beans::XPropertyContainer ),
1220 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
1221 CPPU_TYPE_REF( container::XChild ),
1222 CPPU_TYPE_REF( ucb::XContentCreator ) );
1223 return aFolderCollection.getTypes();
1225 else
1227 static cppu::OTypeCollection aFileCollection
1228 (CPPU_TYPE_REF( lang::XTypeProvider ),
1229 CPPU_TYPE_REF( lang::XServiceInfo ),
1230 CPPU_TYPE_REF( lang::XComponent ),
1231 CPPU_TYPE_REF( ucb::XContent ),
1232 CPPU_TYPE_REF( ucb::XCommandProcessor ),
1233 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
1234 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
1235 CPPU_TYPE_REF( beans::XPropertyContainer ),
1236 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
1237 CPPU_TYPE_REF( container::XChild ) );
1239 return aFileCollection.getTypes();
1243 uno::Sequence< beans::Property > Content::getProperties(
1244 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
1246 static const beans::Property aGenericProperties[] =
1248 beans::Property( OUString( "IsDocument" ),
1249 -1, cppu::UnoType<bool>::get(),
1250 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1251 beans::Property( OUString( "IsFolder" ),
1252 -1, cppu::UnoType<bool>::get(),
1253 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1254 beans::Property( OUString( "Title" ),
1255 -1, cppu::UnoType<OUString>::get(),
1256 beans::PropertyAttribute::BOUND ),
1257 beans::Property( OUString( "IsReadOnly" ),
1258 -1, cppu::UnoType<bool>::get(),
1259 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1260 beans::Property( OUString( "DateCreated" ),
1261 -1, cppu::UnoType<util::DateTime>::get(),
1262 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1263 beans::Property( OUString( "DateModified" ),
1264 -1, cppu::UnoType<util::DateTime>::get(),
1265 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1266 beans::Property( OUString( "Size" ),
1267 -1, cppu::UnoType<sal_Int64>::get(),
1268 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1269 beans::Property( OUString( "IsVolume" ),
1270 1, cppu::UnoType<bool>::get(),
1271 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1272 beans::Property( OUString( "IsCompactDisc" ),
1273 -1, cppu::UnoType<bool>::get(),
1274 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1275 beans::Property( OUString( "IsRemoveable" ),
1276 -1, cppu::UnoType<bool>::get(),
1277 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1278 beans::Property( OUString( "IsHidden" ),
1279 -1, cppu::UnoType<bool>::get(),
1280 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1281 beans::Property( OUString( "CreatableContentsInfo" ),
1282 -1, cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
1283 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
1286 const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
1287 return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
1290 uno::Sequence< ucb::CommandInfo > Content::getCommands( const uno::Reference< ucb::XCommandEnvironment > & xEnv)
1292 static const ucb::CommandInfo aCommandInfoTable[] =
1294 // Required commands
1295 ucb::CommandInfo
1296 ( OUString( "getCommandInfo" ),
1297 -1, cppu::UnoType<void>::get() ),
1298 ucb::CommandInfo
1299 ( OUString( "getPropertySetInfo" ),
1300 -1, cppu::UnoType<void>::get() ),
1301 ucb::CommandInfo
1302 ( OUString( "getPropertyValues" ),
1303 -1, cppu::UnoType<uno::Sequence< beans::Property >>::get() ),
1304 ucb::CommandInfo
1305 ( OUString( "setPropertyValues" ),
1306 -1, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() ),
1308 // Optional standard commands
1309 ucb::CommandInfo
1310 ( OUString( "delete" ),
1311 -1, cppu::UnoType<bool>::get() ),
1312 ucb::CommandInfo
1313 ( OUString( "insert" ),
1314 -1, cppu::UnoType<ucb::InsertCommandArgument>::get() ),
1315 ucb::CommandInfo
1316 ( OUString( "open" ),
1317 -1, cppu::UnoType<ucb::OpenCommandArgument2>::get() ),
1319 // Folder Only, omitted if not a folder
1320 ucb::CommandInfo
1321 ( OUString( "transfer" ),
1322 -1, cppu::UnoType<ucb::TransferInfo>::get() ),
1323 ucb::CommandInfo
1324 ( OUString( "createNewContent" ),
1325 -1, cppu::UnoType<ucb::ContentInfo>::get() )
1328 const int nProps = sizeof (aCommandInfoTable) / sizeof (aCommandInfoTable[0]);
1329 return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 2);
1332 XTYPEPROVIDER_COMMON_IMPL( Content );
1334 void SAL_CALL Content::acquire() throw()
1336 ContentImplHelper::acquire();
1339 void SAL_CALL Content::release() throw()
1341 ContentImplHelper::release();
1344 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException, std::exception )
1346 uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
1347 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
1350 OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException, std::exception )
1352 return OUString("com.sun.star.comp.GIOContent");
1355 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
1356 throw( uno::RuntimeException, std::exception )
1358 uno::Sequence< OUString > aSNS( 1 );
1359 aSNS.getArray()[ 0 ] = "com.sun.star.ucb.GIOContent";
1360 return aSNS;
1365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */