1 --- ucb/source/ucp/gvfs/content.hxx 2003-04-28 15:17:17.000000000 +0100
2 +++ ucb/source/ucp/gvfs/content.hxx 2003-04-28 15:17:17.000000000 +0100
4 +#ifndef _GVFS_UCP_CONTENT_HXX
5 +#define _GVFS_UCP_CONTENT_HXX
10 +#ifndef _RTL_REF_HXX_
11 +#include <rtl/ref.hxx>
14 +#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
15 +#include <com/sun/star/ucb/ContentCreationException.hpp>
17 +#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
18 +#include <com/sun/star/ucb/XContentCreator.hpp>
21 +#ifndef _UCBHELPER_CONTENTHELPER_HXX
22 +#include <ucbhelper/contenthelper.hxx>
25 +#include <glib/gthread.h>
26 +#include <libgnomevfs/gnome-vfs-ops.h>
27 +#include <libgnomevfs/gnome-vfs-directory.h>
29 +namespace com { namespace sun { namespace star { namespace beans {
31 + struct PropertyValue;
34 +namespace com { namespace sun { namespace star { namespace io {
36 + class XOutputStream;
39 +namespace com { namespace sun { namespace star { namespace sdbc {
43 +namespace com { namespace sun { namespace star { namespace ucb {
44 + struct TransferInfo;
50 +class ContentProvider;
51 +class ContentProperties;
53 +// Random made up names - AFAICS
54 +#define GVFS_FILE_TYPE "application/vnd.sun.staroffice.gvfs-file"
55 +#define GVFS_FOLDER_TYPE "application/vnd.sun.staroffice.gvfs-folder"
60 + // Helper class to make exceptions pleasant
61 + Authentication( const com::sun::star::uno::Reference<
62 + com::sun::star::ucb::XCommandEnvironment > & xEnv );
66 +class Content : public ::ucb::ContentImplHelper,
67 + public com::sun::star::ucb::XContentCreator
69 +//=========================================================================
71 +//=========================================================================
73 + typedef rtl::Reference< Content > ContentRef;
74 + typedef std::list< ContentRef > ContentRefList;
77 + ContentProvider *m_pProvider; // No need for a ref, base class holds object
78 + sal_Bool m_bTransient; // A non-existant (as yet) item
79 + GnomeVFSFileInfo m_info; // cached status information
82 + void queryChildren ( ContentRefList& rChildren );
83 + ::com::sun::star::uno::Any getBadArgExcept ();
84 + GnomeVFSResult getInfo ( const ::com::sun::star::uno::Reference<
85 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
86 + sal_Bool isFolder ( const ::com::sun::star::uno::Reference<
87 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
88 + sal_Bool exchangeIdentity( const ::com::sun::star::uno::Reference<
89 + ::com::sun::star::ucb::XContentIdentifier >& xNewId);
90 + GnomeVFSResult doSetFileInfo ( const GnomeVFSFileInfo *newInfo,
91 + GnomeVFSSetFileInfoMask setMask,
92 + const ::com::sun::star::uno::Reference<
93 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
94 + ::rtl::OUString makeNewURL ( const char *newName );
95 + // End Internal helpers
98 + virtual ::rtl::OUString getParentURL();
100 + virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
101 + getProperties( const com::sun::star::uno::Reference<
102 + com::sun::star::ucb::XCommandEnvironment > & xEnv );
104 + virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
105 + getCommands( const com::sun::star::uno::Reference<
106 + com::sun::star::ucb::XCommandEnvironment > & xEnv );
109 + // Command "getPropertyValues"
110 + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
111 + getPropertyValues( const ::com::sun::star::uno::Sequence<
112 + ::com::sun::star::beans::Property >& rProperties,
113 + const ::com::sun::star::uno::Reference<
114 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
117 + // Command "setPropertyValues"
118 + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
119 + setPropertyValues( const ::com::sun::star::uno::Sequence<
120 + ::com::sun::star::beans::PropertyValue >& rValues,
121 + const ::com::sun::star::uno::Reference<
122 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
124 + // Command "insert"
125 + void insert( const ::com::sun::star::uno::Reference<
126 + ::com::sun::star::io::XInputStream > & xInputStream,
127 + sal_Bool bReplaceExisting,
128 + const com::sun::star::uno::Reference<
129 + com::sun::star::ucb::XCommandEnvironment >& xEnv )
130 + throw( ::com::sun::star::uno::Exception );
132 + // Command "transfer"
133 + void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
134 + const com::sun::star::uno::Reference<
135 + com::sun::star::ucb::XCommandEnvironment >& xEnv )
136 + throw( ::com::sun::star::uno::Exception );
138 + // Command "delete"
139 + void destroy( sal_Bool bDeletePhysical )
140 + throw( ::com::sun::star::uno::Exception );
143 + void copyData( ::com::sun::star::uno::Reference<
144 + ::com::sun::star::io::XInputStream > xIn,
145 + ::com::sun::star::uno::Reference<
146 + ::com::sun::star::io::XOutputStream > xOut );
148 + ::com::sun::star::uno::Reference<
149 + ::com::sun::star::io::XInputStream >
150 + createTempStream( const ::com::sun::star::uno::Reference<
151 + com::sun::star::ucb::XCommandEnvironment >& xEnv )
152 + throw( ::com::sun::star::uno::Exception );
153 + ::com::sun::star::uno::Reference<
154 + ::com::sun::star::io::XInputStream >
155 + createInputStream( const ::com::sun::star::uno::Reference<
156 + com::sun::star::ucb::XCommandEnvironment >& xEnv )
157 + throw( ::com::sun::star::uno::Exception );
158 + sal_Bool feedSink( ::com::sun::star::uno::Reference<
159 + ::com::sun::star::uno::XInterface> aSink,
160 + const ::com::sun::star::uno::Reference<
161 + com::sun::star::ucb::XCommandEnvironment >& xEnv );
163 + ::com::sun::star::uno::Any mapVFSException( const GnomeVFSResult result,
166 + void cancelCommandExecution(const GnomeVFSResult result,
167 + const ::com::sun::star::uno::Reference<
168 + com::sun::star::ucb::XCommandEnvironment > & xEnv,
169 + sal_Bool bWrite = sal_False )
170 + throw( ::com::sun::star::uno::Exception );
174 + // Non-interface bits
176 + rtl::OString getOURI ();
177 + rtl::OUString getOUURI ();
179 +//=========================================================================
181 +//=========================================================================
184 + Content( const ::com::sun::star::uno::Reference<
185 + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
186 + ContentProvider *pProvider,
187 + const ::com::sun::star::uno::Reference<
188 + ::com::sun::star::ucb::XContentIdentifier >& Identifier)
189 + throw ( ::com::sun::star::ucb::ContentCreationException );
190 + Content( const ::com::sun::star::uno::Reference<
191 + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
192 + ContentProvider *pProvider,
193 + const ::com::sun::star::uno::Reference<
194 + ::com::sun::star::ucb::XContentIdentifier >& Identifier,
196 + throw ( ::com::sun::star::ucb::ContentCreationException );
197 + virtual ~Content();
203 + XTYPEPROVIDER_DECL()
206 + virtual ::rtl::OUString SAL_CALL getImplementationName()
207 + throw( ::com::sun::star::uno::RuntimeException );
208 + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
209 + getSupportedServiceNames()
210 + throw( ::com::sun::star::uno::RuntimeException );
213 + virtual rtl::OUString SAL_CALL
215 + throw( com::sun::star::uno::RuntimeException );
217 + // XCommandProcessor
218 + virtual com::sun::star::uno::Any SAL_CALL
219 + execute( const com::sun::star::ucb::Command& aCommand,
220 + sal_Int32 CommandId,
221 + const com::sun::star::uno::Reference<
222 + com::sun::star::ucb::XCommandEnvironment >& xEnv )
223 + throw( com::sun::star::uno::Exception,
224 + com::sun::star::ucb::CommandAbortedException,
225 + com::sun::star::uno::RuntimeException );
226 + virtual void SAL_CALL
227 + abort( sal_Int32 CommandId )
228 + throw( com::sun::star::uno::RuntimeException );
230 + //////////////////////////////////////////////////////////////////////
231 + // Additional interfaces
232 + //////////////////////////////////////////////////////////////////////
235 + virtual com::sun::star::uno::Sequence<
236 + com::sun::star::ucb::ContentInfo > SAL_CALL
237 + queryCreatableContentsInfo()
238 + throw( com::sun::star::uno::RuntimeException );
239 + virtual com::sun::star::uno::Reference<
240 + com::sun::star::ucb::XContent > SAL_CALL
241 + createNewContent( const com::sun::star::ucb::ContentInfo& Info )
242 + throw( com::sun::star::uno::RuntimeException );
248 + extern GPrivate *auth_queue;
249 + extern void auth_queue_destroy( gpointer data );
253 --- ucb/source/ucp/gvfs/content.cxx 2003-05-01 10:12:14.000000000 +0100
254 +++ ucb/source/ucp/gvfs/content.cxx 2003-05-01 10:12:14.000000000 +0100
258 +#include <sys/types.h>
259 +#include <tools/datetime.hxx>
260 +#ifndef _OSL_DIAGNOSE_H_
261 +#include <osl/diagnose.h>
263 +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
264 +#include <com/sun/star/beans/PropertyValue.hpp>
266 +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
267 +#include <com/sun/star/beans/PropertyAttribute.hpp>
269 +#ifndef _COM_SUN_STAR_BEANS_PROPERTYSETINFOCHANGE_HPP_
270 +#include <com/sun/star/beans/PropertySetInfoChange.hpp>
272 +#ifndef _COM_SUN_STAR_BEANS_PROPERTYSETINFOCHANGEEVENT_HPP_
273 +#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
275 +#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
276 +#include <com/sun/star/io/XActiveDataSink.hpp>
278 +#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
279 +#include <com/sun/star/io/XOutputStream.hpp>
281 +#ifndef _COM_SUN_STAR_LANG_ILLEGALACCESSEXCEPTION_HPP_
282 +#include <com/sun/star/lang/IllegalAccessException.hpp>
284 +#ifndef _COM_SUN_STAR_UCB_CONTENTINFOATTRIBUTE_HPP_
285 +#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
287 +#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
288 +#include <com/sun/star/ucb/InsertCommandArgument.hpp>
290 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
291 +#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
293 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEAUGMENTEDIOEXCEPTION_HPP_
294 +#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
296 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKCONNECTEXCEPTION_HPP_
297 +#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
299 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_
300 +#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
302 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKREADEXCEPTION_HPP_
303 +#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
305 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKRESOLVENAMEEXCEPTION_HPP_
306 +#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
308 +#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKWRITEEXCEPTION_HPP_
309 +#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
311 +#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
312 +#include <com/sun/star/ucb/NameClash.hpp>
314 +#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
315 +#include <com/sun/star/ucb/NameClashException.hpp>
317 +#ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_
318 +#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
320 +#ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
321 +#include <com/sun/star/ucb/OpenMode.hpp>
323 +#ifndef _COM_SUN_STAR_UCB_POSTCOMMANDARGUMENT2_HPP_
324 +#include <com/sun/star/ucb/PostCommandArgument2.hpp>
326 +#ifndef _COM_SUN_STAR_UCB_TRANSFERINFO_HPP_
327 +#include <com/sun/star/ucb/TransferInfo.hpp>
329 +#ifndef _COM_SUN_STAR_UCB_XCOMMANDINFO_HPP_
330 +#include <com/sun/star/ucb/XCommandInfo.hpp>
332 +#ifndef _COM_SUN_STAR_UCB_XPERSISTENTPROPERTYSET_HPP_
333 +#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
335 +#ifndef _COM_SUN_STAR_UCB_MISSINGINPUTSTREAMEXCEPTION_HPP_
336 +#include <com/sun/star/ucb/MissingInputStreamException.hpp>
338 +#ifndef _COM_SUN_STAR_UCB_MISSINGPROPERTIESEXCEPTION_HPP_
339 +#include <com/sun/star/ucb/MissingPropertiesException.hpp>
341 +#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDCOMMANDEXCEPTION_HPP_
342 +#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
344 +#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDDATASINKEXCEPTION_HPP_
345 +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
347 +#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDNAMECLASHEXCEPTION_HPP_
348 +#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
350 +#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_
351 +#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
353 +#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_
354 +#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
356 +#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
357 +#include <com/sun/star/ucb/NameClashException.hpp>
360 +#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
361 +#include <ucbhelper/contentidentifier.hxx>
363 +#ifndef _UCBHELPER_PROPERTYVALUESET_HXX
364 +#include <ucbhelper/propertyvalueset.hxx>
366 +#ifndef _UCBHELPER_INTERACTIONREQUEST_HXX
367 +#include <ucbhelper/interactionrequest.hxx>
369 +#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
370 +#include <ucbhelper/cancelcommandexecution.hxx>
372 +#ifndef _UCBHELPER_SIMPLEAUTHENTICATIONREQUEST_HXX
373 +#include <ucbhelper/simpleauthenticationrequest.hxx>
376 +const int TRANSFER_BUFFER_SIZE = 65536;
379 + * NB. Name escaping is done only for URIs
380 + * the 'Title' property is unescaped on set/get
382 +#include <libgnomevfs/gnome-vfs-utils.h>
383 +#include <libgnomevfs/gnome-vfs-result.h>
384 +#include <libgnomevfs/gnome-vfs-standard-callbacks.h>
385 +extern "C" { // missing in the header: doh.
386 +# include <libgnomevfs/gnome-vfs-module-callback.h>
389 +#include "content.hxx"
390 +#include "provider.hxx"
391 +#include "directory.hxx"
392 +#include "stream.hxx"
394 +using namespace gvfs;
395 +using namespace com::sun;
396 +using namespace com::sun::star;
398 +#define CLEAR_INFO(info) memset((info), 0, sizeof ((info)[0]))
402 +OUStringToGnome( const rtl::OUString &str )
404 + rtl::OString aTempStr = rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 );
405 + return g_strdup( (const sal_Char *) aTempStr );
408 +static rtl::OUString
409 +GnomeToOUString( const char *utf8_str)
412 + return rtl::OUString();
414 + return rtl::OUString( utf8_str, strlen( utf8_str ), RTL_TEXTENCODING_UTF8 );
419 + const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
420 + ContentProvider* pProvider,
421 + const uno::Reference< star::ucb::XContentIdentifier >& Identifier)
422 + throw ( star::ucb::ContentCreationException )
423 + : ContentImplHelper( rxSMgr, pProvider, Identifier ),
424 + m_pProvider( pProvider ),
425 + m_bTransient( sal_False )
427 + CLEAR_INFO (&m_info);
429 + g_warning ("New Content ('%s')", getURI());
433 +Content::Content( const ::com::sun::star::uno::Reference<
434 + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
435 + ContentProvider *pProvider,
436 + const ::com::sun::star::uno::Reference<
437 + ::com::sun::star::ucb::XContentIdentifier >& Identifier,
439 + throw ( ::com::sun::star::ucb::ContentCreationException )
440 + : ContentImplHelper( rxSMgr, pProvider, Identifier ),
441 + m_pProvider( pProvider ),
442 + m_bTransient( sal_True )
444 + CLEAR_INFO (&m_info);
447 + g_warning ("New Transient content ('%s') (%d)", getURI(), isFolder);
449 +// m_info.name = FIXME: set name ?
450 + m_info.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE;
451 + m_info.type = isFolder ? GNOME_VFS_FILE_TYPE_DIRECTORY :
452 + GNOME_VFS_FILE_TYPE_REGULAR;
458 + gnome_vfs_file_info_clear( &m_info );
462 +// XInterface methods.
465 +void SAL_CALL Content::acquire()
468 + ContentImplHelper::acquire();
470 +void SAL_CALL Content::release()
473 + ContentImplHelper::release();
475 +uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
476 + throw ( uno::RuntimeException )
478 + // Note: isFolder may require network activities! So call it only
479 + // if it is really necessary!!!
480 + uno::Any aRet = cppu::queryInterface( rType,
481 + static_cast< star::ucb::XContentCreator * >( this ) );
482 + if ( aRet.hasValue() )
483 + return isFolder( uno::Reference< star::ucb::XCommandEnvironment >() )
484 + ? aRet : uno::Any();
486 + return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
490 +// XTypeProvider methods.
493 +XTYPEPROVIDER_COMMON_IMPL( Content );
495 +uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
496 + throw( uno::RuntimeException )
498 + static cppu::OTypeCollection *pFolderCollection = NULL;
499 + static cppu::OTypeCollection *pFileCollection = NULL;
501 + if (!pFolderCollection) {
502 + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
504 + if (!pFolderCollection) {
505 + static cppu::OTypeCollection aFolderCollection
506 + (CPPU_TYPE_REF( lang::XTypeProvider ),
507 + CPPU_TYPE_REF( lang::XServiceInfo ),
508 + CPPU_TYPE_REF( lang::XComponent ),
509 + CPPU_TYPE_REF( star::ucb::XContent ),
510 + CPPU_TYPE_REF( star::ucb::XCommandProcessor ),
511 + CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
512 + CPPU_TYPE_REF( star::ucb::XCommandInfoChangeNotifier ),
513 + CPPU_TYPE_REF( beans::XPropertyContainer ),
514 + CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
515 + CPPU_TYPE_REF( container::XChild ),
516 + CPPU_TYPE_REF( star::ucb::XContentCreator ) ); // !!
517 + static cppu::OTypeCollection aFileCollection
518 + (CPPU_TYPE_REF( lang::XTypeProvider ),
519 + CPPU_TYPE_REF( lang::XServiceInfo ),
520 + CPPU_TYPE_REF( lang::XComponent ),
521 + CPPU_TYPE_REF( star::ucb::XContent ),
522 + CPPU_TYPE_REF( star::ucb::XCommandProcessor ),
523 + CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
524 + CPPU_TYPE_REF( star::ucb::XCommandInfoChangeNotifier ),
525 + CPPU_TYPE_REF( beans::XPropertyContainer ),
526 + CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
527 + CPPU_TYPE_REF( container::XChild ) );
529 + pFolderCollection = &aFolderCollection;
530 + pFileCollection = &aFileCollection;
531 + // FIXME: need write barrier from HEAD.
535 + if ( isFolder( uno::Reference< star::ucb::XCommandEnvironment >() ) )
536 + return pFolderCollection->getTypes();
538 + return pFileCollection->getTypes();
542 +// XServiceInfo methods.
545 +rtl::OUString SAL_CALL Content::getImplementationName()
546 + throw( uno::RuntimeException )
548 + return rtl::OUString::createFromAscii("com.sun.star.comp.GnomeVFSContent" );
551 +uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
552 + throw( uno::RuntimeException )
554 + uno::Sequence< rtl::OUString > aSNS( 1 );
555 + aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
556 + "com.sun.star.ucb.GnomeVFSContent" );
561 +// XContent methods.
564 +rtl::OUString SAL_CALL Content::getContentType()
565 + throw( uno::RuntimeException )
567 + if ( isFolder( uno::Reference< star::ucb::XCommandEnvironment >() ) )
568 + return rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
570 + return rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
574 +// XCommandProcessor methods.
577 +uno::Any Content::getBadArgExcept()
579 + return uno::makeAny( lang::IllegalArgumentException
580 + ( rtl::OUString::createFromAscii( "Wrong argument type!" ),
581 + static_cast< cppu::OWeakObject * >( this ),
585 +uno::Any SAL_CALL Content::execute(
586 + const star::ucb::Command& aCommand,
587 + sal_Int32 CommandId,
588 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
589 + throw( uno::Exception,
590 + star::ucb::CommandAbortedException,
591 + uno::RuntimeException )
597 + uno::Reference< task::XInteractionHandler > xIH;
600 + xIH = xEnv->getInteractionHandler();
601 + g_warning( "Execute command: '%s' with %s interaction env",
602 + OUStringToGnome( aCommand.Name ),
603 + xIH.is() ? "" : "NO" );
607 +#define COMMAND_IS(cmd,name) ( (cmd).Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( name ) ) )
609 + if ( COMMAND_IS( aCommand, "getPropertyValues" ) ) {
610 + uno::Sequence< beans::Property > Properties;
612 + if ( !( aCommand.Argument >>= Properties ) )
613 + ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
615 + aRet <<= getPropertyValues( Properties, xEnv );
617 + } else if ( COMMAND_IS( aCommand, "setPropertyValues" ) ) {
618 + uno::Sequence< beans::PropertyValue > aProperties;
620 + if ( !( aCommand.Argument >>= aProperties ) ||
621 + !aProperties.getLength() )
622 + ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
624 + aRet <<= setPropertyValues( aProperties, xEnv );
626 + } else if ( COMMAND_IS( aCommand, "getPropertySetInfo" ) ) {
627 + aRet <<= getPropertySetInfo( xEnv, sal_False );
629 + } else if ( COMMAND_IS( aCommand, "getCommandInfo" ) ) {
630 + aRet <<= getCommandInfo( xEnv, sal_False );
632 + } else if ( COMMAND_IS( aCommand, "open" ) ) {
634 + star::ucb::OpenCommandArgument2 aOpenCommand;
635 + if ( !( aCommand.Argument >>= aOpenCommand ) )
636 + ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
638 + sal_Bool bOpenFolder =
639 + ( ( aOpenCommand.Mode == star::ucb::OpenMode::ALL ) ||
640 + ( aOpenCommand.Mode == star::ucb::OpenMode::FOLDERS ) ||
641 + ( aOpenCommand.Mode == star::ucb::OpenMode::DOCUMENTS ) );
643 + if ( bOpenFolder && isFolder( xEnv ) ) {
644 + uno::Reference< star::ucb::XDynamicResultSet > xSet
645 + = new DynamicResultSet(m_xSMgr, this, aOpenCommand, xEnv );
648 + } else if ( aOpenCommand.Sink.is() ) {
650 + if ( ( aOpenCommand.Mode
651 + == star::ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
652 + ( aOpenCommand.Mode
653 + == star::ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) {
654 + ucbhelper::cancelCommandExecution
655 + ( uno::makeAny ( star::ucb::UnsupportedOpenModeException
657 + static_cast< cppu::OWeakObject * >( this ),
658 + sal_Int16( aOpenCommand.Mode ) ) ),
661 + if ( !feedSink( aOpenCommand.Sink, xEnv ) ) {
662 + // Note: aOpenCommand.Sink may contain an XStream
663 + // implementation. Support for this type of
664 + // sink is optional...
666 + g_warning ("Failed to load data from '%s'", getURI());
668 + ucbhelper::cancelCommandExecution
669 + ( uno::makeAny (star::ucb::UnsupportedDataSinkException
671 + static_cast< cppu::OWeakObject * >( this ),
672 + aOpenCommand.Sink ) ),
678 + g_warning ("Open falling through ...");
681 + } else if ( COMMAND_IS( aCommand, "insert" ) ) {
682 + star::ucb::InsertCommandArgument arg;
683 + if ( !( aCommand.Argument >>= arg ) )
684 + ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
686 + insert( arg.Data, arg.ReplaceExisting, xEnv );
688 + } else if ( COMMAND_IS( aCommand, "delete" ) ) {
690 + sal_Bool bDeletePhysical = sal_False;
691 + aCommand.Argument >>= bDeletePhysical;
693 + ::rtl::OString aURI = getOURI();
694 + GnomeVFSResult result = gnome_vfs_unlink ((const sal_Char *) aURI);
696 + if (result != GNOME_VFS_OK)
697 + cancelCommandExecution( result, xEnv, sal_True );
699 + destroy( bDeletePhysical );
701 + } else if ( COMMAND_IS( aCommand, "transfer" ) && isFolder( xEnv ) ) {
702 + star::ucb::TransferInfo transferArgs;
704 + if ( !( aCommand.Argument >>= transferArgs ) )
705 + ucbhelper::cancelCommandExecution( getBadArgExcept(), xEnv );
707 + transfer( transferArgs, xEnv );
709 + } else { // Unsuported
711 + g_warning( "Unsupported command: '%s'",
712 + OUStringToGnome( aCommand.Name ) );
714 + ucbhelper::cancelCommandExecution
715 + ( uno::makeAny( star::ucb::UnsupportedCommandException
717 + static_cast< cppu::OWeakObject * >( this ) ) ),
725 +void SAL_CALL Content::abort( sal_Int32 CommandId )
726 + throw( uno::RuntimeException )
728 + // FIXME: we should use the GnomeVFSCancellation APIs here ...
732 +// XContentCreator methods.
735 +uno::Sequence< star::ucb::ContentInfo > SAL_CALL
736 +Content::queryCreatableContentsInfo()
737 + throw( uno::RuntimeException )
739 + uno::Sequence< star::ucb::ContentInfo > seq(2);
741 + // Minimum set of props we really need
742 + uno::Sequence< beans::Property > props( 1 );
743 + props[0] = beans::Property(
744 + rtl::OUString::createFromAscii( "Title" ),
746 + getCppuType( static_cast< rtl::OUString* >( 0 ) ),
747 + beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
750 + seq[0].Type = rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
751 + seq[0].Attributes = ( star::ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
752 + star::ucb::ContentInfoAttribute::KIND_DOCUMENT );
753 + seq[0].Properties = props;
756 + seq[1].Type = rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
757 + seq[1].Attributes = star::ucb::ContentInfoAttribute::KIND_FOLDER;
758 + seq[1].Properties = props;
763 +uno::Reference< star::ucb::XContent > SAL_CALL
764 +Content::createNewContent( const star::ucb::ContentInfo& Info )
765 + throw( uno::RuntimeException )
767 + bool create_document;
770 + if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FILE_TYPE ) ) )
771 + create_document = true;
772 + else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FOLDER_TYPE ) ) )
773 + create_document = false;
776 + g_warning( "Failed to create new content '%s'",
777 + OUStringToGnome( Info.Type ) );
779 + return uno::Reference< star::ucb::XContent >();
783 + g_warning( "createNewContent (%d)", (int) create_document );
786 + rtl::OUString aURL = getOUURI();
788 + if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
789 + aURL += rtl::OUString::createFromAscii( "/" );
791 + name = create_document ? "[New_Content]" : "[New_Collection]";
792 + // This looks problematic to me cf. webdav
793 + aURL += rtl::OUString::createFromAscii( name );
795 + uno::Reference< star::ucb::XContentIdentifier > xId
796 + ( new ::ucb::ContentIdentifier( m_xSMgr, aURL ) );
799 + return new ::gvfs::Content( m_xSMgr, m_pProvider, xId, !create_document );
800 + } catch ( star::ucb::ContentCreationException & ) {
801 + return uno::Reference< star::ucb::XContent >();
805 +rtl::OUString Content::getParentURL()
807 + rtl::OUString aParentURL;
808 + // <scheme>:// -> ""
809 + // <scheme>://foo -> ""
810 + // <scheme>://foo/ -> ""
811 + // <scheme>://foo/bar -> <scheme>://foo/
812 + // <scheme>://foo/bar/ -> <scheme>://foo/
813 + // <scheme>://foo/bar/abc -> <scheme>://foo/bar/
815 + rtl::OUString aURL = getOUURI();
817 + sal_Int32 nPos = aURL.lastIndexOf( '/' );
818 + if ( nPos == ( aURL.getLength() - 1 ) ) {
819 + // Trailing slash found. Skip.
820 + nPos = aURL.lastIndexOf( '/', nPos );
823 + sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
825 + nPos1 = aURL.lastIndexOf( '/', nPos1 );
828 + aParentURL = rtl::OUString( aURL.copy( 0, nPos + 1 ) );
831 + g_warning ("getParentURL '%s' -> '%s'",
832 + getURI(), (const sal_Char *) rtl::OUStringToOString
833 + ( aParentURL, RTL_TEXTENCODING_UTF8 ) );
839 +static util::DateTime
840 +getDateFromUnix (time_t t)
842 + static const Date epochStart( 1,1,1970 );
845 + tmp.MakeDateTimeFromSec( epochStart, ((long unsigned int) t) );
847 + return util::DateTime( 0, tmp.GetSec(), tmp.GetMin(), tmp.GetHour(),
848 + tmp.GetDay(), tmp.GetMonth (), tmp.GetYear ());
851 +uno::Reference< sdbc::XRow > Content::getPropertyValues(
852 + const uno::Sequence< beans::Property >& rProperties,
853 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
856 + GnomeVFSResult result;
857 + uno::Sequence< beans::Property > allProperties;
859 + if( ( result = getInfo( xEnv ) ) != GNOME_VFS_OK )
860 + cancelCommandExecution( result, xEnv, sal_False );
862 + const beans::Property* pProps;
864 + if( rProperties.getLength() ) {
865 + nProps = rProperties.getLength();
866 + pProps = rProperties.getConstArray();
868 + allProperties = getPropertySetInfo( xEnv )->getProperties();
869 + nProps = allProperties.getLength();
870 + pProps = allProperties.getConstArray();
873 + rtl::Reference< ::ucb::PropertyValueSet > xRow
874 + = new ::ucb::PropertyValueSet( m_xSMgr );
876 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
877 + for( sal_Int32 n = 0; n < nProps; ++n ) {
878 + const beans::Property& rProp = pProps[ n ];
880 + if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
881 + if (m_info.name && m_info.name[0] == '/')
882 + g_warning ("Odd NFS title on item '%s' == '%s'",
883 + getURI(), m_info.name);
884 + xRow->appendString( rProp, GnomeToOUString( m_info.name ) );
887 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
888 + xRow->appendString( rProp, getContentType () );
890 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) {
891 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
892 + xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_REGULAR ||
893 + m_info.type == GNOME_VFS_FILE_TYPE_UNKNOWN ) );
895 + xRow->appendVoid( rProp );
898 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) {
899 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
900 + xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) );
902 + xRow->appendVoid( rProp );
905 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) {
906 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
907 + xRow->appendLong( rProp, m_info.size );
909 + xRow->appendVoid( rProp );
912 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) ) {
913 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) {
914 + bool read_only = true;
916 + if (m_info.uid == getuid () &&
917 + m_info.permissions & GNOME_VFS_PERM_USER_WRITE)
919 + else if (m_info.gid == getgid () &&
920 + m_info.permissions & GNOME_VFS_PERM_GROUP_WRITE)
922 + else if (m_info.permissions & GNOME_VFS_PERM_OTHER_WRITE)
924 + xRow->appendBoolean( rProp, read_only );
926 + xRow->appendVoid( rProp );
929 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
930 + xRow->appendBoolean( rProp, ( m_info.name && m_info.name[0] == '.' ) );
932 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) ||
933 + rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisk" ) ) )
934 + xRow->appendBoolean( rProp, sal_False );
936 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ) {
937 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_CTIME)
938 + xRow->appendTimestamp( rProp, getDateFromUnix( m_info.ctime ) );
940 + xRow->appendVoid( rProp );
943 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
944 + if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME)
945 + xRow->appendTimestamp( rProp, getDateFromUnix( m_info.mtime ) );
947 + xRow->appendVoid( rProp );
950 + else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) {
951 + // We do this by sniffing in gnome-vfs; rather expensively.
953 + g_warning ("FIXME: Requested mime-type - an expensive op. indeed!");
955 + xRow->appendVoid( rProp );
957 + static int warn_count = 0;
958 + if (warn_count++ < 10)
959 + g_message ("Unknown property: '%s'",
960 + rtl::OUStringToOString( rProp.Name, RTL_TEXTENCODING_UTF8 ).getStr () );
961 + xRow->appendVoid( rProp );
965 + g_warning ("getPropertyValues on '%s' %d properties returned (of %d)",
966 + getURI(), (int)xRow->getLength(), (int)nProps);
969 + return uno::Reference< sdbc::XRow >( xRow.get() );
972 +static lang::IllegalAccessException
973 +getReadOnlyException( Content *ctnt )
975 + return lang::IllegalAccessException
976 + ( rtl::OUString::createFromAscii( "Property is read-only!" ),
977 + static_cast< cppu::OWeakObject * >( ctnt ) );
981 +Content::makeNewURL( const char *newName )
983 + rtl::OUString aNewURL = getParentURL();
984 + if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
985 + aNewURL += rtl::OUString::createFromAscii( "/" );
987 + char *name = gnome_vfs_escape_string( m_info.name );
988 + aNewURL += GnomeToOUString( name );
994 +// This is slightly complicated by needing to support either 'move' or 'setname'
996 +Content::doSetFileInfo( const GnomeVFSFileInfo *newInfo,
997 + GnomeVFSSetFileInfoMask setMask,
998 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1000 + GnomeVFSResult result = GNOME_VFS_OK;
1002 + g_assert (!m_bTransient);
1004 + ::rtl::OString aURI = getOURI();
1006 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1008 + // The simple approach:
1009 + if( setMask != GNOME_VFS_SET_FILE_INFO_NONE )
1010 + result = gnome_vfs_set_file_info // missed a const in the API there
1011 + ( (const sal_Char *) aURI, (GnomeVFSFileInfo *)newInfo, setMask );
1013 + if ( result == GNOME_VFS_ERROR_NOT_SUPPORTED &&
1014 + ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) ) {
1015 + // Try a move instead
1017 + g_warning( "SetFileInfo not supported on '%s'", getURI() );
1020 + char *newURI = OUStringToGnome( makeNewURL( newInfo->name ) );
1022 + result = gnome_vfs_move ((const sal_Char *)aURI, newURI, FALSE);
1031 +uno::Sequence< uno::Any > Content::setPropertyValues(
1032 + const uno::Sequence< beans::PropertyValue >& rValues,
1033 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1035 + rtl::OUString aNewTitle;
1036 + GnomeVFSFileInfo newInfo;
1037 + int setMask = GNOME_VFS_SET_FILE_INFO_NONE;
1041 + osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1043 + gnome_vfs_file_info_copy( &newInfo, &m_info );
1045 + Authentication aAuth( xEnv );
1047 + int nChanged = 0, nTitlePos = 0;
1048 + uno::Sequence< uno::Any > aRet( rValues.getLength() );
1049 + uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1051 + beans::PropertyChangeEvent aEvent;
1052 + aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1053 + aEvent.Further = sal_False;
1054 + aEvent.PropertyHandle = -1;
1055 + // aEvent.PropertyName = fill in later ...
1056 + // aEvent.OldValue =
1057 + // aEvent.NewValue =
1059 + int nCount = rValues.getLength();
1060 + const beans::PropertyValue* pValues = rValues.getConstArray();
1062 + for ( sal_Int32 n = 0; n < nCount; ++n ) {
1063 + const beans::PropertyValue& rValue = pValues[ n ];
1066 + g_warning( "Set prop '%s'", OUStringToGnome( rValue.Name ) );
1068 + if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
1069 + rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
1070 + rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
1071 + rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
1072 + rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
1073 + aRet[ n ] <<= getReadOnlyException( this );
1075 + else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
1076 + if ( rValue.Value >>= aNewTitle ) {
1077 + if ( aNewTitle.getLength() <= 0 )
1078 + aRet[ n ] <<= lang::IllegalArgumentException
1079 + ( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
1080 + static_cast< cppu::OWeakObject * >( this ), -1 );
1082 + char *newName = OUStringToGnome( aNewTitle );
1084 + if( !newName || !m_info.name || strcmp( newName, m_info.name ) ) {
1086 + g_warning ("Set new name to '%s'", newName);
1089 + aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
1090 + aEvent.OldValue = uno::makeAny( GnomeToOUString( newInfo.name ) );
1091 + aEvent.NewValue = uno::makeAny( aNewTitle );
1092 + aChanges.getArray()[ nChanged ] = aEvent;
1093 + nTitlePos = nChanged++;
1095 + newInfo.name = newName;
1096 + setMask |= GNOME_VFS_SET_FILE_INFO_NAME;
1097 + } else // same name
1101 + aRet[ n ] <<= beans::IllegalTypeException
1102 + ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
1103 + static_cast< cppu::OWeakObject * >( this ) );
1105 + } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ||
1106 + rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
1107 + // FIXME: should be able to set the timestamps
1108 + aRet[ n ] <<= getReadOnlyException( this );
1111 + g_warning( "Unhandled property '%s'", OUStringToGnome( rValue.Name ) );
1113 + aRet[ n ] <<= getReadOnlyException( this );
1117 + GnomeVFSResult result = GNOME_VFS_OK;
1119 + if ( !m_bTransient &&
1120 + ( result = doSetFileInfo( &newInfo,
1121 + (GnomeVFSSetFileInfoMask) setMask,
1122 + xEnv ) ) != GNOME_VFS_OK ) {
1123 + for (int i = 0; i < nChanged; i++)
1124 + aRet[ i ] <<= mapVFSException( result, sal_True );
1128 + if ( result == GNOME_VFS_OK) {
1129 + gnome_vfs_file_info_copy( &m_info, &newInfo );
1131 + if ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) {
1132 + uno::Reference< star::ucb::XContentIdentifier > xNewId
1133 + = new ::ucb::ContentIdentifier( m_xSMgr, makeNewURL( newInfo.name ) );
1136 + if (!exchangeIdentity( xNewId ) )
1137 + aRet[ nTitlePos ] <<= uno::Exception
1138 + ( rtl::OUString::createFromAscii( "Exchange failed!" ),
1139 + static_cast< cppu::OWeakObject * >( this ) );
1143 + gnome_vfs_file_info_clear( &newInfo );
1145 + if ( nChanged > 0 ) {
1147 + aChanges.realloc( nChanged );
1148 + notifyPropertiesChange( aChanges );
1154 +void Content::queryChildren( ContentRefList& rChildren )
1156 + // Obtain a list with a snapshot of all currently instanciated contents
1157 + // from provider and extract the contents which are direct children
1158 + // of this content.
1160 + ::ucb::ContentRefList aAllContents;
1161 + m_xProvider->queryExistingContents( aAllContents );
1163 + rtl::OUString aURL = getOUURI();
1164 + sal_Int32 nPos = aURL.lastIndexOf( '/' );
1166 + if ( nPos != ( aURL.getLength() - 1 ) )
1167 + aURL += rtl::OUString::createFromAscii( "/" );
1169 + sal_Int32 nLen = aURL.getLength();
1171 + ::ucb::ContentRefList::const_iterator it = aAllContents.begin();
1172 + ::ucb::ContentRefList::const_iterator end = aAllContents.end();
1174 + while ( it != end ) {
1175 + ::ucb::ContentImplHelperRef xChild = (*it);
1176 + rtl::OUString aChildURL
1177 + = xChild->getIdentifier()->getContentIdentifier();
1179 + // Is aURL a prefix of aChildURL?
1180 + if ( ( aChildURL.getLength() > nLen ) &&
1181 + ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) {
1182 + sal_Int32 nPos = nLen;
1183 + nPos = aChildURL.indexOf( '/', nPos );
1185 + if ( ( nPos == -1 ) ||
1186 + ( nPos == ( aChildURL.getLength() - 1 ) ) ) {
1187 + // No further slashes / only a final slash. It's a child!
1188 + rChildren.push_back( ::gvfs::Content::ContentRef
1189 + (static_cast< ::gvfs::Content * >(xChild.getBodyPtr() ) ) );
1196 +void Content::insert(
1197 + const uno::Reference< io::XInputStream > &xInputStream,
1198 + sal_Bool bReplaceExisting,
1199 + const uno::Reference< star::ucb::XCommandEnvironment > &xEnv )
1200 + throw( uno::Exception )
1202 + osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1205 + g_warning( "Insert '%s' (%d) (0x%x:%d)", getURI(), bReplaceExisting,
1206 + m_info.valid_fields, m_info.type );
1209 + GnomeVFSResult result = getInfo( xEnv );
1210 + // a racy design indeed.
1211 + if( !bReplaceExisting && !m_bTransient &&
1212 + result != GNOME_VFS_ERROR_NOT_FOUND) {
1214 + g_warning ("Nasty error inserting to '%s' ('%s')",
1215 + getURI(), gnome_vfs_result_to_string( result ));
1217 + cancelCommandExecution( GNOME_VFS_ERROR_FILE_EXISTS, xEnv, sal_True );
1220 + if ( m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
1221 + m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) {
1222 + ::rtl::OString aURI = getOURI();
1225 + perm = ( GNOME_VFS_PERM_USER_ALL |
1226 + GNOME_VFS_PERM_GROUP_READ |
1227 + GNOME_VFS_PERM_OTHER_READ );
1230 + g_warning ("Make directory");
1232 + result = gnome_vfs_make_directory( (const sal_Char *) aURI, perm );
1234 + if( result != GNOME_VFS_OK )
1235 + cancelCommandExecution( result, xEnv, sal_True );
1240 + if ( !xInputStream.is() ) {
1241 + // FIXME: slightly unclear whether to accept this and create an empty file
1242 + ucbhelper::cancelCommandExecution
1244 + ( star::ucb::MissingInputStreamException
1245 + ( rtl::OUString(),
1246 + static_cast< cppu::OWeakObject * >( this ) ) ),
1250 + GnomeVFSHandle *handle = NULL;
1251 + ::rtl::OString aURI = getOURI();
1253 + result = GNOME_VFS_OK;
1254 + if ( bReplaceExisting ) {
1255 + Authentication aAuth( xEnv );
1256 + result = gnome_vfs_open( &handle, (const sal_Char *)aURI,
1257 + GNOME_VFS_OPEN_WRITE );
1260 + if ( result != GNOME_VFS_OK ) {
1262 + Authentication aAuth( xEnv );
1264 + perm = ( ( GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ ) |
1265 + ( GNOME_VFS_PERM_GROUP_WRITE | GNOME_VFS_PERM_GROUP_READ ) );
1267 + result = gnome_vfs_create
1268 + ( &handle, (const sal_Char *)aURI, GNOME_VFS_OPEN_WRITE, TRUE, perm );
1271 + if( result != GNOME_VFS_OK )
1272 + cancelCommandExecution( result, xEnv, sal_True );
1274 + if ( !xInputStream.is() ) {
1275 + result = gnome_vfs_close( handle );
1276 + if (result != GNOME_VFS_OK)
1277 + cancelCommandExecution( result, xEnv, sal_True );
1279 + } else { // copy it over
1280 + uno::Reference < io::XOutputStream > xOutput =
1281 + new gvfs::Stream( handle, &m_info );
1283 + copyData( xInputStream, xOutput );
1286 + if (m_bTransient) {
1287 + m_bTransient = sal_False;
1293 +void Content::transfer(const star::ucb::TransferInfo & rArgs,
1294 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1295 + throw( uno::Exception )
1297 + // FIXME: see gnome-vfs-xfer.h - but we need to be able to easily
1298 + // detect which are gnome-vfs owned URI types ...
1299 + ucbhelper::cancelCommandExecution
1301 + ( star::ucb::InteractiveBadTransferURLException
1302 + ( rtl::OUString::createFromAscii( "Unsupported URL scheme!" ),
1303 + static_cast< cppu::OWeakObject * >( this ) ) ),
1307 +void Content::destroy( sal_Bool bDeletePhysical )
1308 + throw( uno::Exception )
1310 + // @@@ take care about bDeletePhysical -> trashcan support
1311 + rtl::OUString aURL = getOUURI();
1313 + uno::Reference< star::ucb::XContent > xThis = this;
1317 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1319 + // Process instanciated children...
1320 + ::gvfs::Content::ContentRefList aChildren;
1321 + queryChildren( aChildren );
1323 + ContentRefList::const_iterator it = aChildren.begin();
1324 + ContentRefList::const_iterator end = aChildren.end();
1326 + while ( it != end ) {
1327 + (*it)->destroy( bDeletePhysical );
1332 +// Used by the 'setPropertyValues' method for
1333 +// propagating the renaming of a Content.
1334 +sal_Bool Content::exchangeIdentity(
1335 + const uno::Reference< star::ucb::XContentIdentifier >& xNewId )
1337 + if ( !xNewId.is() )
1340 + uno::Reference< star::ucb::XContent > xThis = this;
1343 + g_warning( "exchangeIdentity from '%s' to '%s'",
1344 + getURI(), OUStringToGnome( xNewId->getContentIdentifier() ) );
1347 + if ( m_bTransient ) {
1348 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1349 + /* FIXME: can we not screw up an identically named
1350 + * Content pointing to ourself here ? */
1351 + m_xIdentifier = xNewId;
1355 + rtl::OUString aOldURL = getOUURI();
1357 + // Exchange own identitity.
1358 + if ( exchange( xNewId ) ) {
1360 + // Process instanciated children...
1361 + ContentRefList aChildren;
1362 + queryChildren( aChildren );
1364 + ContentRefList::const_iterator it = aChildren.begin();
1365 + ContentRefList::const_iterator end = aChildren.end();
1367 + while ( it != end ) {
1368 + ContentRef xChild = (*it);
1370 + // Create new content identifier for the child...
1371 + uno::Reference< star::ucb::XContentIdentifier >
1372 + xOldChildId = xChild->getIdentifier();
1373 + rtl::OUString aOldChildURL
1374 + = xOldChildId->getContentIdentifier();
1375 + rtl::OUString aNewChildURL
1376 + = aOldChildURL.replaceAt(
1378 + aOldURL.getLength(),
1379 + xNewId->getContentIdentifier() );
1380 + uno::Reference< star::ucb::XContentIdentifier >
1382 + = new ::ucb::ContentIdentifier( m_xSMgr, aNewChildURL );
1384 + if ( !xChild->exchangeIdentity( xNewChildId ) )
1396 +Content::getInfo( const ::com::sun::star::uno::Reference<
1397 + ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
1399 + GnomeVFSResult result;
1400 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1403 + result = GNOME_VFS_OK;
1405 + else if ( !m_info.valid_fields ) {
1406 + ::rtl::OString aURI = getOURI();
1407 + Authentication aAuth( xEnv );
1408 + result = gnome_vfs_get_file_info
1409 + ( (const sal_Char *)aURI, &m_info, GNOME_VFS_FILE_INFO_DEFAULT );
1410 + if (result != GNOME_VFS_OK)
1411 + gnome_vfs_file_info_clear( &m_info );
1413 + result = GNOME_VFS_OK;
1415 + g_warning( "getInfo on '%s' returns '%s' (%d) (0x%x)",
1416 + getURI(), gnome_vfs_result_to_string( result ),
1417 + result, m_info.valid_fields );
1423 +Content::isFolder(const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1425 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1427 + return (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
1428 + m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY);
1431 +uno::Any Content::mapVFSException( const GnomeVFSResult result, sal_Bool bWrite )
1433 + uno::Any aException;
1434 + const char *gvfs_message;
1435 + rtl::OUString message;
1436 + uno::Sequence< uno::Any > aArgs( 1 );
1439 + g_warning ("Map VFS exception '%s' (%d)",
1440 + gnome_vfs_result_to_string( result ), result );
1443 + if ((gvfs_message = gnome_vfs_result_to_string (result)))
1444 + message = GnomeToOUString( gvfs_message );
1447 + case GNOME_VFS_OK:
1448 + g_error ("VFS_OK mapped to exception.");
1450 + case GNOME_VFS_ERROR_EOF:
1451 + g_warning ("VFS_EOF not handled somewhere.");
1453 + case GNOME_VFS_ERROR_NOT_FOUND:
1454 + aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
1456 + star::ucb::InteractiveAugmentedIOException
1457 + ( rtl::OUString::createFromAscii( "Not found!" ),
1458 + static_cast< cppu::OWeakObject * >( this ),
1459 + task::InteractionClassification_ERROR,
1460 + star::ucb::IOErrorCode_NOT_EXISTING,
1463 + case GNOME_VFS_ERROR_BAD_PARAMETERS:
1465 + lang::IllegalArgumentException
1466 + ( rtl::OUString(),
1467 + static_cast< cppu::OWeakObject * >( this ),
1470 + case GNOME_VFS_ERROR_GENERIC:
1471 + case GNOME_VFS_ERROR_INTERNAL:
1472 + case GNOME_VFS_ERROR_NOT_SUPPORTED:
1474 + g_warning ("Internal - un-mapped error");
1476 + aException <<= io::IOException();
1478 + case GNOME_VFS_ERROR_IO:
1481 + star::ucb::InteractiveNetworkWriteException
1482 + ( rtl::OUString(),
1483 + static_cast< cppu::OWeakObject * >( this ),
1484 + task::InteractionClassification_ERROR,
1488 + star::ucb::InteractiveNetworkReadException
1489 + ( rtl::OUString(),
1490 + static_cast< cppu::OWeakObject * >( this ),
1491 + task::InteractionClassification_ERROR,
1494 + case GNOME_VFS_ERROR_HOST_NOT_FOUND:
1495 + case GNOME_VFS_ERROR_INVALID_HOST_NAME:
1497 + star::ucb::InteractiveNetworkResolveNameException
1498 + ( rtl::OUString(),
1499 + static_cast< cppu::OWeakObject * >( this ),
1500 + task::InteractionClassification_ERROR,
1503 + case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
1504 + case GNOME_VFS_ERROR_SERVICE_OBSOLETE:
1505 + case GNOME_VFS_ERROR_PROTOCOL_ERROR:
1506 + case GNOME_VFS_ERROR_NO_MASTER_BROWSER:
1508 + star::ucb::InteractiveNetworkConnectException
1509 + ( rtl::OUString(),
1510 + static_cast< cppu::OWeakObject * >( this ),
1511 + task::InteractionClassification_ERROR,
1515 + case GNOME_VFS_ERROR_FILE_EXISTS:
1516 + aException <<= star::ucb::NameClashException
1517 + ( rtl::OUString(),
1518 + static_cast< cppu::OWeakObject * >( this ),
1519 + task::InteractionClassification_ERROR,
1523 + case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
1524 + aException <<= star::ucb::UnsupportedOpenModeException();
1527 + case GNOME_VFS_ERROR_CORRUPTED_DATA:
1528 + case GNOME_VFS_ERROR_WRONG_FORMAT:
1529 + case GNOME_VFS_ERROR_BAD_FILE:
1530 + case GNOME_VFS_ERROR_TOO_BIG:
1531 + case GNOME_VFS_ERROR_NO_SPACE:
1532 + case GNOME_VFS_ERROR_READ_ONLY:
1533 + case GNOME_VFS_ERROR_INVALID_URI:
1534 + case GNOME_VFS_ERROR_NOT_OPEN:
1535 + case GNOME_VFS_ERROR_ACCESS_DENIED:
1536 + case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
1537 + case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
1538 + case GNOME_VFS_ERROR_IN_PROGRESS:
1539 + case GNOME_VFS_ERROR_INTERRUPTED:
1540 + case GNOME_VFS_ERROR_LOOP:
1541 + case GNOME_VFS_ERROR_NOT_PERMITTED:
1542 + case GNOME_VFS_ERROR_IS_DIRECTORY:
1543 + case GNOME_VFS_ERROR_NO_MEMORY:
1544 + case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
1545 + case GNOME_VFS_ERROR_LOGIN_FAILED:
1546 + case GNOME_VFS_ERROR_CANCELLED:
1547 + case GNOME_VFS_ERROR_DIRECTORY_BUSY:
1548 + case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
1549 + case GNOME_VFS_ERROR_TOO_MANY_LINKS:
1550 + case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:
1551 + case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
1552 + case GNOME_VFS_ERROR_NAME_TOO_LONG:
1554 + g_warning( "FIXME: Un-mapped VFS exception '%s' (%d)",
1555 + gnome_vfs_result_to_string( result ), result );
1558 + aException <<= star::ucb::InteractiveNetworkGeneralException
1559 + ( rtl::OUString(),
1560 + static_cast< cppu::OWeakObject * >( this ),
1561 + task::InteractionClassification_ERROR );
1565 + return aException;
1568 +void Content::cancelCommandExecution(
1569 + GnomeVFSResult result,
1570 + const uno::Reference< star::ucb::XCommandEnvironment > & xEnv,
1571 + sal_Bool bWrite /* = sal_False */ )
1572 + throw ( uno::Exception )
1574 + ucbhelper::cancelCommandExecution( mapVFSException( result, bWrite ), xEnv );
1578 +uno::Sequence< beans::Property > Content::getProperties(
1579 + const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
1581 + static const beans::Property aGenericProperties[] = {
1582 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
1583 + -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1584 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1585 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
1586 + -1, getCppuBooleanType(),
1587 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1588 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
1589 + -1, getCppuBooleanType(),
1590 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1591 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
1592 + -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1593 + beans::PropertyAttribute::BOUND ),
1595 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
1596 + -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1597 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1598 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
1599 + -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
1600 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1601 +// FIXME: Too expensive for now (?)
1602 +// beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1603 +// -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
1604 +// beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1605 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
1606 + -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
1607 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1608 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
1609 + -1, getCppuBooleanType(),
1610 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1611 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
1612 + -1, getCppuBooleanType(),
1613 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1614 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisk" ) ),
1615 + -1, getCppuBooleanType(),
1616 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
1617 + beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
1618 + -1, getCppuBooleanType(),
1619 + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
1622 + const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
1624 + return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
1628 +uno::Sequence< com::sun::star::ucb::CommandInfo > Content::getCommands(
1629 + const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
1631 + static com::sun::star::ucb::CommandInfo aDocumentCommandInfoTable[] = {
1632 + // Required commands
1633 + com::sun::star::ucb::CommandInfo
1634 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
1635 + -1, getCppuVoidType() ),
1636 + com::sun::star::ucb::CommandInfo
1637 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
1638 + -1, getCppuVoidType() ),
1639 + com::sun::star::ucb::CommandInfo
1640 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
1641 + -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
1642 + com::sun::star::ucb::CommandInfo
1643 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
1644 + -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
1646 + // Optional standard commands
1647 + com::sun::star::ucb::CommandInfo
1648 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
1649 + -1, getCppuBooleanType() ),
1650 + com::sun::star::ucb::CommandInfo
1651 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
1652 + -1, getCppuType( static_cast<com::sun::star::ucb::InsertCommandArgument * >( 0 ) ) ),
1653 + com::sun::star::ucb::CommandInfo
1654 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
1655 + -1, getCppuType( static_cast<com::sun::star::ucb::OpenCommandArgument2 * >( 0 ) ) ),
1658 + com::sun::star::ucb::CommandInfo
1659 + ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
1660 + -1, getCppuType( static_cast<com::sun::star::ucb::TransferInfo * >( 0 ) ) )
1664 + if ( isFolder( xEnv ) )
1667 + return uno::Sequence< com::sun::star::ucb::CommandInfo >(aDocumentCommandInfoTable, num );
1671 +Content::getOUURI ()
1673 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1674 + return m_xIdentifier->getContentIdentifier();
1678 +Content::getOURI ()
1680 + return rtl::OUStringToOString( getOUURI(), RTL_TEXTENCODING_UTF8 );
1686 + return OUStringToGnome( getOUURI() );
1690 +Content::copyData( ::com::sun::star::uno::Reference<
1691 + ::com::sun::star::io::XInputStream > xIn,
1692 + ::com::sun::star::uno::Reference<
1693 + ::com::sun::star::io::XOutputStream > xOut )
1695 + uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
1697 + g_return_if_fail( xIn.is() && xOut.is() );
1699 + while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
1700 + xOut->writeBytes( theData );
1702 + xOut->closeOutput();
1705 +// Inherits an authentication context
1706 +::com::sun::star::uno::Reference<
1707 + ::com::sun::star::io::XInputStream >
1708 +Content::createTempStream( const ::com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
1709 + throw( ::com::sun::star::uno::Exception )
1711 + GnomeVFSResult result;
1712 + GnomeVFSHandle *handle = NULL;
1713 + ::rtl::OString aURI = getOURI();
1715 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1716 + // Something badly wrong happened - can't seek => stream to a temporary file
1717 + const rtl::OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
1718 + uno::Reference < io::XOutputStream > xTempOut =
1719 + uno::Reference < io::XOutputStream >
1720 + ( m_xSMgr->createInstance( sServiceName ), uno::UNO_QUERY );
1722 + if ( !xTempOut.is() )
1723 + cancelCommandExecution( GNOME_VFS_ERROR_IO, xEnv );
1725 + result = gnome_vfs_open
1726 + ( &handle, (const sal_Char *)aURI, GNOME_VFS_OPEN_READ );
1727 + if (result != GNOME_VFS_OK)
1728 + cancelCommandExecution( result, xEnv );
1730 + uno::Reference < io::XInputStream > pStream = new ::gvfs::Stream( handle, &m_info );
1731 + copyData( pStream, xTempOut );
1733 + return uno::Reference < io::XInputStream > ( xTempOut, uno::UNO_QUERY );
1736 +::com::sun::star::uno::Reference<
1737 + ::com::sun::star::io::XInputStream >
1738 +Content::createInputStream( const ::com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
1739 + throw( ::com::sun::star::uno::Exception )
1741 + GnomeVFSHandle *handle = NULL;
1742 + GnomeVFSResult result;
1743 + uno::Reference<io::XInputStream > xIn;
1745 + Authentication aAuth( xEnv );
1746 + osl::Guard< osl::Mutex > aGuard( m_aMutex );
1749 + ::rtl::OString aURI = getOURI();
1751 + if ( !(m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) )
1752 + return createTempStream( xEnv );
1754 + result = gnome_vfs_open
1755 + ( &handle, (const sal_Char *)aURI,
1756 + (GnomeVFSOpenMode) (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM ) );
1758 + if (result == GNOME_VFS_ERROR_INVALID_OPEN_MODE ||
1759 + result == GNOME_VFS_ERROR_NOT_SUPPORTED)
1760 + return createTempStream( xEnv );
1762 + if (result != GNOME_VFS_OK)
1763 + cancelCommandExecution( result, xEnv );
1765 + // Try a seek just to make sure it's Random access: some lie.
1766 + result = gnome_vfs_seek( handle, GNOME_VFS_SEEK_START, 0);
1767 + if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) {
1768 + gnome_vfs_close( handle );
1769 + return createTempStream( xEnv );
1772 + if (result != GNOME_VFS_OK)
1773 + cancelCommandExecution( result, xEnv );
1775 + if (handle != NULL)
1776 + xIn = new ::gvfs::Stream( handle, &m_info );
1782 +Content::feedSink( uno::Reference< ::com::sun::star::uno::XInterface > aSink,
1783 + const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1785 + if ( !aSink.is() )
1788 + uno::Reference< io::XOutputStream > xOut
1789 + = uno::Reference< io::XOutputStream >(aSink, uno::UNO_QUERY );
1790 + uno::Reference< io::XActiveDataSink > xDataSink
1791 + = uno::Reference< io::XActiveDataSink >(aSink, uno::UNO_QUERY );
1793 + if ( !xOut.is() && !xDataSink.is() )
1796 + uno::Reference< io::XInputStream > xIn = createInputStream( xEnv );
1801 + copyData( xIn, xOut );
1803 + if ( xDataSink.is() )
1804 + xDataSink->setInputStream( xIn );
1811 + vfs_authentication_callback (gconstpointer in_void,
1813 + gpointer out_void,
1815 + gpointer callback_data)
1817 + task::XInteractionHandler *xIH;
1820 + g_warning ("Authentication callback (%p)...", callback_data);
1823 + if( !( xIH = (task::XInteractionHandler *) callback_data ) )
1826 + const GnomeVFSModuleCallbackAuthenticationIn *in =
1827 + (const GnomeVFSModuleCallbackAuthenticationIn *) in_void;
1828 + GnomeVFSModuleCallbackAuthenticationOut *out =
1829 + (GnomeVFSModuleCallbackAuthenticationOut *) out_void;
1831 + g_return_if_fail (in != NULL && out != NULL);
1832 + g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size &&
1833 + sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
1836 + ::rtl::OUString inHostName, inRealm;
1837 + ::rtl::OUString aUserName, aPassword;
1840 + GnomeVFSURI *uri = gnome_vfs_uri_new( in->uri );
1841 + if( gnome_vfs_uri_get_host_name( uri ) )
1842 + inHostName = rtl::OUString::createFromAscii
1843 + ( gnome_vfs_uri_get_host_name( uri ) );
1844 + if( gnome_vfs_uri_get_user_name( uri ) )
1845 + aUserName = rtl::OUString::createFromAscii
1846 + ( gnome_vfs_uri_get_user_name( uri ) );
1847 + if( gnome_vfs_uri_get_password( uri ) )
1848 + aPassword = rtl::OUString::createFromAscii
1849 + ( gnome_vfs_uri_get_password( uri ) );
1850 + gnome_vfs_uri_unref (uri);
1853 + inRealm = rtl::OUString::createFromAscii( in->realm );
1855 + rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
1856 + = new ucbhelper::SimpleAuthenticationRequest
1857 + ( inHostName, inRealm, rtl::OUString(), rtl::OUString() );
1859 + xIH->handle( xRequest.get() );
1861 + rtl::Reference< ucbhelper::InteractionContinuation > xSelection
1862 + = xRequest->getSelection();
1864 + if ( xSelection.is() ) {
1865 + // Handler handled the request.
1866 + uno::Reference< task::XInteractionAbort > xAbort(xSelection.get(), uno::UNO_QUERY );
1867 + if ( !xAbort.is() ) {
1868 + const rtl::Reference<
1869 + ucbhelper::InteractionSupplyAuthentication > & xSupp
1870 + = xRequest->getAuthenticationSupplier();
1872 + aUserName = xSupp->getUserName();
1873 + aPassword = xSupp->getPassword();
1875 + out->username = OUStringToGnome( aUserName );
1876 + out->password = OUStringToGnome( aPassword );
1878 + g_warning ("Got valid user/password '%s' '%s'",
1879 + out->username, out->password);
1886 + auth_destroy (gpointer data)
1888 + task::XInteractionHandler *xIH;
1889 + if( ( xIH = ( task::XInteractionHandler * )data ) )
1893 + // This sucks, but gnome-vfs doesn't much like
1894 + // repeated set / unsets - so we have to compensate.
1895 + GPrivate *auth_queue = NULL;
1897 + void auth_queue_destroy( gpointer data )
1900 + GQueue *vq = (GQueue *) data;
1902 + for (l = vq->head; l; l = l->next)
1903 + auth_destroy (l->data);
1904 + g_queue_free (vq);
1909 +refresh_auth( GQueue *vq )
1913 + gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION );
1915 + for (l = vq->head; l; l = l->next) {
1917 + gnome_vfs_module_callback_push
1918 + ( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
1919 + vfs_authentication_callback, l->data, NULL );
1925 +gvfs::Authentication::Authentication(const com::sun::star::uno::Reference<
1926 + com::sun::star::ucb::XCommandEnvironment > & xEnv )
1929 + uno::Reference< task::XInteractionHandler > xIH;
1932 + xIH = xEnv->getInteractionHandler();
1937 + if( !(vq = (GQueue *)g_private_get( auth_queue ) ) ) {
1938 + vq = g_queue_new();
1939 + g_private_set( auth_queue, vq );
1942 + g_queue_push_head( vq, (gpointer) xIH.get() );
1943 + refresh_auth( vq );
1946 +gvfs::Authentication::~Authentication()
1951 + vq = (GQueue *)g_private_get( auth_queue );
1953 + data = g_queue_pop_head( vq );
1954 + auth_destroy (data);
1956 + refresh_auth( vq );