]> git.pld-linux.org Git - packages/libreoffice.git/blame - openoffice-vfs-content.patch
- DON'T hardcode java paths!
[packages/libreoffice.git] / openoffice-vfs-content.patch
CommitLineData
6a08dcc1 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
3@@ -0,0 +1,249 @@
4+#ifndef _GVFS_UCP_CONTENT_HXX
5+#define _GVFS_UCP_CONTENT_HXX
6+
7+#include <memory>
8+#include <list>
9+
10+#ifndef _RTL_REF_HXX_
11+#include <rtl/ref.hxx>
12+#endif
13+
14+#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
15+#include <com/sun/star/ucb/ContentCreationException.hpp>
16+#endif
17+#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
18+#include <com/sun/star/ucb/XContentCreator.hpp>
19+#endif
20+
21+#ifndef _UCBHELPER_CONTENTHELPER_HXX
22+#include <ucbhelper/contenthelper.hxx>
23+#endif
24+
25+#include <glib/gthread.h>
26+#include <libgnomevfs/gnome-vfs-ops.h>
27+#include <libgnomevfs/gnome-vfs-directory.h>
28+
29+namespace com { namespace sun { namespace star { namespace beans {
30+ struct Property;
31+ struct PropertyValue;
32+} } } }
33+
34+namespace com { namespace sun { namespace star { namespace io {
35+ class XInputStream;
36+ class XOutputStream;
37+} } } }
38+
39+namespace com { namespace sun { namespace star { namespace sdbc {
40+ class XRow;
41+} } } }
42+
43+namespace com { namespace sun { namespace star { namespace ucb {
44+ struct TransferInfo;
45+} } } }
46+
47+namespace gvfs
48+{
49+
50+class ContentProvider;
51+class ContentProperties;
52+
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"
56+
57+class Authentication
58+{
59+public:
60+ // Helper class to make exceptions pleasant
61+ Authentication( const com::sun::star::uno::Reference<
62+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
63+ ~Authentication();
64+};
65+
66+class Content : public ::ucb::ContentImplHelper,
67+ public com::sun::star::ucb::XContentCreator
68+{
69+//=========================================================================
70+// Internals
71+//=========================================================================
72+private:
73+ typedef rtl::Reference< Content > ContentRef;
74+ typedef std::list< ContentRef > ContentRefList;
75+
76+ // Instance data
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
80+
81+ // Internal helpers
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
96+
97+ // For ucbhelper
98+ virtual ::rtl::OUString getParentURL();
99+ // For ucbhelper
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 );
103+ // For ucbhelper
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 );
107+
108+public:
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 );
115+
116+private:
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 );
123+
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 );
131+
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 );
137+
138+ // Command "delete"
139+ void destroy( sal_Bool bDeletePhysical )
140+ throw( ::com::sun::star::uno::Exception );
141+
142+ // "open" helpers
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 );
147+
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 );
162+
163+ ::com::sun::star::uno::Any mapVFSException( const GnomeVFSResult result,
164+ sal_Bool bWrite );
165+
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 );
171+
172+
173+public:
174+ // Non-interface bits
175+ char *getURI ();
176+ rtl::OString getOURI ();
177+ rtl::OUString getOUURI ();
178+
179+//=========================================================================
180+// Externals
181+//=========================================================================
182+public:
183+
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,
195+ sal_Bool isFolder)
196+ throw ( ::com::sun::star::ucb::ContentCreationException );
197+ virtual ~Content();
198+
199+ // XInterface
200+ XINTERFACE_DECL()
201+
202+ // XTypeProvider
203+ XTYPEPROVIDER_DECL()
204+
205+ // XServiceInfo
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 );
211+
212+ // XContent
213+ virtual rtl::OUString SAL_CALL
214+ getContentType()
215+ throw( com::sun::star::uno::RuntimeException );
216+
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 );
229+
230+ //////////////////////////////////////////////////////////////////////
231+ // Additional interfaces
232+ //////////////////////////////////////////////////////////////////////
233+
234+ // XContentCreator
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 );
243+};
244+
245+};
246+
247+extern "C" {
248+ extern GPrivate *auth_queue;
249+ extern void auth_queue_destroy( gpointer data );
250+};
251+
252+#endif
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
255@@ -0,0 +1,1702 @@
256+#include <string.h>
257+#include <unistd.h>
258+#include <sys/types.h>
259+#include <tools/datetime.hxx>
260+#ifndef _OSL_DIAGNOSE_H_
261+#include <osl/diagnose.h>
262+#endif
263+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
264+#include <com/sun/star/beans/PropertyValue.hpp>
265+#endif
266+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
267+#include <com/sun/star/beans/PropertyAttribute.hpp>
268+#endif
269+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSETINFOCHANGE_HPP_
270+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
271+#endif
272+#ifndef _COM_SUN_STAR_BEANS_PROPERTYSETINFOCHANGEEVENT_HPP_
273+#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
274+#endif
275+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
276+#include <com/sun/star/io/XActiveDataSink.hpp>
277+#endif
278+#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
279+#include <com/sun/star/io/XOutputStream.hpp>
280+#endif
281+#ifndef _COM_SUN_STAR_LANG_ILLEGALACCESSEXCEPTION_HPP_
282+#include <com/sun/star/lang/IllegalAccessException.hpp>
283+#endif
284+#ifndef _COM_SUN_STAR_UCB_CONTENTINFOATTRIBUTE_HPP_
285+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
286+#endif
287+#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
288+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
289+#endif
290+#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
291+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
292+#endif
293+#ifndef _COM_SUN_STAR_UCB_INTERACTIVEAUGMENTEDIOEXCEPTION_HPP_
294+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
295+#endif
296+#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKCONNECTEXCEPTION_HPP_
297+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
298+#endif
299+#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_
300+#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
301+#endif
302+#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKREADEXCEPTION_HPP_
303+#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
304+#endif
305+#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKRESOLVENAMEEXCEPTION_HPP_
306+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
307+#endif
308+#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKWRITEEXCEPTION_HPP_
309+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
310+#endif
311+#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
312+#include <com/sun/star/ucb/NameClash.hpp>
313+#endif
314+#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
315+#include <com/sun/star/ucb/NameClashException.hpp>
316+#endif
317+#ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_
318+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
319+#endif
320+#ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
321+#include <com/sun/star/ucb/OpenMode.hpp>
322+#endif
323+#ifndef _COM_SUN_STAR_UCB_POSTCOMMANDARGUMENT2_HPP_
324+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
325+#endif
326+#ifndef _COM_SUN_STAR_UCB_TRANSFERINFO_HPP_
327+#include <com/sun/star/ucb/TransferInfo.hpp>
328+#endif
329+#ifndef _COM_SUN_STAR_UCB_XCOMMANDINFO_HPP_
330+#include <com/sun/star/ucb/XCommandInfo.hpp>
331+#endif
332+#ifndef _COM_SUN_STAR_UCB_XPERSISTENTPROPERTYSET_HPP_
333+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
334+#endif
335+#ifndef _COM_SUN_STAR_UCB_MISSINGINPUTSTREAMEXCEPTION_HPP_
336+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
337+#endif
338+#ifndef _COM_SUN_STAR_UCB_MISSINGPROPERTIESEXCEPTION_HPP_
339+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
340+#endif
341+#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDCOMMANDEXCEPTION_HPP_
342+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
343+#endif
344+#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDDATASINKEXCEPTION_HPP_
345+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
346+#endif
347+#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDNAMECLASHEXCEPTION_HPP_
348+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
349+#endif
350+#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_
351+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
352+#endif
353+#ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_
354+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
355+#endif
356+#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
357+#include <com/sun/star/ucb/NameClashException.hpp>
358+#endif
359+
360+#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
361+#include <ucbhelper/contentidentifier.hxx>
362+#endif
363+#ifndef _UCBHELPER_PROPERTYVALUESET_HXX
364+#include <ucbhelper/propertyvalueset.hxx>
365+#endif
366+#ifndef _UCBHELPER_INTERACTIONREQUEST_HXX
367+#include <ucbhelper/interactionrequest.hxx>
368+#endif
369+#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
370+#include <ucbhelper/cancelcommandexecution.hxx>
371+#endif
372+#ifndef _UCBHELPER_SIMPLEAUTHENTICATIONREQUEST_HXX
373+#include <ucbhelper/simpleauthenticationrequest.hxx>
374+#endif
375+
376+const int TRANSFER_BUFFER_SIZE = 65536;
377+
378+/*
379+ * NB. Name escaping is done only for URIs
380+ * the 'Title' property is unescaped on set/get
381+ */
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>
387+}
388+
389+#include "content.hxx"
390+#include "provider.hxx"
391+#include "directory.hxx"
392+#include "stream.hxx"
393+
394+using namespace gvfs;
395+using namespace com::sun;
396+using namespace com::sun::star;
397+
398+#define CLEAR_INFO(info) memset((info), 0, sizeof ((info)[0]))
399+
400+
401+static char *
402+OUStringToGnome( const rtl::OUString &str )
403+{
404+ rtl::OString aTempStr = rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 );
405+ return g_strdup( (const sal_Char *) aTempStr );
406+}
407+
408+static rtl::OUString
409+GnomeToOUString( const char *utf8_str)
410+{
411+ if (!utf8_str)
412+ return rtl::OUString();
413+ else
414+ return rtl::OUString( utf8_str, strlen( utf8_str ), RTL_TEXTENCODING_UTF8 );
415+}
416+
417+
418+Content::Content(
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 )
426+{
427+ CLEAR_INFO (&m_info);
428+#ifdef DEBUG
429+ g_warning ("New Content ('%s')", getURI());
430+#endif
431+}
432+
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,
438+ sal_Bool isFolder)
439+ throw ( ::com::sun::star::ucb::ContentCreationException )
440+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
441+ m_pProvider( pProvider ),
442+ m_bTransient( sal_True )
443+{
444+ CLEAR_INFO (&m_info);
445+
446+#ifdef DEBUG
447+ g_warning ("New Transient content ('%s') (%d)", getURI(), isFolder);
448+#endif
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;
453+}
454+
455+// virtual
456+Content::~Content()
457+{
458+ gnome_vfs_file_info_clear( &m_info );
459+}
460+
461+//
462+// XInterface methods.
463+//
464+
465+void SAL_CALL Content::acquire()
466+ throw( )
467+{
468+ ContentImplHelper::acquire();
469+}
470+void SAL_CALL Content::release()
471+ throw( )
472+{
473+ ContentImplHelper::release();
474+}
475+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
476+ throw ( uno::RuntimeException )
477+{
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();
485+ else
486+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
487+}
488+
489+//
490+// XTypeProvider methods.
491+//
492+
493+XTYPEPROVIDER_COMMON_IMPL( Content );
494+
495+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
496+ throw( uno::RuntimeException )
497+{
498+ static cppu::OTypeCollection *pFolderCollection = NULL;
499+ static cppu::OTypeCollection *pFileCollection = NULL;
500+
501+ if (!pFolderCollection) {
502+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
503+
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 ) );
528+
529+ pFolderCollection = &aFolderCollection;
530+ pFileCollection = &aFileCollection;
531+ // FIXME: need write barrier from HEAD.
532+ }
533+ }
534+
535+ if ( isFolder( uno::Reference< star::ucb::XCommandEnvironment >() ) )
536+ return pFolderCollection->getTypes();
537+ else
538+ return pFileCollection->getTypes();
539+}
540+
541+//
542+// XServiceInfo methods.
543+//
544+
545+rtl::OUString SAL_CALL Content::getImplementationName()
546+ throw( uno::RuntimeException )
547+{
548+ return rtl::OUString::createFromAscii("com.sun.star.comp.GnomeVFSContent" );
549+}
550+
551+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
552+ throw( uno::RuntimeException )
553+{
554+ uno::Sequence< rtl::OUString > aSNS( 1 );
555+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
556+ "com.sun.star.ucb.GnomeVFSContent" );
557+ return aSNS;
558+}
559+
560+//
561+// XContent methods.
562+//
563+
564+rtl::OUString SAL_CALL Content::getContentType()
565+ throw( uno::RuntimeException )
566+{
567+ if ( isFolder( uno::Reference< star::ucb::XCommandEnvironment >() ) )
568+ return rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
569+ else
570+ return rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
571+}
572+
573+//
574+// XCommandProcessor methods.
575+//
576+
577+uno::Any Content::getBadArgExcept()
578+{
579+ return uno::makeAny( lang::IllegalArgumentException
580+ ( rtl::OUString::createFromAscii( "Wrong argument type!" ),
581+ static_cast< cppu::OWeakObject * >( this ),
582+ -1 ) );
583+}
584+
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 )
592+{
593+ uno::Any aRet;
594+
595+#ifdef DEBUG
596+ {
597+ uno::Reference< task::XInteractionHandler > xIH;
598+
599+ if ( xEnv.is() )
600+ xIH = xEnv->getInteractionHandler();
601+ g_warning( "Execute command: '%s' with %s interaction env",
602+ OUStringToGnome( aCommand.Name ),
603+ xIH.is() ? "" : "NO" );
604+ }
605+#endif
606+
607+#define COMMAND_IS(cmd,name) ( (cmd).Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( name ) ) )
608+
609+ if ( COMMAND_IS( aCommand, "getPropertyValues" ) ) {
610+ uno::Sequence< beans::Property > Properties;
611+
612+ if ( !( aCommand.Argument >>= Properties ) )
613+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
614+
615+ aRet <<= getPropertyValues( Properties, xEnv );
616+
617+ } else if ( COMMAND_IS( aCommand, "setPropertyValues" ) ) {
618+ uno::Sequence< beans::PropertyValue > aProperties;
619+
620+ if ( !( aCommand.Argument >>= aProperties ) ||
621+ !aProperties.getLength() )
622+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
623+
624+ aRet <<= setPropertyValues( aProperties, xEnv );
625+
626+ } else if ( COMMAND_IS( aCommand, "getPropertySetInfo" ) ) {
627+ aRet <<= getPropertySetInfo( xEnv, sal_False );
628+
629+ } else if ( COMMAND_IS( aCommand, "getCommandInfo" ) ) {
630+ aRet <<= getCommandInfo( xEnv, sal_False );
631+
632+ } else if ( COMMAND_IS( aCommand, "open" ) ) {
633+
634+ star::ucb::OpenCommandArgument2 aOpenCommand;
635+ if ( !( aCommand.Argument >>= aOpenCommand ) )
636+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
637+
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 ) );
642+
643+ if ( bOpenFolder && isFolder( xEnv ) ) {
644+ uno::Reference< star::ucb::XDynamicResultSet > xSet
645+ = new DynamicResultSet(m_xSMgr, this, aOpenCommand, xEnv );
646+ aRet <<= xSet;
647+
648+ } else if ( aOpenCommand.Sink.is() ) {
649+
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
656+ ( rtl::OUString(),
657+ static_cast< cppu::OWeakObject * >( this ),
658+ sal_Int16( aOpenCommand.Mode ) ) ),
659+ xEnv );
660+ }
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...
665+#ifdef DEBUG
666+ g_warning ("Failed to load data from '%s'", getURI());
667+#endif
668+ ucbhelper::cancelCommandExecution
669+ ( uno::makeAny (star::ucb::UnsupportedDataSinkException
670+ ( rtl::OUString(),
671+ static_cast< cppu::OWeakObject * >( this ),
672+ aOpenCommand.Sink ) ),
673+ xEnv );
674+ }
675+ }
676+#ifdef DEBUG
677+ else
678+ g_warning ("Open falling through ...");
679+#endif
680+
681+ } else if ( COMMAND_IS( aCommand, "insert" ) ) {
682+ star::ucb::InsertCommandArgument arg;
683+ if ( !( aCommand.Argument >>= arg ) )
684+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
685+
686+ insert( arg.Data, arg.ReplaceExisting, xEnv );
687+
688+ } else if ( COMMAND_IS( aCommand, "delete" ) ) {
689+
690+ sal_Bool bDeletePhysical = sal_False;
691+ aCommand.Argument >>= bDeletePhysical;
692+
693+ ::rtl::OString aURI = getOURI();
694+ GnomeVFSResult result = gnome_vfs_unlink ((const sal_Char *) aURI);
695+
696+ if (result != GNOME_VFS_OK)
697+ cancelCommandExecution( result, xEnv, sal_True );
698+
699+ destroy( bDeletePhysical );
700+
701+ } else if ( COMMAND_IS( aCommand, "transfer" ) && isFolder( xEnv ) ) {
702+ star::ucb::TransferInfo transferArgs;
703+
704+ if ( !( aCommand.Argument >>= transferArgs ) )
705+ ucbhelper::cancelCommandExecution( getBadArgExcept(), xEnv );
706+
707+ transfer( transferArgs, xEnv );
708+
709+ } else { // Unsuported
710+#ifdef DEBUG
711+ g_warning( "Unsupported command: '%s'",
712+ OUStringToGnome( aCommand.Name ) );
713+#endif
714+ ucbhelper::cancelCommandExecution
715+ ( uno::makeAny( star::ucb::UnsupportedCommandException
716+ ( rtl::OUString(),
717+ static_cast< cppu::OWeakObject * >( this ) ) ),
718+ xEnv );
719+ }
720+#undef COMMAND_IS
721+
722+ return aRet;
723+}
724+
725+void SAL_CALL Content::abort( sal_Int32 CommandId )
726+ throw( uno::RuntimeException )
727+{
728+ // FIXME: we should use the GnomeVFSCancellation APIs here ...
729+}
730+
731+//
732+// XContentCreator methods.
733+//
734+
735+uno::Sequence< star::ucb::ContentInfo > SAL_CALL
736+Content::queryCreatableContentsInfo()
737+ throw( uno::RuntimeException )
738+{
739+ uno::Sequence< star::ucb::ContentInfo > seq(2);
740+
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" ),
745+ -1,
746+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
747+ beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
748+
749+ // file
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;
754+
755+ // folder
756+ seq[1].Type = rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
757+ seq[1].Attributes = star::ucb::ContentInfoAttribute::KIND_FOLDER;
758+ seq[1].Properties = props;
759+
760+ return seq;
761+}
762+
763+uno::Reference< star::ucb::XContent > SAL_CALL
764+Content::createNewContent( const star::ucb::ContentInfo& Info )
765+ throw( uno::RuntimeException )
766+{
767+ bool create_document;
768+ const char *name;
769+
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;
774+ else {
775+#ifdef DEBUG
776+ g_warning( "Failed to create new content '%s'",
777+ OUStringToGnome( Info.Type ) );
778+#endif
779+ return uno::Reference< star::ucb::XContent >();
780+ }
781+
782+#ifdef DEBUG
783+ g_warning( "createNewContent (%d)", (int) create_document );
784+#endif
785+
786+ rtl::OUString aURL = getOUURI();
787+
788+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
789+ aURL += rtl::OUString::createFromAscii( "/" );
790+
791+ name = create_document ? "[New_Content]" : "[New_Collection]";
792+ // This looks problematic to me cf. webdav
793+ aURL += rtl::OUString::createFromAscii( name );
794+
795+ uno::Reference< star::ucb::XContentIdentifier > xId
796+ ( new ::ucb::ContentIdentifier( m_xSMgr, aURL ) );
797+
798+ try {
799+ return new ::gvfs::Content( m_xSMgr, m_pProvider, xId, !create_document );
800+ } catch ( star::ucb::ContentCreationException & ) {
801+ return uno::Reference< star::ucb::XContent >();
802+ }
803+}
804+
805+rtl::OUString Content::getParentURL()
806+{
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/
814+
815+ rtl::OUString aURL = getOUURI();
816+
817+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
818+ if ( nPos == ( aURL.getLength() - 1 ) ) {
819+ // Trailing slash found. Skip.
820+ nPos = aURL.lastIndexOf( '/', nPos );
821+ }
822+
823+ sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
824+ if ( nPos1 != -1 )
825+ nPos1 = aURL.lastIndexOf( '/', nPos1 );
826+
827+ if ( nPos1 != -1 )
828+ aParentURL = rtl::OUString( aURL.copy( 0, nPos + 1 ) );
829+
830+#ifdef DEBUG
831+ g_warning ("getParentURL '%s' -> '%s'",
832+ getURI(), (const sal_Char *) rtl::OUStringToOString
833+ ( aParentURL, RTL_TEXTENCODING_UTF8 ) );
834+#endif
835+
836+ return aParentURL;
837+}
838+
839+static util::DateTime
840+getDateFromUnix (time_t t)
841+{
842+ static const Date epochStart( 1,1,1970 );
843+
844+ ::DateTime tmp;
845+ tmp.MakeDateTimeFromSec( epochStart, ((long unsigned int) t) );
846+
847+ return util::DateTime( 0, tmp.GetSec(), tmp.GetMin(), tmp.GetHour(),
848+ tmp.GetDay(), tmp.GetMonth (), tmp.GetYear ());
849+}
850+
851+uno::Reference< sdbc::XRow > Content::getPropertyValues(
852+ const uno::Sequence< beans::Property >& rProperties,
853+ const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
854+{
855+ int nProps;
856+ GnomeVFSResult result;
857+ uno::Sequence< beans::Property > allProperties;
858+
859+ if( ( result = getInfo( xEnv ) ) != GNOME_VFS_OK )
860+ cancelCommandExecution( result, xEnv, sal_False );
861+
862+ const beans::Property* pProps;
863+
864+ if( rProperties.getLength() ) {
865+ nProps = rProperties.getLength();
866+ pProps = rProperties.getConstArray();
867+ } else {
868+ allProperties = getPropertySetInfo( xEnv )->getProperties();
869+ nProps = allProperties.getLength();
870+ pProps = allProperties.getConstArray();
871+ }
872+
873+ rtl::Reference< ::ucb::PropertyValueSet > xRow
874+ = new ::ucb::PropertyValueSet( m_xSMgr );
875+
876+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
877+ for( sal_Int32 n = 0; n < nProps; ++n ) {
878+ const beans::Property& rProp = pProps[ n ];
879+
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 ) );
885+ }
886+
887+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
888+ xRow->appendString( rProp, getContentType () );
889+
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 ) );
894+ else
895+ xRow->appendVoid( rProp );
896+ }
897+
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 ) );
901+ else
902+ xRow->appendVoid( rProp );
903+ }
904+
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 );
908+ else
909+ xRow->appendVoid( rProp );
910+ }
911+
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;
915+
916+ if (m_info.uid == getuid () &&
917+ m_info.permissions & GNOME_VFS_PERM_USER_WRITE)
918+ read_only = false;
919+ else if (m_info.gid == getgid () &&
920+ m_info.permissions & GNOME_VFS_PERM_GROUP_WRITE)
921+ read_only = false;
922+ else if (m_info.permissions & GNOME_VFS_PERM_OTHER_WRITE)
923+ read_only = false;
924+ xRow->appendBoolean( rProp, read_only );
925+ } else
926+ xRow->appendVoid( rProp );
927+ }
928+
929+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
930+ xRow->appendBoolean( rProp, ( m_info.name && m_info.name[0] == '.' ) );
931+
932+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) ||
933+ rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisk" ) ) )
934+ xRow->appendBoolean( rProp, sal_False );
935+
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 ) );
939+ else
940+ xRow->appendVoid( rProp );
941+ }
942+
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 ) );
946+ else
947+ xRow->appendVoid( rProp );
948+ }
949+
950+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) {
951+ // We do this by sniffing in gnome-vfs; rather expensively.
952+#ifdef DEBUG
953+ g_warning ("FIXME: Requested mime-type - an expensive op. indeed!");
954+#endif
955+ xRow->appendVoid( rProp );
956+ } else {
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 );
962+ }
963+ }
964+#ifdef DEBUG
965+ g_warning ("getPropertyValues on '%s' %d properties returned (of %d)",
966+ getURI(), (int)xRow->getLength(), (int)nProps);
967+#endif
968+
969+ return uno::Reference< sdbc::XRow >( xRow.get() );
970+}
971+
972+static lang::IllegalAccessException
973+getReadOnlyException( Content *ctnt )
974+{
975+ return lang::IllegalAccessException
976+ ( rtl::OUString::createFromAscii( "Property is read-only!" ),
977+ static_cast< cppu::OWeakObject * >( ctnt ) );
978+}
979+
980+rtl::OUString
981+Content::makeNewURL( const char *newName )
982+{
983+ rtl::OUString aNewURL = getParentURL();
984+ if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
985+ aNewURL += rtl::OUString::createFromAscii( "/" );
986+
987+ char *name = gnome_vfs_escape_string( m_info.name );
988+ aNewURL += GnomeToOUString( name );
989+ g_free( name );
990+
991+ return aNewURL;
992+}
993+
994+// This is slightly complicated by needing to support either 'move' or 'setname'
995+GnomeVFSResult
996+Content::doSetFileInfo( const GnomeVFSFileInfo *newInfo,
997+ GnomeVFSSetFileInfoMask setMask,
998+ const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
999+{
1000+ GnomeVFSResult result = GNOME_VFS_OK;
1001+
1002+ g_assert (!m_bTransient);
1003+
1004+ ::rtl::OString aURI = getOURI();
1005+
1006+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1007+
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 );
1012+
1013+ if ( result == GNOME_VFS_ERROR_NOT_SUPPORTED &&
1014+ ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) ) {
1015+ // Try a move instead
1016+#ifdef DEBUG
1017+ g_warning( "SetFileInfo not supported on '%s'", getURI() );
1018+#endif
1019+
1020+ char *newURI = OUStringToGnome( makeNewURL( newInfo->name ) );
1021+
1022+ result = gnome_vfs_move ((const sal_Char *)aURI, newURI, FALSE);
1023+
1024+ g_free (newURI);
1025+ }
1026+
1027+ return result;
1028+}
1029+
1030+
1031+uno::Sequence< uno::Any > Content::setPropertyValues(
1032+ const uno::Sequence< beans::PropertyValue >& rValues,
1033+ const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1034+{
1035+ rtl::OUString aNewTitle;
1036+ GnomeVFSFileInfo newInfo;
1037+ int setMask = GNOME_VFS_SET_FILE_INFO_NONE;
1038+
1039+ getInfo( xEnv );
1040+
1041+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1042+
1043+ gnome_vfs_file_info_copy( &newInfo, &m_info );
1044+
1045+ Authentication aAuth( xEnv );
1046+
1047+ int nChanged = 0, nTitlePos = 0;
1048+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
1049+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1050+
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 =
1058+
1059+ int nCount = rValues.getLength();
1060+ const beans::PropertyValue* pValues = rValues.getConstArray();
1061+
1062+ for ( sal_Int32 n = 0; n < nCount; ++n ) {
1063+ const beans::PropertyValue& rValue = pValues[ n ];
1064+
1065+#ifdef DEBUG
1066+ g_warning( "Set prop '%s'", OUStringToGnome( rValue.Name ) );
1067+#endif
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 );
1074+
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 );
1081+ else {
1082+ char *newName = OUStringToGnome( aNewTitle );
1083+
1084+ if( !newName || !m_info.name || strcmp( newName, m_info.name ) ) {
1085+#ifdef DEBUG
1086+ g_warning ("Set new name to '%s'", newName);
1087+#endif
1088+
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++;
1094+
1095+ newInfo.name = newName;
1096+ setMask |= GNOME_VFS_SET_FILE_INFO_NAME;
1097+ } else // same name
1098+ g_free (newName);
1099+ }
1100+ } else
1101+ aRet[ n ] <<= beans::IllegalTypeException
1102+ ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
1103+ static_cast< cppu::OWeakObject * >( this ) );
1104+
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 );
1109+ } else {
1110+#ifdef DEBUG
1111+ g_warning( "Unhandled property '%s'", OUStringToGnome( rValue.Name ) );
1112+#endif
1113+ aRet[ n ] <<= getReadOnlyException( this );
1114+ }
1115+ }
1116+
1117+ GnomeVFSResult result = GNOME_VFS_OK;
1118+
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 );
1125+
1126+ }
1127+
1128+ if ( result == GNOME_VFS_OK) {
1129+ gnome_vfs_file_info_copy( &m_info, &newInfo );
1130+
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 ) );
1134+
1135+ aGuard.clear();
1136+ if (!exchangeIdentity( xNewId ) )
1137+ aRet[ nTitlePos ] <<= uno::Exception
1138+ ( rtl::OUString::createFromAscii( "Exchange failed!" ),
1139+ static_cast< cppu::OWeakObject * >( this ) );
1140+ }
1141+ }
1142+
1143+ gnome_vfs_file_info_clear( &newInfo );
1144+
1145+ if ( nChanged > 0 ) {
1146+ aGuard.clear();
1147+ aChanges.realloc( nChanged );
1148+ notifyPropertiesChange( aChanges );
1149+ }
1150+
1151+ return aRet;
1152+}
1153+
1154+void Content::queryChildren( ContentRefList& rChildren )
1155+{
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.
1159+
1160+ ::ucb::ContentRefList aAllContents;
1161+ m_xProvider->queryExistingContents( aAllContents );
1162+
1163+ rtl::OUString aURL = getOUURI();
1164+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
1165+
1166+ if ( nPos != ( aURL.getLength() - 1 ) )
1167+ aURL += rtl::OUString::createFromAscii( "/" );
1168+
1169+ sal_Int32 nLen = aURL.getLength();
1170+
1171+ ::ucb::ContentRefList::const_iterator it = aAllContents.begin();
1172+ ::ucb::ContentRefList::const_iterator end = aAllContents.end();
1173+
1174+ while ( it != end ) {
1175+ ::ucb::ContentImplHelperRef xChild = (*it);
1176+ rtl::OUString aChildURL
1177+ = xChild->getIdentifier()->getContentIdentifier();
1178+
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 );
1184+
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() ) ) );
1190+ }
1191+ }
1192+ ++it;
1193+ }
1194+}
1195+
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 )
1201+{
1202+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1203+
1204+#ifdef DEBUG
1205+ g_warning( "Insert '%s' (%d) (0x%x:%d)", getURI(), bReplaceExisting,
1206+ m_info.valid_fields, m_info.type );
1207+#endif
1208+
1209+ GnomeVFSResult result = getInfo( xEnv );
1210+ // a racy design indeed.
1211+ if( !bReplaceExisting && !m_bTransient &&
1212+ result != GNOME_VFS_ERROR_NOT_FOUND) {
1213+#ifdef DEBUG
1214+ g_warning ("Nasty error inserting to '%s' ('%s')",
1215+ getURI(), gnome_vfs_result_to_string( result ));
1216+#endif
1217+ cancelCommandExecution( GNOME_VFS_ERROR_FILE_EXISTS, xEnv, sal_True );
1218+ }
1219+
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();
1223+ int perm;
1224+
1225+ perm = ( GNOME_VFS_PERM_USER_ALL |
1226+ GNOME_VFS_PERM_GROUP_READ |
1227+ GNOME_VFS_PERM_OTHER_READ );
1228+
1229+#ifdef DEBUG
1230+ g_warning ("Make directory");
1231+#endif
1232+ result = gnome_vfs_make_directory( (const sal_Char *) aURI, perm );
1233+
1234+ if( result != GNOME_VFS_OK )
1235+ cancelCommandExecution( result, xEnv, sal_True );
1236+
1237+ return;
1238+ }
1239+
1240+ if ( !xInputStream.is() ) {
1241+ // FIXME: slightly unclear whether to accept this and create an empty file
1242+ ucbhelper::cancelCommandExecution
1243+ ( uno::makeAny
1244+ ( star::ucb::MissingInputStreamException
1245+ ( rtl::OUString(),
1246+ static_cast< cppu::OWeakObject * >( this ) ) ),
1247+ xEnv );
1248+ }
1249+
1250+ GnomeVFSHandle *handle = NULL;
1251+ ::rtl::OString aURI = getOURI();
1252+
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 );
1258+ }
1259+
1260+ if ( result != GNOME_VFS_OK ) {
1261+ int perm;
1262+ Authentication aAuth( xEnv );
1263+
1264+ perm = ( ( GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ ) |
1265+ ( GNOME_VFS_PERM_GROUP_WRITE | GNOME_VFS_PERM_GROUP_READ ) );
1266+
1267+ result = gnome_vfs_create
1268+ ( &handle, (const sal_Char *)aURI, GNOME_VFS_OPEN_WRITE, TRUE, perm );
1269+ }
1270+
1271+ if( result != GNOME_VFS_OK )
1272+ cancelCommandExecution( result, xEnv, sal_True );
1273+
1274+ if ( !xInputStream.is() ) {
1275+ result = gnome_vfs_close( handle );
1276+ if (result != GNOME_VFS_OK)
1277+ cancelCommandExecution( result, xEnv, sal_True );
1278+
1279+ } else { // copy it over
1280+ uno::Reference < io::XOutputStream > xOutput =
1281+ new gvfs::Stream( handle, &m_info );
1282+
1283+ copyData( xInputStream, xOutput );
1284+ }
1285+
1286+ if (m_bTransient) {
1287+ m_bTransient = sal_False;
1288+ aGuard.clear();
1289+ inserted();
1290+ }
1291+}
1292+
1293+void Content::transfer(const star::ucb::TransferInfo & rArgs,
1294+ const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1295+ throw( uno::Exception )
1296+{
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
1300+ ( uno::makeAny
1301+ ( star::ucb::InteractiveBadTransferURLException
1302+ ( rtl::OUString::createFromAscii( "Unsupported URL scheme!" ),
1303+ static_cast< cppu::OWeakObject * >( this ) ) ),
1304+ xEnv );
1305+}
1306+
1307+void Content::destroy( sal_Bool bDeletePhysical )
1308+ throw( uno::Exception )
1309+{
1310+ // @@@ take care about bDeletePhysical -> trashcan support
1311+ rtl::OUString aURL = getOUURI();
1312+
1313+ uno::Reference< star::ucb::XContent > xThis = this;
1314+
1315+ deleted();
1316+
1317+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1318+
1319+ // Process instanciated children...
1320+ ::gvfs::Content::ContentRefList aChildren;
1321+ queryChildren( aChildren );
1322+
1323+ ContentRefList::const_iterator it = aChildren.begin();
1324+ ContentRefList::const_iterator end = aChildren.end();
1325+
1326+ while ( it != end ) {
1327+ (*it)->destroy( bDeletePhysical );
1328+ ++it;
1329+ }
1330+}
1331+
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 )
1336+{
1337+ if ( !xNewId.is() )
1338+ return sal_False;
1339+
1340+ uno::Reference< star::ucb::XContent > xThis = this;
1341+
1342+#ifdef DEBUG
1343+ g_warning( "exchangeIdentity from '%s' to '%s'",
1344+ getURI(), OUStringToGnome( xNewId->getContentIdentifier() ) );
1345+#endif
1346+
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;
1352+ return sal_False;
1353+ }
1354+
1355+ rtl::OUString aOldURL = getOUURI();
1356+
1357+ // Exchange own identitity.
1358+ if ( exchange( xNewId ) ) {
1359+
1360+ // Process instanciated children...
1361+ ContentRefList aChildren;
1362+ queryChildren( aChildren );
1363+
1364+ ContentRefList::const_iterator it = aChildren.begin();
1365+ ContentRefList::const_iterator end = aChildren.end();
1366+
1367+ while ( it != end ) {
1368+ ContentRef xChild = (*it);
1369+
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(
1377+ 0,
1378+ aOldURL.getLength(),
1379+ xNewId->getContentIdentifier() );
1380+ uno::Reference< star::ucb::XContentIdentifier >
1381+ xNewChildId
1382+ = new ::ucb::ContentIdentifier( m_xSMgr, aNewChildURL );
1383+
1384+ if ( !xChild->exchangeIdentity( xNewChildId ) )
1385+ return sal_False;
1386+
1387+ ++it;
1388+ }
1389+ return sal_True;
1390+ }
1391+
1392+ return sal_False;
1393+}
1394+
1395+GnomeVFSResult
1396+Content::getInfo( const ::com::sun::star::uno::Reference<
1397+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
1398+{
1399+ GnomeVFSResult result;
1400+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1401+
1402+ if (m_bTransient)
1403+ result = GNOME_VFS_OK;
1404+
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 );
1412+ } else
1413+ result = GNOME_VFS_OK;
1414+#ifdef DEBUG
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 );
1418+#endif
1419+ return result;
1420+}
1421+
1422+sal_Bool
1423+Content::isFolder(const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1424+{
1425+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1426+ getInfo( xEnv );
1427+ return (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
1428+ m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY);
1429+}
1430+
1431+uno::Any Content::mapVFSException( const GnomeVFSResult result, sal_Bool bWrite )
1432+{
1433+ uno::Any aException;
1434+ const char *gvfs_message;
1435+ rtl::OUString message;
1436+ uno::Sequence< uno::Any > aArgs( 1 );
1437+
1438+#ifdef DEBUG
1439+ g_warning ("Map VFS exception '%s' (%d)",
1440+ gnome_vfs_result_to_string( result ), result );
1441+#endif
1442+
1443+ if ((gvfs_message = gnome_vfs_result_to_string (result)))
1444+ message = GnomeToOUString( gvfs_message );
1445+
1446+ switch (result) {
1447+ case GNOME_VFS_OK:
1448+ g_error ("VFS_OK mapped to exception.");
1449+ break;
1450+ case GNOME_VFS_ERROR_EOF:
1451+ g_warning ("VFS_EOF not handled somewhere.");
1452+ break;
1453+ case GNOME_VFS_ERROR_NOT_FOUND:
1454+ aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
1455+ aException <<=
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,
1461+ aArgs );
1462+ break;
1463+ case GNOME_VFS_ERROR_BAD_PARAMETERS:
1464+ aException <<=
1465+ lang::IllegalArgumentException
1466+ ( rtl::OUString(),
1467+ static_cast< cppu::OWeakObject * >( this ),
1468+ -1 );
1469+ break;
1470+ case GNOME_VFS_ERROR_GENERIC:
1471+ case GNOME_VFS_ERROR_INTERNAL:
1472+ case GNOME_VFS_ERROR_NOT_SUPPORTED:
1473+#ifdef DEBUG
1474+ g_warning ("Internal - un-mapped error");
1475+#endif
1476+ aException <<= io::IOException();
1477+ break;
1478+ case GNOME_VFS_ERROR_IO:
1479+ if ( bWrite )
1480+ aException <<=
1481+ star::ucb::InteractiveNetworkWriteException
1482+ ( rtl::OUString(),
1483+ static_cast< cppu::OWeakObject * >( this ),
1484+ task::InteractionClassification_ERROR,
1485+ message );
1486+ else
1487+ aException <<=
1488+ star::ucb::InteractiveNetworkReadException
1489+ ( rtl::OUString(),
1490+ static_cast< cppu::OWeakObject * >( this ),
1491+ task::InteractionClassification_ERROR,
1492+ message );
1493+ break;
1494+ case GNOME_VFS_ERROR_HOST_NOT_FOUND:
1495+ case GNOME_VFS_ERROR_INVALID_HOST_NAME:
1496+ aException <<=
1497+ star::ucb::InteractiveNetworkResolveNameException
1498+ ( rtl::OUString(),
1499+ static_cast< cppu::OWeakObject * >( this ),
1500+ task::InteractionClassification_ERROR,
1501+ message );
1502+ break;
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:
1507+ aException <<=
1508+ star::ucb::InteractiveNetworkConnectException
1509+ ( rtl::OUString(),
1510+ static_cast< cppu::OWeakObject * >( this ),
1511+ task::InteractionClassification_ERROR,
1512+ message );
1513+ break;
1514+
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,
1520+ message );
1521+ break;
1522+
1523+ case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
1524+ aException <<= star::ucb::UnsupportedOpenModeException();
1525+ break;
1526+
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:
1553+#ifdef DEBUG
1554+ g_warning( "FIXME: Un-mapped VFS exception '%s' (%d)",
1555+ gnome_vfs_result_to_string( result ), result );
1556+#endif
1557+ default:
1558+ aException <<= star::ucb::InteractiveNetworkGeneralException
1559+ ( rtl::OUString(),
1560+ static_cast< cppu::OWeakObject * >( this ),
1561+ task::InteractionClassification_ERROR );
1562+ break;
1563+ }
1564+
1565+ return aException;
1566+}
1567+
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 )
1573+{
1574+ ucbhelper::cancelCommandExecution( mapVFSException( result, bWrite ), xEnv );
1575+ // Unreachable
1576+}
1577+
1578+uno::Sequence< beans::Property > Content::getProperties(
1579+ const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
1580+{
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 ),
1594+ // Optional ...
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 )
1620+ };
1621+
1622+ const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
1623+
1624+ return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
1625+
1626+}
1627+
1628+uno::Sequence< com::sun::star::ucb::CommandInfo > Content::getCommands(
1629+ const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
1630+{
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 ) ) ),
1645+
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 ) ) ),
1656+
1657+ // Folder only
1658+ com::sun::star::ucb::CommandInfo
1659+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
1660+ -1, getCppuType( static_cast<com::sun::star::ucb::TransferInfo * >( 0 ) ) )
1661+ };
1662+ int num = 7;
1663+
1664+ if ( isFolder( xEnv ) )
1665+ num += 1;
1666+
1667+ return uno::Sequence< com::sun::star::ucb::CommandInfo >(aDocumentCommandInfoTable, num );
1668+}
1669+
1670+rtl::OUString
1671+Content::getOUURI ()
1672+{
1673+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1674+ return m_xIdentifier->getContentIdentifier();
1675+}
1676+
1677+rtl::OString
1678+Content::getOURI ()
1679+{
1680+ return rtl::OUStringToOString( getOUURI(), RTL_TEXTENCODING_UTF8 );
1681+}
1682+
1683+char *
1684+Content::getURI ()
1685+{
1686+ return OUStringToGnome( getOUURI() );
1687+}
1688+
1689+void
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 )
1694+{
1695+ uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
1696+
1697+ g_return_if_fail( xIn.is() && xOut.is() );
1698+
1699+ while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
1700+ xOut->writeBytes( theData );
1701+
1702+ xOut->closeOutput();
1703+}
1704+
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 )
1710+{
1711+ GnomeVFSResult result;
1712+ GnomeVFSHandle *handle = NULL;
1713+ ::rtl::OString aURI = getOURI();
1714+
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 );
1721+
1722+ if ( !xTempOut.is() )
1723+ cancelCommandExecution( GNOME_VFS_ERROR_IO, xEnv );
1724+
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 );
1729+
1730+ uno::Reference < io::XInputStream > pStream = new ::gvfs::Stream( handle, &m_info );
1731+ copyData( pStream, xTempOut );
1732+
1733+ return uno::Reference < io::XInputStream > ( xTempOut, uno::UNO_QUERY );
1734+}
1735+
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 )
1740+{
1741+ GnomeVFSHandle *handle = NULL;
1742+ GnomeVFSResult result;
1743+ uno::Reference<io::XInputStream > xIn;
1744+
1745+ Authentication aAuth( xEnv );
1746+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
1747+
1748+ getInfo( xEnv );
1749+ ::rtl::OString aURI = getOURI();
1750+
1751+ if ( !(m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) )
1752+ return createTempStream( xEnv );
1753+
1754+ result = gnome_vfs_open
1755+ ( &handle, (const sal_Char *)aURI,
1756+ (GnomeVFSOpenMode) (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM ) );
1757+
1758+ if (result == GNOME_VFS_ERROR_INVALID_OPEN_MODE ||
1759+ result == GNOME_VFS_ERROR_NOT_SUPPORTED)
1760+ return createTempStream( xEnv );
1761+
1762+ if (result != GNOME_VFS_OK)
1763+ cancelCommandExecution( result, xEnv );
1764+
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 );
1770+ }
1771+
1772+ if (result != GNOME_VFS_OK)
1773+ cancelCommandExecution( result, xEnv );
1774+
1775+ if (handle != NULL)
1776+ xIn = new ::gvfs::Stream( handle, &m_info );
1777+
1778+ return xIn;
1779+}
1780+
1781+sal_Bool
1782+Content::feedSink( uno::Reference< ::com::sun::star::uno::XInterface > aSink,
1783+ const uno::Reference< star::ucb::XCommandEnvironment >& xEnv )
1784+{
1785+ if ( !aSink.is() )
1786+ return sal_False;
1787+
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 );
1792+
1793+ if ( !xOut.is() && !xDataSink.is() )
1794+ return sal_False;
1795+
1796+ uno::Reference< io::XInputStream > xIn = createInputStream( xEnv );
1797+ if ( !xIn.is() )
1798+ return sal_False;
1799+
1800+ if ( xOut.is() )
1801+ copyData( xIn, xOut );
1802+
1803+ if ( xDataSink.is() )
1804+ xDataSink->setInputStream( xIn );
1805+
1806+ return sal_True;
1807+}
1808+
1809+extern "C" {
1810+ static void
1811+ vfs_authentication_callback (gconstpointer in_void,
1812+ gsize in_size,
1813+ gpointer out_void,
1814+ gsize out_size,
1815+ gpointer callback_data)
1816+ {
1817+ task::XInteractionHandler *xIH;
1818+
1819+#ifdef DEBUG
1820+ g_warning ("Authentication callback (%p)...", callback_data);
1821+#endif
1822+
1823+ if( !( xIH = (task::XInteractionHandler *) callback_data ) )
1824+ return;
1825+
1826+ const GnomeVFSModuleCallbackAuthenticationIn *in =
1827+ (const GnomeVFSModuleCallbackAuthenticationIn *) in_void;
1828+ GnomeVFSModuleCallbackAuthenticationOut *out =
1829+ (GnomeVFSModuleCallbackAuthenticationOut *) out_void;
1830+
1831+ g_return_if_fail (in != NULL && out != NULL);
1832+ g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size &&
1833+ sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
1834+
1835+
1836+ ::rtl::OUString inHostName, inRealm;
1837+ ::rtl::OUString aUserName, aPassword;
1838+
1839+ if( in->uri ) {
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);
1851+ }
1852+ if( in->realm )
1853+ inRealm = rtl::OUString::createFromAscii( in->realm );
1854+
1855+ rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
1856+ = new ucbhelper::SimpleAuthenticationRequest
1857+ ( inHostName, inRealm, rtl::OUString(), rtl::OUString() );
1858+
1859+ xIH->handle( xRequest.get() );
1860+
1861+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
1862+ = xRequest->getSelection();
1863+
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();
1871+
1872+ aUserName = xSupp->getUserName();
1873+ aPassword = xSupp->getPassword();
1874+
1875+ out->username = OUStringToGnome( aUserName );
1876+ out->password = OUStringToGnome( aPassword );
1877+#ifdef DEBUG
1878+ g_warning ("Got valid user/password '%s' '%s'",
1879+ out->username, out->password);
1880+#endif
1881+ }
1882+ }
1883+ }
1884+
1885+ static void
1886+ auth_destroy (gpointer data)
1887+ {
1888+ task::XInteractionHandler *xIH;
1889+ if( ( xIH = ( task::XInteractionHandler * )data ) )
1890+ xIH->release();
1891+ }
1892+
1893+ // This sucks, but gnome-vfs doesn't much like
1894+ // repeated set / unsets - so we have to compensate.
1895+ GPrivate *auth_queue = NULL;
1896+
1897+ void auth_queue_destroy( gpointer data )
1898+ {
1899+ GList *l;
1900+ GQueue *vq = (GQueue *) data;
1901+
1902+ for (l = vq->head; l; l = l->next)
1903+ auth_destroy (l->data);
1904+ g_queue_free (vq);
1905+ }
1906+};
1907+
1908+static void
1909+refresh_auth( GQueue *vq )
1910+{
1911+ GList *l;
1912+
1913+ gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION );
1914+
1915+ for (l = vq->head; l; l = l->next) {
1916+ if (l->data) {
1917+ gnome_vfs_module_callback_push
1918+ ( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
1919+ vfs_authentication_callback, l->data, NULL );
1920+ break;
1921+ }
1922+ }
1923+}
1924+
1925+gvfs::Authentication::Authentication(const com::sun::star::uno::Reference<
1926+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
1927+{
1928+ GQueue *vq;
1929+ uno::Reference< task::XInteractionHandler > xIH;
1930+
1931+ if ( xEnv.is() )
1932+ xIH = xEnv->getInteractionHandler();
1933+
1934+ if ( xIH.is() )
1935+ xIH->acquire();
1936+
1937+ if( !(vq = (GQueue *)g_private_get( auth_queue ) ) ) {
1938+ vq = g_queue_new();
1939+ g_private_set( auth_queue, vq );
1940+ }
1941+
1942+ g_queue_push_head( vq, (gpointer) xIH.get() );
1943+ refresh_auth( vq );
1944+}
1945+
1946+gvfs::Authentication::~Authentication()
1947+{
1948+ GQueue *vq;
1949+ gpointer data;
1950+
1951+ vq = (GQueue *)g_private_get( auth_queue );
1952+
1953+ data = g_queue_pop_head( vq );
1954+ auth_destroy (data);
1955+
1956+ refresh_auth( vq );
1957+}
This page took 0.354936 seconds and 4 git commands to generate.