]> git.pld-linux.org Git - packages/libreoffice.git/blob - openoffice-vfs-content.patch
- up
[packages/libreoffice.git] / openoffice-vfs-content.patch
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.247705 seconds and 3 git commands to generate.