summaryrefslogtreecommitdiff
path: root/ucb/source
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source')
-rw-r--r--ucb/source/cacher/cached.xml146
-rw-r--r--ucb/source/cacher/cachedcontentresultset.cxx2229
-rw-r--r--ucb/source/cacher/cachedcontentresultset.hxx521
-rw-r--r--ucb/source/cacher/cachedcontentresultsetstub.cxx631
-rw-r--r--ucb/source/cacher/cachedcontentresultsetstub.hxx202
-rw-r--r--ucb/source/cacher/cacheddynamicresultset.cxx206
-rw-r--r--ucb/source/cacher/cacheddynamicresultset.hxx137
-rw-r--r--ucb/source/cacher/cacheddynamicresultsetstub.cxx245
-rw-r--r--ucb/source/cacher/cacheddynamicresultsetstub.hxx136
-rw-r--r--ucb/source/cacher/cacheserv.cxx187
-rw-r--r--ucb/source/cacher/contentresultsetwrapper.cxx1477
-rw-r--r--ucb/source/cacher/contentresultsetwrapper.hxx587
-rw-r--r--ucb/source/cacher/dynamicresultsetwrapper.cxx528
-rw-r--r--ucb/source/cacher/dynamicresultsetwrapper.hxx229
-rw-r--r--ucb/source/cacher/makefile.mk68
-rw-r--r--ucb/source/core/cmdenv.cxx191
-rw-r--r--ucb/source/core/cmdenv.hxx102
-rw-r--r--ucb/source/core/exports2.dxp5
-rw-r--r--ucb/source/core/identify.cxx116
-rw-r--r--ucb/source/core/identify.hxx68
-rw-r--r--ucb/source/core/makefile.mk76
-rw-r--r--ucb/source/core/providermap.hxx77
-rw-r--r--ucb/source/core/provprox.cxx401
-rw-r--r--ucb/source/core/provprox.hxx166
-rw-r--r--ucb/source/core/ucb.cxx956
-rw-r--r--ucb/source/core/ucb.hxx226
-rw-r--r--ucb/source/core/ucb.xml172
-rw-r--r--ucb/source/core/ucbcmds.cxx2090
-rw-r--r--ucb/source/core/ucbcmds.hxx43
-rw-r--r--ucb/source/core/ucbprops.cxx477
-rw-r--r--ucb/source/core/ucbprops.hxx93
-rw-r--r--ucb/source/core/ucbserv.cxx208
-rw-r--r--ucb/source/core/ucbstore.cxx2793
-rw-r--r--ucb/source/core/ucbstore.hxx347
-rw-r--r--ucb/source/inc/regexp.hxx84
-rw-r--r--ucb/source/inc/regexpmap.hxx188
-rw-r--r--ucb/source/inc/regexpmap.tpt564
-rw-r--r--ucb/source/regexp/makefile.mk41
-rw-r--r--ucb/source/regexp/regexp.cxx473
-rw-r--r--ucb/source/sorter/makefile.mk63
-rw-r--r--ucb/source/sorter/sortdynres.cxx628
-rw-r--r--ucb/source/sorter/sortdynres.hxx257
-rw-r--r--ucb/source/sorter/sortmain.cxx130
-rw-r--r--ucb/source/sorter/sortresult.cxx2070
-rw-r--r--ucb/source/sorter/sortresult.hxx455
-rw-r--r--ucb/source/sorter/srtrs.xml66
-rw-r--r--ucb/source/ucp/expand/makefile.mk61
-rw-r--r--ucb/source/ucp/expand/ucpexpand.cxx293
-rw-r--r--ucb/source/ucp/file/bc.cxx1409
-rw-r--r--ucb/source/ucp/file/bc.hxx353
-rw-r--r--ucb/source/ucp/file/exports2.dxp9
-rw-r--r--ucb/source/ucp/file/filcmd.cxx141
-rw-r--r--ucb/source/ucp/file/filcmd.hxx108
-rw-r--r--ucb/source/ucp/file/filerror.hxx118
-rw-r--r--ucb/source/ucp/file/filglob.cxx954
-rw-r--r--ucb/source/ucp/file/filglob.hxx119
-rw-r--r--ucb/source/ucp/file/filid.cxx148
-rw-r--r--ucb/source/ucp/file/filid.hxx102
-rw-r--r--ucb/source/ucp/file/filinl.hxx76
-rw-r--r--ucb/source/ucp/file/filinpstr.cxx262
-rw-r--r--ucb/source/ucp/file/filinpstr.hxx164
-rw-r--r--ucb/source/ucp/file/filinsreq.cxx224
-rw-r--r--ucb/source/ucp/file/filinsreq.hxx240
-rw-r--r--ucb/source/ucp/file/filnot.cxx269
-rw-r--r--ucb/source/ucp/file/filnot.hxx137
-rw-r--r--ucb/source/ucp/file/filprp.cxx151
-rw-r--r--ucb/source/ucp/file/filprp.hxx97
-rw-r--r--ucb/source/ucp/file/filrec.cxx201
-rw-r--r--ucb/source/ucp/file/filrec.hxx86
-rw-r--r--ucb/source/ucp/file/filrow.cxx429
-rw-r--r--ucb/source/ucp/file/filrow.hxx204
-rw-r--r--ucb/source/ucp/file/filrset.cxx936
-rw-r--r--ucb/source/ucp/file/filrset.hxx683
-rw-r--r--ucb/source/ucp/file/filstr.cxx404
-rw-r--r--ucb/source/ucp/file/filstr.hxx246
-rw-r--r--ucb/source/ucp/file/filtask.cxx184
-rw-r--r--ucb/source/ucp/file/filtask.hxx225
-rw-r--r--ucb/source/ucp/file/makefile.mk80
-rw-r--r--ucb/source/ucp/file/prov.cxx738
-rw-r--r--ucb/source/ucp/file/prov.hxx238
-rw-r--r--ucb/source/ucp/file/shell.cxx3068
-rw-r--r--ucb/source/ucp/file/shell.hxx607
-rw-r--r--ucb/source/ucp/file/ucpfile.xml113
-rw-r--r--ucb/source/ucp/ftp/curl.hxx41
-rw-r--r--ucb/source/ucp/ftp/ftpcfunc.cxx56
-rw-r--r--ucb/source/ucp/ftp/ftpcfunc.hxx63
-rw-r--r--ucb/source/ucp/ftp/ftpcontainer.hxx61
-rw-r--r--ucb/source/ucp/ftp/ftpcontent.cxx957
-rw-r--r--ucb/source/ucp/ftp/ftpcontent.hxx183
-rw-r--r--ucb/source/ucp/ftp/ftpcontentcaps.cxx187
-rw-r--r--ucb/source/ucp/ftp/ftpcontentidentifier.cxx150
-rw-r--r--ucb/source/ucp/ftp/ftpcontentidentifier.hxx118
-rw-r--r--ucb/source/ucp/ftp/ftpcontentprovider.cxx280
-rw-r--r--ucb/source/ucp/ftp/ftpcontentprovider.hxx130
-rw-r--r--ucb/source/ucp/ftp/ftpdirp.cxx1292
-rw-r--r--ucb/source/ucp/ftp/ftpdirp.hxx189
-rw-r--r--ucb/source/ucp/ftp/ftpdynresultset.cxx91
-rw-r--r--ucb/source/ucp/ftp/ftpdynresultset.hxx67
-rwxr-xr-xucb/source/ucp/ftp/ftphandleprovider.hxx29
-rw-r--r--ucb/source/ucp/ftp/ftpinpstr.cxx217
-rw-r--r--ucb/source/ucp/ftp/ftpinpstr.hxx151
-rw-r--r--ucb/source/ucp/ftp/ftpintreq.cxx230
-rw-r--r--ucb/source/ucp/ftp/ftpintreq.hxx181
-rw-r--r--ucb/source/ucp/ftp/ftploaderthread.cxx109
-rw-r--r--ucb/source/ucp/ftp/ftploaderthread.hxx73
-rw-r--r--ucb/source/ucp/ftp/ftpresultsetI.cxx105
-rw-r--r--ucb/source/ucp/ftp/ftpresultsetI.hxx63
-rw-r--r--ucb/source/ucp/ftp/ftpresultsetbase.cxx662
-rw-r--r--ucb/source/ucp/ftp/ftpresultsetbase.hxx608
-rw-r--r--ucb/source/ucp/ftp/ftpresultsetfactory.hxx57
-rw-r--r--ucb/source/ucp/ftp/ftpservices.cxx128
-rw-r--r--ucb/source/ucp/ftp/ftpstrcont.hxx87
-rw-r--r--ucb/source/ucp/ftp/ftpurl.cxx838
-rw-r--r--ucb/source/ucp/ftp/ftpurl.hxx178
-rw-r--r--ucb/source/ucp/ftp/makefile.mk106
-rw-r--r--ucb/source/ucp/ftp/test.cxx298
-rw-r--r--ucb/source/ucp/ftp/test.py25
-rw-r--r--ucb/source/ucp/ftp/test_activedatasink.cxx64
-rw-r--r--ucb/source/ucp/ftp/test_activedatasink.hxx89
-rwxr-xr-xucb/source/ucp/ftp/test_ftpurl.cxx284
-rwxr-xr-xucb/source/ucp/ftp/test_ftpurl.hxx5
-rw-r--r--ucb/source/ucp/ftp/test_interactionhandler.hxx75
-rw-r--r--ucb/source/ucp/ftp/test_multiservicefac.cxx113
-rw-r--r--ucb/source/ucp/ftp/test_multiservicefac.hxx96
-rw-r--r--ucb/source/ucp/ftp/ucpftp.xml89
-rw-r--r--ucb/source/ucp/gio/gio_content.cxx1334
-rw-r--r--ucb/source/ucp/gio/gio_content.hxx200
-rw-r--r--ucb/source/ucp/gio/gio_datasupplier.cxx282
-rw-r--r--ucb/source/ucp/gio/gio_datasupplier.hxx99
-rw-r--r--ucb/source/ucp/gio/gio_inputstream.cxx120
-rw-r--r--ucb/source/ucp/gio/gio_inputstream.hxx94
-rw-r--r--ucb/source/ucp/gio/gio_mount.cxx183
-rw-r--r--ucb/source/ucp/gio/gio_mount.hxx72
-rw-r--r--ucb/source/ucp/gio/gio_outputstream.cxx92
-rw-r--r--ucb/source/ucp/gio/gio_outputstream.hxx82
-rw-r--r--ucb/source/ucp/gio/gio_provider.cxx175
-rw-r--r--ucb/source/ucp/gio/gio_provider.hxx66
-rw-r--r--ucb/source/ucp/gio/gio_resultset.cxx59
-rw-r--r--ucb/source/ucp/gio/gio_resultset.hxx56
-rw-r--r--ucb/source/ucp/gio/gio_seekable.cxx140
-rw-r--r--ucb/source/ucp/gio/gio_seekable.hxx80
-rw-r--r--ucb/source/ucp/gio/makefile.mk81
-rw-r--r--ucb/source/ucp/gio/ucpgio-ucd.txt6
-rw-r--r--ucb/source/ucp/gio/ucpgio.xml100
-rw-r--r--ucb/source/ucp/gvfs/gvfs_content.cxx1817
-rw-r--r--ucb/source/ucp/gvfs/gvfs_content.hxx271
-rw-r--r--ucb/source/ucp/gvfs/gvfs_directory.cxx423
-rw-r--r--ucb/source/ucp/gvfs/gvfs_directory.hxx95
-rw-r--r--ucb/source/ucp/gvfs/gvfs_provider.cxx228
-rw-r--r--ucb/source/ucp/gvfs/gvfs_provider.hxx65
-rw-r--r--ucb/source/ucp/gvfs/gvfs_stream.cxx343
-rw-r--r--ucb/source/ucp/gvfs/gvfs_stream.hxx165
-rw-r--r--ucb/source/ucp/gvfs/makefile.mk86
-rw-r--r--ucb/source/ucp/gvfs/ucpgvfs-ucd.txt6
-rw-r--r--ucb/source/ucp/gvfs/ucpgvfs.xml113
-rw-r--r--ucb/source/ucp/hierarchy/dynamicresultset.cxx91
-rw-r--r--ucb/source/ucp/hierarchy/dynamicresultset.hxx55
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontent.cxx2009
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontent.hxx311
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx765
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydata.cxx1266
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydata.hxx149
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasource.cxx1116
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasource.hxx125
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx446
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx82
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyprovider.cxx338
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyprovider.hxx155
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyservices.cxx149
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyuri.cxx209
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyuri.hxx91
-rw-r--r--ucb/source/ucp/hierarchy/makefile.mk84
-rw-r--r--ucb/source/ucp/hierarchy/ucphier.xml121
-rw-r--r--ucb/source/ucp/inc/urihelper.hxx123
-rw-r--r--ucb/source/ucp/odma/makefile.mk97
-rw-r--r--ucb/source/ucp/odma/odma.h315
-rw-r--r--ucb/source/ucp/odma/odma_content.cxx1215
-rw-r--r--ucb/source/ucp/odma/odma_content.hxx196
-rw-r--r--ucb/source/ucp/odma/odma_contentcaps.cxx247
-rw-r--r--ucb/source/ucp/odma/odma_contentprops.hxx85
-rw-r--r--ucb/source/ucp/odma/odma_datasupplier.cxx455
-rw-r--r--ucb/source/ucp/odma/odma_datasupplier.hxx74
-rw-r--r--ucb/source/ucp/odma/odma_inputstream.cxx286
-rw-r--r--ucb/source/ucp/odma/odma_inputstream.hxx138
-rw-r--r--ucb/source/ucp/odma/odma_lib.cxx133
-rw-r--r--ucb/source/ucp/odma/odma_lib.hxx272
-rw-r--r--ucb/source/ucp/odma/odma_main.cxx91
-rw-r--r--ucb/source/ucp/odma/odma_provider.cxx599
-rw-r--r--ucb/source/ucp/odma/odma_provider.hxx174
-rw-r--r--ucb/source/ucp/odma/odma_resultset.cxx96
-rw-r--r--ucb/source/ucp/odma/odma_resultset.hxx60
-rw-r--r--ucb/source/ucp/odma/odma_services.cxx138
-rw-r--r--ucb/source/ucp/odma/ucpodma.xml100
-rw-r--r--ucb/source/ucp/package/makefile.mk88
-rw-r--r--ucb/source/ucp/package/pkgcontent.cxx3012
-rw-r--r--ucb/source/ucp/package/pkgcontent.hxx335
-rw-r--r--ucb/source/ucp/package/pkgcontentcaps.cxx562
-rw-r--r--ucb/source/ucp/package/pkgdatasupplier.cxx498
-rw-r--r--ucb/source/ucp/package/pkgdatasupplier.hxx77
-rw-r--r--ucb/source/ucp/package/pkgprovider.cxx330
-rw-r--r--ucb/source/ucp/package/pkgprovider.hxx105
-rw-r--r--ucb/source/ucp/package/pkgresultset.cxx94
-rw-r--r--ucb/source/ucp/package/pkgresultset.hxx59
-rw-r--r--ucb/source/ucp/package/pkgservices.cxx133
-rw-r--r--ucb/source/ucp/package/pkguri.cxx245
-rw-r--r--ucb/source/ucp/package/pkguri.hxx101
-rw-r--r--ucb/source/ucp/package/ucppkg.xml92
-rw-r--r--ucb/source/ucp/tdoc/makefile.mk94
-rw-r--r--ucb/source/ucp/tdoc/tdoc_content.cxx3135
-rw-r--r--ucb/source/ucp/tdoc/tdoc_content.hxx342
-rw-r--r--ucb/source/ucp/tdoc/tdoc_contentcaps.cxx705
-rw-r--r--ucb/source/ucp/tdoc/tdoc_datasupplier.cxx468
-rw-r--r--ucb/source/ucp/tdoc/tdoc_datasupplier.hxx81
-rw-r--r--ucb/source/ucp/tdoc/tdoc_docmgr.cxx691
-rw-r--r--ucb/source/ucp/tdoc/tdoc_docmgr.hxx173
-rw-r--r--ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx188
-rw-r--r--ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx86
-rw-r--r--ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx242
-rw-r--r--ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx100
-rw-r--r--ucb/source/ucp/tdoc/tdoc_provider.cxx629
-rw-r--r--ucb/source/ucp/tdoc/tdoc_provider.hxx148
-rw-r--r--ucb/source/ucp/tdoc/tdoc_resultset.cxx95
-rw-r--r--ucb/source/ucp/tdoc/tdoc_resultset.hxx56
-rw-r--r--ucb/source/ucp/tdoc/tdoc_services.cxx151
-rw-r--r--ucb/source/ucp/tdoc/tdoc_stgelems.cxx1108
-rw-r--r--ucb/source/ucp/tdoc/tdoc_stgelems.hxx542
-rw-r--r--ucb/source/ucp/tdoc/tdoc_storage.cxx712
-rw-r--r--ucb/source/ucp/tdoc/tdoc_storage.hxx172
-rw-r--r--ucb/source/ucp/tdoc/tdoc_uri.cxx135
-rw-r--r--ucb/source/ucp/tdoc/tdoc_uri.hxx131
-rw-r--r--ucb/source/ucp/tdoc/ucptdoc.xml129
-rw-r--r--ucb/source/ucp/webdav/ContentProperties.cxx573
-rw-r--r--ucb/source/ucp/webdav/ContentProperties.hxx197
-rw-r--r--ucb/source/ucp/webdav/DAVAuthListener.hxx55
-rw-r--r--ucb/source/ucp/webdav/DAVAuthListenerImpl.hxx78
-rw-r--r--ucb/source/ucp/webdav/DAVException.hxx166
-rw-r--r--ucb/source/ucp/webdav/DAVProperties.cxx199
-rw-r--r--ucb/source/ucp/webdav/DAVProperties.hxx62
-rw-r--r--ucb/source/ucp/webdav/DAVRequestEnvironment.hxx62
-rw-r--r--ucb/source/ucp/webdav/DAVResource.hxx67
-rw-r--r--ucb/source/ucp/webdav/DAVResourceAccess.cxx1219
-rw-r--r--ucb/source/ucp/webdav/DAVResourceAccess.hxx251
-rw-r--r--ucb/source/ucp/webdav/DAVSession.hxx219
-rw-r--r--ucb/source/ucp/webdav/DAVSessionFactory.cxx106
-rw-r--r--ucb/source/ucp/webdav/DAVSessionFactory.hxx82
-rw-r--r--ucb/source/ucp/webdav/DAVTypes.hxx85
-rw-r--r--ucb/source/ucp/webdav/DateTimeHelper.cxx270
-rw-r--r--ucb/source/ucp/webdav/DateTimeHelper.hxx63
-rw-r--r--ucb/source/ucp/webdav/LinkSequence.cxx223
-rw-r--r--ucb/source/ucp/webdav/LinkSequence.hxx51
-rw-r--r--ucb/source/ucp/webdav/LockEntrySequence.cxx244
-rw-r--r--ucb/source/ucp/webdav/LockEntrySequence.hxx48
-rw-r--r--ucb/source/ucp/webdav/LockSequence.cxx351
-rw-r--r--ucb/source/ucp/webdav/LockSequence.hxx48
-rw-r--r--ucb/source/ucp/webdav/NeonHeadRequest.cxx200
-rw-r--r--ucb/source/ucp/webdav/NeonHeadRequest.hxx53
-rw-r--r--ucb/source/ucp/webdav/NeonInputStream.cxx195
-rw-r--r--ucb/source/ucp/webdav/NeonInputStream.hxx124
-rw-r--r--ucb/source/ucp/webdav/NeonLockStore.cxx245
-rw-r--r--ucb/source/ucp/webdav/NeonLockStore.hxx102
-rw-r--r--ucb/source/ucp/webdav/NeonPropFindRequest.cxx345
-rw-r--r--ucb/source/ucp/webdav/NeonPropFindRequest.hxx62
-rw-r--r--ucb/source/ucp/webdav/NeonSession.cxx2205
-rw-r--r--ucb/source/ucp/webdav/NeonSession.hxx295
-rw-r--r--ucb/source/ucp/webdav/NeonTypes.hxx46
-rw-r--r--ucb/source/ucp/webdav/NeonUri.cxx358
-rw-r--r--ucb/source/ucp/webdav/NeonUri.hxx102
-rw-r--r--ucb/source/ucp/webdav/PropertyMap.hxx65
-rw-r--r--ucb/source/ucp/webdav/UCBDeadPropertyValue.cxx547
-rw-r--r--ucb/source/ucp/webdav/UCBDeadPropertyValue.hxx65
-rw-r--r--ucb/source/ucp/webdav/makefile.mk160
-rw-r--r--ucb/source/ucp/webdav/ucpdav.xml109
-rw-r--r--ucb/source/ucp/webdav/webdavcontent.cxx3247
-rw-r--r--ucb/source/ucp/webdav/webdavcontent.hxx299
-rw-r--r--ucb/source/ucp/webdav/webdavcontentcaps.cxx672
-rw-r--r--ucb/source/ucp/webdav/webdavdatasupplier.cxx512
-rw-r--r--ucb/source/ucp/webdav/webdavdatasupplier.hxx82
-rw-r--r--ucb/source/ucp/webdav/webdavprovider.cxx232
-rw-r--r--ucb/source/ucp/webdav/webdavprovider.hxx124
-rw-r--r--ucb/source/ucp/webdav/webdavresultset.cxx95
-rw-r--r--ucb/source/ucp/webdav/webdavresultset.hxx59
-rw-r--r--ucb/source/ucp/webdav/webdavservices.cxx130
282 files changed, 94739 insertions, 0 deletions
diff --git a/ucb/source/cacher/cached.xml b/ucb/source/cacher/cached.xml
new file mode 100644
index 000000000000..208520272f7c
--- /dev/null
+++ b/ucb/source/cacher/cached.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ cached
+ </module-name>
+
+ <component-description>
+ <author>
+ Ingrid Halama
+ </author>
+ <name>
+ com.sun.star.comp.ucb.CachedContentResultSetFactory
+ </name>
+ <description>
+ This component implements a factory for locally cached resultsets.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.CachedContentResultSetFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.script.Converter
+ </service-dependency>
+ </component-description>
+ <component-description>
+ <author>
+ Ingrid Halama
+ </author>
+ <name>
+ com.sun.star.comp.ucb.CachedContentResultSetStubFactory
+ </name>
+ <description>
+ This component implements a factory for stubs for locally cached
+ resultsets.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.CachedContentResultSetStubFactory
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>
+ Ingrid Halama
+ </author>
+ <name>
+ com.sun.star.comp.ucb.CachedDynamicResultSetFactory
+ </name>
+ <description>
+ This component implements a factory for locally cached dynamic
+ resultsets.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.CachedDynamicResultSetFactory
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>
+ Ingrid Halama
+ </author>
+ <name>
+ com.sun.star.comp.ucb.CachedDynamicResultSetStubFactory
+ </name>
+ <description>
+ This component implements a factory for stubs for locally cached
+ dynamic resultsets.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.CachedDynamicResultSetStubFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.SortedDynamicResultSetFactory
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.sdbc.FetchDirection </type>
+ <type> com.sun.star.sdbc.ResultSetType </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSet </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentResultSetCapability </type>
+ <type> com.sun.star.ucb.FetchError </type>
+ <type> com.sun.star.ucb.ListActionType </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XCachedContentResultSetFactory </type>
+ <type> com.sun.star.ucb.XCachedContentResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetFactory </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XContentIdentifierMapping </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XFetchProvider </type>
+ <type> com.sun.star.ucb.XFetchProviderForContentAccess </type>
+ <type> com.sun.star.ucb.XSortedDynamicResultSetFactory </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.uno.XWeak </type>
+</module-description>
diff --git a/ucb/source/cacher/cachedcontentresultset.cxx b/ucb/source/cacher/cachedcontentresultset.cxx
new file mode 100644
index 000000000000..e5c879448338
--- /dev/null
+++ b/ucb/source/cacher/cachedcontentresultset.cxx
@@ -0,0 +1,2229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <cachedcontentresultset.hxx>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/ucb/FetchError.hpp>
+#include <com/sun/star/ucb/ResultSetException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+#define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
+#define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//define for getXXX methods of interface XRow
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+//if you change this macro please pay attention to
+//function ::getObject, where this is similar implemented
+
+#define XROW_GETXXX( getXXX, Type ) \
+impl_EnsureNotDisposed(); \
+ReacquireableGuard aGuard( m_aMutex ); \
+sal_Int32 nRow = m_nRow; \
+sal_Int32 nFetchSize = m_nFetchSize; \
+sal_Int32 nFetchDirection = m_nFetchDirection; \
+if( !m_aCache.hasRow( nRow ) ) \
+{ \
+ if( !m_aCache.hasCausedException( nRow ) ) \
+{ \
+ if( !m_xFetchProvider.is() ) \
+ { \
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \
+ throw SQLException(); \
+ } \
+ aGuard.clear(); \
+ if( impl_isForwardOnly() ) \
+ applyPositionToOrigin( nRow ); \
+ \
+ impl_fetchData( nRow, nFetchSize, nFetchDirection ); \
+ } \
+ aGuard.reacquire(); \
+ if( !m_aCache.hasRow( nRow ) ) \
+ { \
+ m_bLastReadWasFromCache = sal_False; \
+ aGuard.clear(); \
+ applyPositionToOrigin( nRow ); \
+ impl_init_xRowOrigin(); \
+ return m_xRowOrigin->getXXX( columnIndex ); \
+ } \
+} \
+const Any& rValue = m_aCache.getAny( nRow, columnIndex );\
+Type aRet = Type(); \
+m_bLastReadWasFromCache = sal_True; \
+m_bLastCachedReadWasNull = !( rValue >>= aRet ); \
+/* Last chance. Try type converter service... */ \
+if ( m_bLastCachedReadWasNull && rValue.hasValue() ) \
+{ \
+ Reference< XTypeConverter > xConverter \
+ = getTypeConverter(); \
+ if ( xConverter.is() ) \
+ { \
+ try \
+ { \
+ Any aConvAny = xConverter->convertTo( \
+ rValue, \
+ getCppuType( static_cast< \
+ const Type * >( 0 ) ) ); \
+ m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \
+ } \
+ catch ( IllegalArgumentException ) \
+ { \
+ } \
+ catch ( CannotConvertException ) \
+ { \
+ } \
+ } \
+} \
+return aRet;
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// CCRS_Cache methoeds.
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedContentResultSet::CCRS_Cache::CCRS_Cache(
+ const Reference< XContentIdentifierMapping > & xMapping )
+ : m_pResult( NULL )
+ , m_xContentIdentifierMapping( xMapping )
+ , m_pMappedReminder( NULL )
+{
+}
+
+CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
+{
+ delete m_pResult;
+}
+
+void SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::clear()
+{
+ if( m_pResult )
+ {
+ delete m_pResult;
+ m_pResult = NULL;
+ }
+ clearMappedReminder();
+}
+
+void SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::loadData( const FetchResult& rResult )
+{
+ clear();
+ m_pResult = new FetchResult( rResult );
+}
+
+sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::hasRow( sal_Int32 row )
+{
+ if( !m_pResult )
+ return sal_False;
+ long nStart = m_pResult->StartIndex;
+ long nEnd = nStart;
+ if( m_pResult->Orientation )
+ nEnd += m_pResult->Rows.getLength() - 1;
+ else
+ nStart -= m_pResult->Rows.getLength() + 1;
+
+ return nStart <= row && row <= nEnd;
+}
+
+sal_Int32 SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getMaxRow()
+{
+ if( !m_pResult )
+ return 0;
+ long nEnd = m_pResult->StartIndex;
+ if( m_pResult->Orientation )
+ return nEnd += m_pResult->Rows.getLength() - 1;
+ else
+ return nEnd;
+}
+
+sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::hasKnownLast()
+{
+ if( !m_pResult )
+ return sal_False;
+
+ if( ( m_pResult->FetchError & FetchError::ENDOFDATA )
+ && m_pResult->Orientation
+ && m_pResult->Rows.getLength() )
+ return sal_True;
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::hasCausedException( sal_Int32 nRow )
+{
+ if( !m_pResult )
+ return sal_False;
+ if( !( m_pResult->FetchError & FetchError::EXCEPTION ) )
+ return sal_False;
+
+ long nEnd = m_pResult->StartIndex;
+ if( m_pResult->Orientation )
+ nEnd += m_pResult->Rows.getLength();
+
+ return nRow == nEnd+1;
+}
+
+Any& SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getRowAny( sal_Int32 nRow )
+ throw( SQLException,
+ RuntimeException )
+{
+ if( !nRow )
+ throw SQLException();
+ if( !m_pResult )
+ throw SQLException();
+ if( !hasRow( nRow ) )
+ throw SQLException();
+
+ long nDiff = nRow - m_pResult->StartIndex;
+ if( nDiff < 0 )
+ nDiff *= -1;
+
+ return (m_pResult->Rows)[nDiff];
+}
+
+void SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::remindMapped( sal_Int32 nRow )
+{
+ //remind that this row was mapped
+ if( !m_pResult )
+ return;
+ long nDiff = nRow - m_pResult->StartIndex;
+ if( nDiff < 0 )
+ nDiff *= -1;
+ Sequence< sal_Bool >* pMappedReminder = getMappedReminder();
+ if( nDiff < pMappedReminder->getLength() )
+ (*pMappedReminder)[nDiff] = sal_True;
+}
+
+sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::isRowMapped( sal_Int32 nRow )
+{
+ if( !m_pMappedReminder || !m_pResult )
+ return sal_False;
+ long nDiff = nRow - m_pResult->StartIndex;
+ if( nDiff < 0 )
+ nDiff *= -1;
+ if( nDiff < m_pMappedReminder->getLength() )
+ return (*m_pMappedReminder)[nDiff];
+ return sal_False;
+}
+
+void SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::clearMappedReminder()
+{
+ delete m_pMappedReminder;
+ m_pMappedReminder = NULL;
+}
+
+Sequence< sal_Bool >* SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getMappedReminder()
+{
+ if( !m_pMappedReminder )
+ {
+ sal_Int32 nCount = m_pResult->Rows.getLength();
+ m_pMappedReminder = new Sequence< sal_Bool >( nCount );
+ for( ;nCount; nCount-- )
+ (*m_pMappedReminder)[nCount] = sal_False;
+ }
+ return m_pMappedReminder;
+}
+
+const Any& SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getAny( sal_Int32 nRow, sal_Int32 nColumnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ if( !nColumnIndex )
+ throw SQLException();
+ if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
+ {
+ Any& rRow = getRowAny( nRow );
+ Sequence< Any > aValue;
+ rRow >>= aValue;
+ if( m_xContentIdentifierMapping->mapRow( aValue ) )
+ {
+ rRow <<= aValue;
+ remindMapped( nRow );
+ }
+ else
+ m_xContentIdentifierMapping.clear();
+ }
+ const Sequence< Any >& rRow =
+ (* reinterpret_cast< const Sequence< Any > * >
+ (getRowAny( nRow ).getValue() ));
+
+ if( nColumnIndex > rRow.getLength() )
+ throw SQLException();
+ return rRow[nColumnIndex-1];
+}
+
+const rtl::OUString& SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getContentIdentifierString( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ try
+ {
+ if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
+ {
+ Any& rRow = getRowAny( nRow );
+ rtl::OUString aValue;
+ rRow >>= aValue;
+ rRow <<= m_xContentIdentifierMapping->mapContentIdentifierString( aValue );
+ remindMapped( nRow );
+ }
+ return (* reinterpret_cast< const rtl::OUString * >
+ (getRowAny( nRow ).getValue() ));
+ }
+ catch( SQLException )
+ {
+ throw RuntimeException();
+ }
+}
+
+const Reference< XContentIdentifier >& SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getContentIdentifier( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ try
+ {
+ if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
+ {
+ Any& rRow = getRowAny( nRow );
+ Reference< XContentIdentifier > aValue;
+ rRow >>= aValue;
+ rRow <<= m_xContentIdentifierMapping->mapContentIdentifier( aValue );
+ remindMapped( nRow );
+ }
+ return (* reinterpret_cast< const Reference< XContentIdentifier > * >
+ (getRowAny( nRow ).getValue() ));
+ }
+ catch( SQLException )
+ {
+ throw RuntimeException();
+ }
+}
+
+const Reference< XContent >& SAL_CALL CachedContentResultSet::CCRS_Cache
+ ::getContent( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ try
+ {
+ if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
+ {
+ Any& rRow = getRowAny( nRow );
+ Reference< XContent > aValue;
+ rRow >>= aValue;
+ rRow <<= m_xContentIdentifierMapping->mapContent( aValue );
+ remindMapped( nRow );
+ }
+ return (* reinterpret_cast< const Reference< XContent > * >
+ (getRowAny( nRow ).getValue() ));
+ }
+ catch( SQLException )
+ {
+ throw RuntimeException();
+ }
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CCRS_PropertySetInfo
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+class CCRS_PropertySetInfo :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::beans::XPropertySetInfo
+{
+ friend class CachedContentResultSet;
+
+ //my Properties
+ Sequence< com::sun::star::beans::Property >*
+ m_pProperties;
+
+ //some helping variables ( names for my special properties )
+ static rtl::OUString m_aPropertyNameForCount;
+ static rtl::OUString m_aPropertyNameForFinalCount;
+ static rtl::OUString m_aPropertyNameForFetchSize;
+ static rtl::OUString m_aPropertyNameForFetchDirection;
+
+ long m_nFetchSizePropertyHandle;
+ long m_nFetchDirectionPropertyHandle;
+
+private:
+ sal_Int32 SAL_CALL
+ impl_getRemainedHandle() const;
+
+ sal_Bool SAL_CALL
+ impl_queryProperty(
+ const rtl::OUString& rName
+ , com::sun::star::beans::Property& rProp ) const;
+ sal_Int32 SAL_CALL
+ impl_getPos( const rtl::OUString& rName ) const;
+
+ static sal_Bool SAL_CALL
+ impl_isMyPropertyName( const rtl::OUString& rName );
+
+public:
+ CCRS_PropertySetInfo( Reference<
+ XPropertySetInfo > xPropertySetInfoOrigin );
+
+ virtual ~CCRS_PropertySetInfo();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XPropertySetInfo
+ virtual Sequence< com::sun::star::beans::Property > SAL_CALL
+ getProperties()
+ throw( RuntimeException );
+
+ virtual com::sun::star::beans::Property SAL_CALL
+ getPropertyByName( const rtl::OUString& aName )
+ throw( com::sun::star::beans::UnknownPropertyException, RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ hasPropertyByName( const rtl::OUString& Name )
+ throw( RuntimeException );
+};
+
+OUString CCRS_PropertySetInfo::m_aPropertyNameForCount( OUString::createFromAscii( "RowCount" ) );
+OUString CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( OUString::createFromAscii( "IsRowCountFinal" ) );
+OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) );
+OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) );
+
+CCRS_PropertySetInfo::CCRS_PropertySetInfo(
+ Reference< XPropertySetInfo > xInfo )
+ : m_pProperties( NULL )
+ , m_nFetchSizePropertyHandle( -1 )
+ , m_nFetchDirectionPropertyHandle( -1 )
+{
+ //initialize list of properties:
+
+ // it is required, that the received xInfo contains the two
+ // properties with names 'm_aPropertyNameForCount' and
+ // 'm_aPropertyNameForFinalCount'
+
+ if( xInfo.is() )
+ {
+ Sequence<Property> aProps = xInfo->getProperties();
+ m_pProperties = new Sequence<Property> ( aProps );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "The received XPropertySetInfo doesn't contain required properties" );
+ m_pProperties = new Sequence<Property>;
+ }
+
+ //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
+ sal_Int32 nFetchSize = impl_getPos( m_aPropertyNameForFetchSize );
+ sal_Int32 nFetchDirection = impl_getPos( m_aPropertyNameForFetchDirection );
+ sal_Int32 nDeleted = 0;
+ if( nFetchSize != -1 )
+ nDeleted++;
+ if( nFetchDirection != -1 )
+ nDeleted++;
+
+ Sequence< Property >* pOrigProps = new Sequence<Property> ( *m_pProperties );
+ sal_Int32 nOrigProps = pOrigProps->getLength();
+
+ m_pProperties->realloc( nOrigProps + 2 - nDeleted );//note that nDeleted is <= 2
+ for( sal_Int32 n = 0, m = 0; n < nOrigProps; n++, m++ )
+ {
+ if( n == nFetchSize || n == nFetchDirection )
+ m--;
+ else
+ (*m_pProperties)[ m ] = (*pOrigProps)[ n ];
+ }
+ {
+ Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted ];
+ rMyProp.Name = m_aPropertyNameForFetchSize;
+ rMyProp.Type = getCppuType( static_cast< const sal_Int32 * >( 0 ) );
+ rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
+
+ if( nFetchSize != -1 )
+ m_nFetchSizePropertyHandle = (*pOrigProps)[nFetchSize].Handle;
+ else
+ m_nFetchSizePropertyHandle = impl_getRemainedHandle();
+
+ rMyProp.Handle = m_nFetchSizePropertyHandle;
+
+ }
+ {
+ Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted + 1 ];
+ rMyProp.Name = m_aPropertyNameForFetchDirection;
+ rMyProp.Type = getCppuType( static_cast< const sal_Bool * >( 0 ) );
+ rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
+
+ if( nFetchSize != -1 )
+ m_nFetchDirectionPropertyHandle = (*pOrigProps)[nFetchDirection].Handle;
+ else
+ m_nFetchDirectionPropertyHandle = impl_getRemainedHandle();
+
+ m_nFetchDirectionPropertyHandle = rMyProp.Handle;
+ }
+ delete pOrigProps;
+}
+
+CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
+{
+ delete m_pProperties;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+//list all interfaces inclusive baseclasses of interfaces
+XINTERFACE_IMPL_2( CCRS_PropertySetInfo
+ , XTypeProvider
+ , XPropertySetInfo
+ );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+//list all interfaces exclusive baseclasses
+XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
+ , XTypeProvider
+ , XPropertySetInfo
+ );
+//--------------------------------------------------------------------------
+// XPropertySetInfo methods.
+//--------------------------------------------------------------------------
+//virtual
+Sequence< Property > SAL_CALL CCRS_PropertySetInfo
+ ::getProperties() throw( RuntimeException )
+{
+ return *m_pProperties;
+}
+
+//virtual
+Property SAL_CALL CCRS_PropertySetInfo
+ ::getPropertyByName( const rtl::OUString& aName )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ if ( !aName.getLength() )
+ throw UnknownPropertyException();
+
+ Property aProp;
+ if ( impl_queryProperty( aName, aProp ) )
+ return aProp;
+
+ throw UnknownPropertyException();
+}
+
+//virtual
+sal_Bool SAL_CALL CCRS_PropertySetInfo
+ ::hasPropertyByName( const rtl::OUString& Name )
+ throw( RuntimeException )
+{
+ return ( impl_getPos( Name ) != -1 );
+}
+
+//--------------------------------------------------------------------------
+// impl_ methods.
+//--------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL CCRS_PropertySetInfo
+ ::impl_getPos( const OUString& rName ) const
+{
+ for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
+ {
+ const Property& rMyProp = (*m_pProperties)[nN];
+ if( rMyProp.Name == rName )
+ return nN;
+ }
+ return -1;
+}
+
+sal_Bool SAL_CALL CCRS_PropertySetInfo
+ ::impl_queryProperty( const OUString& rName, Property& rProp ) const
+{
+ for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
+ {
+ const Property& rMyProp = (*m_pProperties)[nN];
+ if( rMyProp.Name == rName )
+ {
+ rProp.Name = rMyProp.Name;
+ rProp.Handle = rMyProp.Handle;
+ rProp.Type = rMyProp.Type;
+ rProp.Attributes = rMyProp.Attributes;
+
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+//static
+sal_Bool SAL_CALL CCRS_PropertySetInfo
+ ::impl_isMyPropertyName( const OUString& rPropertyName )
+{
+ return ( rPropertyName == m_aPropertyNameForCount
+ || rPropertyName == m_aPropertyNameForFinalCount
+ || rPropertyName == m_aPropertyNameForFetchSize
+ || rPropertyName == m_aPropertyNameForFetchDirection );
+}
+
+sal_Int32 SAL_CALL CCRS_PropertySetInfo
+ ::impl_getRemainedHandle( ) const
+{
+ sal_Int32 nHandle = 1;
+
+ if( !m_pProperties )
+ {
+ OSL_ENSURE( sal_False, "Properties not initialized yet" );
+ return nHandle;
+ }
+ sal_Bool bFound = sal_True;
+ while( bFound )
+ {
+ bFound = sal_False;
+ for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
+ {
+ if( nHandle == (*m_pProperties)[nN].Handle )
+ {
+ bFound = sal_True;
+ nHandle++;
+ break;
+ }
+ }
+ }
+ return nHandle;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CachedContentResultSet
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedContentResultSet::CachedContentResultSet(
+ const Reference< XMultiServiceFactory > & xSMgr
+ , const Reference< XResultSet > & xOrigin
+ , const Reference< XContentIdentifierMapping > &
+ xContentIdentifierMapping )
+ : ContentResultSetWrapper( xOrigin )
+
+ , m_xSMgr( xSMgr )
+ , m_xFetchProvider( NULL )
+ , m_xFetchProviderForContentAccess( NULL )
+
+ , m_xMyPropertySetInfo( NULL )
+ , m_pMyPropSetInfo( NULL )
+
+ , m_xContentIdentifierMapping( xContentIdentifierMapping )
+ , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
+ , m_bAfterLast( sal_False )
+ , m_nLastAppliedPos( 0 )
+ , m_bAfterLastApplied( sal_False )
+ , m_nKnownCount( 0 )
+ , m_bFinalCount( sal_False )
+ , m_nFetchSize(
+ COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE )
+ , m_nFetchDirection(
+ COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION )
+
+ , m_bLastReadWasFromCache( sal_False )
+ , m_bLastCachedReadWasNull( sal_True )
+ , m_aCache( m_xContentIdentifierMapping )
+ , m_aCacheContentIdentifierString( m_xContentIdentifierMapping )
+ , m_aCacheContentIdentifier( m_xContentIdentifierMapping )
+ , m_aCacheContent( m_xContentIdentifierMapping )
+ , m_bTriedToGetTypeConverter( sal_False )
+ , m_xTypeConverter( NULL )
+{
+ m_xFetchProvider = Reference< XFetchProvider >( m_xResultSetOrigin, UNO_QUERY );
+ OSL_ENSURE( m_xFetchProvider.is(), "interface XFetchProvider is required" );
+
+ m_xFetchProviderForContentAccess = Reference< XFetchProviderForContentAccess >( m_xResultSetOrigin, UNO_QUERY );
+ OSL_ENSURE( m_xFetchProviderForContentAccess.is(), "interface XFetchProviderForContentAccess is required" );
+
+ impl_init();
+};
+
+CachedContentResultSet::~CachedContentResultSet()
+{
+ impl_deinit();
+ //do not delete m_pMyPropSetInfo, cause it is hold via reference
+};
+
+//--------------------------------------------------------------------------
+// impl_ methods.
+//--------------------------------------------------------------------------
+
+sal_Bool SAL_CALL CachedContentResultSet
+ ::applyPositionToOrigin( sal_Int32 nRow )
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ //-------------------------------------------------------------------------
+ /**
+ @returns
+ <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
+ the result set.
+ */
+
+ ReacquireableGuard aGuard( m_aMutex );
+ OSL_ENSURE( nRow >= 0, "only positive values supported" );
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+// OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
+
+ sal_Int32 nLastAppliedPos = m_nLastAppliedPos;
+ sal_Bool bAfterLastApplied = m_bAfterLastApplied;
+ sal_Bool bAfterLast = m_bAfterLast;
+ sal_Int32 nForwardOnly = m_nForwardOnly;
+
+ aGuard.clear();
+
+ if( bAfterLastApplied || nLastAppliedPos != nRow )
+ {
+ if( nForwardOnly == 1 )
+ {
+ if( bAfterLastApplied || bAfterLast || !nRow || nRow < nLastAppliedPos )
+ throw SQLException();
+
+ sal_Int32 nN = nRow - nLastAppliedPos;
+ sal_Int32 nM;
+ for( nM = 0; nN--; nM++ )
+ {
+ if( !m_xResultSetOrigin->next() )
+ break;
+ }
+
+ aGuard.reacquire();
+ m_nLastAppliedPos += nM;
+ m_bAfterLastApplied = nRow != m_nLastAppliedPos;
+ return nRow == m_nLastAppliedPos;
+ }
+
+ if( !nRow ) //absolute( 0 ) will throw exception
+ {
+ m_xResultSetOrigin->beforeFirst();
+
+ aGuard.reacquire();
+ m_nLastAppliedPos = 0;
+ m_bAfterLastApplied = sal_False;
+ return sal_False;
+ }
+ try
+ {
+ //move absolute, if !nLastAppliedPos
+ //because move relative would throw exception
+ if( !nLastAppliedPos || bAfterLast || bAfterLastApplied )
+ {
+ sal_Bool bValid = m_xResultSetOrigin->absolute( nRow );
+
+ aGuard.reacquire();
+ m_nLastAppliedPos = nRow;
+ m_bAfterLastApplied = !bValid;
+ return bValid;
+ }
+ else
+ {
+ sal_Bool bValid = m_xResultSetOrigin->relative( nRow - nLastAppliedPos );
+
+ aGuard.reacquire();
+ m_nLastAppliedPos += ( nRow - nLastAppliedPos );
+ m_bAfterLastApplied = !bValid;
+ return bValid;
+ }
+ }
+ catch( SQLException& rEx )
+ {
+ if( !bAfterLastApplied && !bAfterLast && nRow > nLastAppliedPos && impl_isForwardOnly() )
+ {
+ sal_Int32 nN = nRow - nLastAppliedPos;
+ sal_Int32 nM;
+ for( nM = 0; nN--; nM++ )
+ {
+ if( !m_xResultSetOrigin->next() )
+ break;
+ }
+
+ aGuard.reacquire();
+ m_nLastAppliedPos += nM;
+ m_bAfterLastApplied = nRow != m_nLastAppliedPos;
+ }
+ else
+ throw rEx;
+ }
+
+ return nRow == m_nLastAppliedPos;
+ }
+ return sal_True;
+};
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//define for fetching data
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+#define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
+sal_Bool bDirection = !!( \
+ nFetchDirection != FetchDirection::REVERSE ); \
+FetchResult aResult = \
+ fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
+osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
+aCache.loadData( aResult ); \
+sal_Int32 nMax = aCache.getMaxRow(); \
+sal_Int32 nCurCount = m_nKnownCount; \
+sal_Bool bIsFinalCount = aCache.hasKnownLast(); \
+sal_Bool bCurIsFinalCount = m_bFinalCount; \
+aGuard2.clear(); \
+if( nMax > nCurCount ) \
+ impl_changeRowCount( nCurCount, nMax ); \
+if( bIsFinalCount && !bCurIsFinalCount ) \
+ impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
+
+void SAL_CALL CachedContentResultSet
+ ::impl_fetchData( sal_Int32 nRow
+ , sal_Int32 nFetchSize, sal_Int32 nFetchDirection )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ FETCH_XXX( m_aCache, m_xFetchProvider, fetch );
+}
+
+void SAL_CALL CachedContentResultSet
+ ::impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew )
+{
+ OSL_ENSURE( nNew > nOld, "RowCount only can grow" );
+ if( nNew <= nOld )
+ return;
+
+ //create PropertyChangeEvent and set value
+ PropertyChangeEvent aEvt;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+ aEvt.OldValue <<= nOld;
+ aEvt.NewValue <<= nNew;
+
+ m_nKnownCount = nNew;
+ }
+
+ //send PropertyChangeEvent to listeners
+ impl_notifyPropertyChangeListeners( aEvt );
+}
+
+void SAL_CALL CachedContentResultSet
+ ::impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew )
+{
+ OSL_ENSURE( !bOld && bNew, "This change is not allowed for IsRowCountFinal" );
+ if( ! (!bOld && bNew ) )
+ return;
+
+ //create PropertyChangeEvent and set value
+ PropertyChangeEvent aEvt;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+ aEvt.OldValue <<= bOld;
+ aEvt.NewValue <<= bNew;
+
+ m_bFinalCount = bNew;
+ }
+
+ //send PropertyChangeEvent to listeners
+ impl_notifyPropertyChangeListeners( aEvt );
+}
+
+sal_Bool SAL_CALL CachedContentResultSet
+ ::impl_isKnownValidPosition( sal_Int32 nRow )
+{
+ return m_nKnownCount && nRow
+ && nRow <= m_nKnownCount;
+}
+
+sal_Bool SAL_CALL CachedContentResultSet
+ ::impl_isKnownInvalidPosition( sal_Int32 nRow )
+{
+ if( !nRow )
+ return sal_True;
+ if( !m_bFinalCount )
+ return sal_False;
+ return nRow > m_nKnownCount;
+}
+
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::impl_initPropertySetInfo()
+{
+ ContentResultSetWrapper::impl_initPropertySetInfo();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_pMyPropSetInfo )
+ return;
+ m_pMyPropSetInfo = new CCRS_PropertySetInfo( m_xPropertySetInfo );
+ m_xMyPropertySetInfo = m_pMyPropSetInfo;
+ m_xPropertySetInfo = m_xMyPropertySetInfo;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods. ( inherited )
+//--------------------------------------------------------------------------
+XINTERFACE_COMMON_IMPL( CachedContentResultSet )
+
+Any SAL_CALL CachedContentResultSet
+ ::queryInterface( const Type& rType )
+ throw ( RuntimeException )
+{
+ //list all interfaces inclusive baseclasses of interfaces
+
+ Any aRet = ContentResultSetWrapper::queryInterface( rType );
+ if( aRet.hasValue() )
+ return aRet;
+
+ aRet = cppu::queryInterface( rType,
+ static_cast< XTypeProvider* >( this ),
+ static_cast< XServiceInfo* >( this ) );
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+//list all interfaces exclusive baseclasses
+XTYPEPROVIDER_IMPL_11( CachedContentResultSet
+ , XTypeProvider
+ , XServiceInfo
+ , XComponent
+ , XCloseable
+ , XResultSetMetaDataSupplier
+ , XPropertySet
+
+ , XPropertyChangeListener
+ , XVetoableChangeListener
+
+ , XContentAccess
+
+ , XResultSet
+ , XRow );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedContentResultSet" ),
+ OUString::createFromAscii(
+ CACHED_CONTENT_RESULTSET_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// XPropertySet methods. ( inherited )
+//--------------------------------------------------------------------------
+
+// virtual
+void SAL_CALL CachedContentResultSet
+ ::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !getPropertySetInfo().is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+
+ Property aProp = m_pMyPropSetInfo->getPropertyByName( aPropertyName );
+ //throws UnknownPropertyException, if so
+
+ if( aProp.Attributes & PropertyAttribute::READONLY )
+ {
+ //It is assumed, that the properties
+ //'RowCount' and 'IsRowCountFinal' are readonly!
+ throw IllegalArgumentException();
+ }
+ if( aProp.Name == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchDirection )
+ {
+ //check value
+ sal_Int32 nNew;
+ if( !( aValue >>= nNew ) )
+ {
+ throw IllegalArgumentException();
+ }
+
+ if( nNew == FetchDirection::UNKNOWN )
+ {
+ nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION;
+ }
+ else if( !( nNew == FetchDirection::FORWARD
+ || nNew == FetchDirection::REVERSE ) )
+ {
+ throw IllegalArgumentException();
+ }
+
+ //create PropertyChangeEvent and set value
+ PropertyChangeEvent aEvt;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.PropertyName = aPropertyName;
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = m_pMyPropSetInfo->
+ m_nFetchDirectionPropertyHandle;
+ aEvt.OldValue <<= m_nFetchDirection;
+ aEvt.NewValue <<= nNew;
+
+ m_nFetchDirection = nNew;
+ }
+
+ //send PropertyChangeEvent to listeners
+ impl_notifyPropertyChangeListeners( aEvt );
+ }
+ else if( aProp.Name == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchSize )
+ {
+ //check value
+ sal_Int32 nNew;
+ if( !( aValue >>= nNew ) )
+ {
+ throw IllegalArgumentException();
+ }
+
+ if( nNew < 0 )
+ {
+ nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE;
+ }
+
+ //create PropertyChangeEvent and set value
+ PropertyChangeEvent aEvt;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.PropertyName = aPropertyName;
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = m_pMyPropSetInfo->
+ m_nFetchSizePropertyHandle;
+ aEvt.OldValue <<= m_nFetchSize;
+ aEvt.NewValue <<= nNew;
+
+ m_nFetchSize = nNew;
+ }
+
+ //send PropertyChangeEvent to listeners
+ impl_notifyPropertyChangeListeners( aEvt );
+ }
+ else
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return;
+ }
+ }
+ m_xPropertySetOrigin->setPropertyValue( aPropertyName, aValue );
+ }
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Any SAL_CALL CachedContentResultSet
+ ::getPropertyValue( const OUString& rPropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !getPropertySetInfo().is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+
+ Property aProp = m_pMyPropSetInfo->getPropertyByName( rPropertyName );
+ //throws UnknownPropertyException, if so
+
+ Any aValue;
+ if( rPropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForCount )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aValue <<= m_nKnownCount;
+ }
+ else if( rPropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFinalCount )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aValue <<= m_bFinalCount;
+ }
+ else if( rPropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchSize )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aValue <<= m_nFetchSize;
+ }
+ else if( rPropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchDirection )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ aValue <<= m_nFetchDirection;
+ }
+ else
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+ }
+ aValue = m_xPropertySetOrigin->getPropertyValue( rPropertyName );
+ }
+ return aValue;
+}
+
+//--------------------------------------------------------------------------
+// own methods. ( inherited )
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::impl_disposing( const EventObject& rEventObject )
+ throw( RuntimeException )
+{
+ {
+ impl_EnsureNotDisposed();
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ //release all references to the broadcaster:
+ m_xFetchProvider.clear();
+ m_xFetchProviderForContentAccess.clear();
+ }
+ ContentResultSetWrapper::impl_disposing( rEventObject );
+}
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::impl_propertyChange( const PropertyChangeEvent& rEvt )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+ //---------
+
+ if( CCRS_PropertySetInfo
+ ::impl_isMyPropertyName( rEvt.PropertyName ) )
+ {
+ //don't notify foreign events on fetchsize and fetchdirection
+ if( aEvt.PropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchSize
+ || aEvt.PropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFetchDirection )
+ return;
+
+ //adjust my props 'RowCount' and 'IsRowCountFinal'
+ if( aEvt.PropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForCount )
+ {//RowCount changed
+
+ //check value
+ sal_Int32 nNew = 0;
+ if( !( aEvt.NewValue >>= nNew ) )
+ {
+ OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
+ return;
+ }
+
+ impl_changeRowCount( m_nKnownCount, nNew );
+ }
+ else if( aEvt.PropertyName == CCRS_PropertySetInfo
+ ::m_aPropertyNameForFinalCount )
+ {//IsRowCountFinal changed
+
+ //check value
+ sal_Bool bNew = sal_False;
+ if( !( aEvt.NewValue >>= bNew ) )
+ {
+ OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
+ return;
+ }
+ impl_changeIsRowCountFinal( m_bFinalCount, bNew );
+ }
+ return;
+ }
+
+ //-----------
+ impl_notifyPropertyChangeListeners( aEvt );
+}
+
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
+ throw( PropertyVetoException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //don't notify events on my properties, cause they are not vetoable
+ if( CCRS_PropertySetInfo
+ ::impl_isMyPropertyName( rEvt.PropertyName ) )
+ {
+ return;
+ }
+
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+
+ impl_notifyVetoableChangeListeners( aEvt );
+}
+
+//--------------------------------------------------------------------------
+// XContentAccess methods. ( inherited ) ( -- position dependent )
+//--------------------------------------------------------------------------
+
+#define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
+impl_EnsureNotDisposed(); \
+ReacquireableGuard aGuard( m_aMutex ); \
+sal_Int32 nRow = m_nRow; \
+sal_Int32 nFetchSize = m_nFetchSize; \
+sal_Int32 nFetchDirection = m_nFetchDirection; \
+if( !m_aCache##XXX.hasRow( nRow ) ) \
+{ \
+ if( !m_aCache##XXX.hasCausedException( nRow ) ) \
+{ \
+ if( !m_xFetchProviderForContentAccess.is() ) \
+ { \
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );\
+ throw RuntimeException(); \
+ } \
+ aGuard.clear(); \
+ if( impl_isForwardOnly() ) \
+ applyPositionToOrigin( nRow ); \
+ \
+ FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
+ } \
+ aGuard.reacquire(); \
+ if( !m_aCache##XXX.hasRow( nRow ) ) \
+ { \
+ aGuard.clear(); \
+ applyPositionToOrigin( nRow ); \
+ TYPE aRet = ContentResultSetWrapper::queryXXX(); \
+ if( m_xContentIdentifierMapping.is() ) \
+ return m_xContentIdentifierMapping->map##XXX( aRet );\
+ return aRet; \
+ } \
+} \
+return m_aCache##XXX.get##XXX( nRow );
+
+//--------------------------------------------------------------------------
+// virtual
+OUString SAL_CALL CachedContentResultSet
+ ::queryContentIdentifierString()
+ throw( RuntimeException )
+{
+ XCONTENTACCESS_queryXXX( queryContentIdentifierString, ContentIdentifierString, OUString )
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Reference< XContentIdentifier > SAL_CALL CachedContentResultSet
+ ::queryContentIdentifier()
+ throw( RuntimeException )
+{
+ XCONTENTACCESS_queryXXX( queryContentIdentifier, ContentIdentifier, Reference< XContentIdentifier > )
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Reference< XContent > SAL_CALL CachedContentResultSet
+ ::queryContent()
+ throw( RuntimeException )
+{
+ XCONTENTACCESS_queryXXX( queryContent, Content, Reference< XContent > )
+}
+
+//-----------------------------------------------------------------
+// XResultSet methods. ( inherited )
+//-----------------------------------------------------------------
+//virtual
+
+sal_Bool SAL_CALL CachedContentResultSet
+ ::next()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ //after last
+ if( m_bAfterLast )
+ return sal_False;
+ //last
+ aGuard.clear();
+ if( isLast() )
+ {
+ aGuard.reacquire();
+ m_nRow++;
+ m_bAfterLast = sal_True;
+ return sal_False;
+ }
+ aGuard.reacquire();
+ //known valid position
+ if( impl_isKnownValidPosition( m_nRow + 1 ) )
+ {
+ m_nRow++;
+ return sal_True;
+ }
+
+ //unknown position
+ sal_Int32 nRow = m_nRow;
+ aGuard.clear();
+
+ sal_Bool bValid = applyPositionToOrigin( nRow + 1 );
+
+ aGuard.reacquire();
+ m_nRow = nRow + 1;
+ m_bAfterLast = !bValid;
+ return bValid;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::previous()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ //before first ?:
+ if( !m_bAfterLast && !m_nRow )
+ return sal_False;
+ //first ?:
+ if( !m_bAfterLast && m_nKnownCount && m_nRow == 1 )
+ {
+ m_nRow--;
+ m_bAfterLast = sal_False;
+ return sal_False;
+ }
+ //known valid position ?:
+ if( impl_isKnownValidPosition( m_nRow - 1 ) )
+ {
+ m_nRow--;
+ m_bAfterLast = sal_False;
+ return sal_True;
+ }
+ //unknown position:
+ sal_Int32 nRow = m_nRow;
+ aGuard.clear();
+
+ sal_Bool bValid = applyPositionToOrigin( nRow - 1 );
+
+ aGuard.reacquire();
+ m_nRow = nRow - 1;
+ m_bAfterLast = sal_False;
+ return bValid;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::absolute( sal_Int32 row )
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !row )
+ throw SQLException();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ ReacquireableGuard aGuard( m_aMutex );
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+ if( row < 0 )
+ {
+ if( m_bFinalCount )
+ {
+ sal_Int32 nNewRow = m_nKnownCount + 1 + row;
+ sal_Bool bValid = sal_True;
+ if( nNewRow <= 0 )
+ {
+ nNewRow = 0;
+ bValid = sal_False;
+ }
+ m_nRow = nNewRow;
+ m_bAfterLast = sal_False;
+ return bValid;
+ }
+ //unknown final count:
+ aGuard.clear();
+
+ // Solaris has problems catching or propagating derived exceptions
+ // when only the base class is known, so make ResultSetException
+ // (derived from SQLException) known here:
+ sal_Bool bValid;
+ try
+ {
+ bValid = m_xResultSetOrigin->absolute( row );
+ }
+ catch (ResultSetException &)
+ {
+ throw;
+ }
+
+ aGuard.reacquire();
+ if( m_bFinalCount )
+ {
+ sal_Int32 nNewRow = m_nKnownCount + 1 + row;
+ if( nNewRow < 0 )
+ nNewRow = 0;
+ m_nLastAppliedPos = nNewRow;
+ m_nRow = nNewRow;
+ m_bAfterLastApplied = m_bAfterLast = sal_False;
+ return bValid;
+ }
+ aGuard.clear();
+
+ sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
+
+ aGuard.reacquire();
+ m_nLastAppliedPos = nCurRow;
+ m_nRow = nCurRow;
+ m_bAfterLast = sal_False;
+ return nCurRow != 0;
+ }
+ //row > 0:
+ if( m_bFinalCount )
+ {
+ if( row > m_nKnownCount )
+ {
+ m_nRow = m_nKnownCount + 1;
+ m_bAfterLast = sal_True;
+ return sal_False;
+ }
+ m_nRow = row;
+ m_bAfterLast = sal_False;
+ return sal_True;
+ }
+ //unknown new position:
+ aGuard.clear();
+
+ sal_Bool bValid = m_xResultSetOrigin->absolute( row );
+
+ aGuard.reacquire();
+ if( m_bFinalCount )
+ {
+ sal_Int32 nNewRow = row;
+ if( nNewRow > m_nKnownCount )
+ {
+ nNewRow = m_nKnownCount + 1;
+ m_bAfterLastApplied = m_bAfterLast = sal_True;
+ }
+ else
+ m_bAfterLastApplied = m_bAfterLast = sal_False;
+
+ m_nLastAppliedPos = nNewRow;
+ m_nRow = nNewRow;
+ return bValid;
+ }
+ aGuard.clear();
+
+ sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
+ sal_Bool bIsAfterLast = m_xResultSetOrigin->isAfterLast();
+
+ aGuard.reacquire();
+ m_nLastAppliedPos = nCurRow;
+ m_nRow = nCurRow;
+ m_bAfterLastApplied = m_bAfterLast = bIsAfterLast;
+ return nCurRow && !bIsAfterLast;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::relative( sal_Int32 rows )
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( m_bAfterLast || impl_isKnownInvalidPosition( m_nRow ) )
+ throw SQLException();
+
+ if( !rows )
+ return sal_True;
+
+ sal_Int32 nNewRow = m_nRow + rows;
+ if( nNewRow < 0 )
+ nNewRow = 0;
+
+ if( impl_isKnownValidPosition( nNewRow ) )
+ {
+ m_nRow = nNewRow;
+ m_bAfterLast = sal_False;
+ return sal_True;
+ }
+ else
+ {
+ //known invalid new position:
+ if( nNewRow == 0 )
+ {
+ m_bAfterLast = sal_False;
+ m_nRow = 0;
+ return sal_False;
+ }
+ if( m_bFinalCount && nNewRow > m_nKnownCount )
+ {
+ m_bAfterLast = sal_True;
+ m_nRow = m_nKnownCount + 1;
+ return sal_False;
+ }
+ //unknown new position:
+ aGuard.clear();
+ sal_Bool bValid = applyPositionToOrigin( nNewRow );
+
+ aGuard.reacquire();
+ m_nRow = nNewRow;
+ m_bAfterLast = !bValid && nNewRow > 0;
+ return bValid;
+ }
+}
+
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::first()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( impl_isKnownValidPosition( 1 ) )
+ {
+ m_nRow = 1;
+ m_bAfterLast = sal_False;
+ return sal_True;
+ }
+ if( impl_isKnownInvalidPosition( 1 ) )
+ {
+ m_nRow = 1;
+ m_bAfterLast = sal_False;
+ return sal_False;
+ }
+ //unknown position
+ aGuard.clear();
+
+ sal_Bool bValid = applyPositionToOrigin( 1 );
+
+ aGuard.reacquire();
+ m_nRow = 1;
+ m_bAfterLast = sal_False;
+ return bValid;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::last()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( m_bFinalCount )
+ {
+ m_nRow = m_nKnownCount;
+ m_bAfterLast = sal_False;
+ return m_nKnownCount != 0;
+ }
+ //unknown position
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+ aGuard.clear();
+
+ sal_Bool bValid = m_xResultSetOrigin->last();
+
+ aGuard.reacquire();
+ m_bAfterLastApplied = m_bAfterLast = sal_False;
+ if( m_bFinalCount )
+ {
+ m_nLastAppliedPos = m_nKnownCount;
+ m_nRow = m_nKnownCount;
+ return bValid;
+ }
+ aGuard.clear();
+
+ sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
+
+ aGuard.reacquire();
+ m_nLastAppliedPos = nCurRow;
+ m_nRow = nCurRow;
+ OSL_ENSURE( nCurRow >= m_nKnownCount, "position of last row < known Count, that could not be" );
+ m_nKnownCount = nCurRow;
+ m_bFinalCount = sal_True;
+ return nCurRow != 0;
+}
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::beforeFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_nRow = 0;
+ m_bAfterLast = sal_False;
+}
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::afterLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( impl_isForwardOnly() )
+ throw SQLException();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_nRow = 1;
+ m_bAfterLast = sal_True;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::isAfterLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( !m_bAfterLast )
+ return sal_False;
+ if( m_nKnownCount )
+ return m_bAfterLast;
+ if( m_bFinalCount )
+ return sal_False;
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+ aGuard.clear();
+
+ //find out whethter the original resultset contains rows or not
+ m_xResultSetOrigin->afterLast();
+
+ aGuard.reacquire();
+ m_bAfterLastApplied = sal_True;
+ aGuard.clear();
+
+ return m_xResultSetOrigin->isAfterLast();
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::isBeforeFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( m_bAfterLast )
+ return sal_False;
+ if( m_nRow )
+ return sal_False;
+ if( m_nKnownCount )
+ return !m_nRow;
+ if( m_bFinalCount )
+ return sal_False;
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+ aGuard.clear();
+
+ //find out whethter the original resultset contains rows or not
+ m_xResultSetOrigin->beforeFirst();
+
+ aGuard.reacquire();
+ m_bAfterLastApplied = sal_False;
+ m_nLastAppliedPos = 0;
+ aGuard.clear();
+
+ return m_xResultSetOrigin->isBeforeFirst();
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::isFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ sal_Int32 nRow = 0;
+ Reference< XResultSet > xResultSetOrigin;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bAfterLast )
+ return sal_False;
+ if( m_nRow != 1 )
+ return sal_False;
+ if( m_nKnownCount )
+ return m_nRow == 1;
+ if( m_bFinalCount )
+ return sal_False;
+
+ nRow = m_nRow;
+ xResultSetOrigin = m_xResultSetOrigin;
+ }
+
+ //need to ask origin
+ {
+ if( applyPositionToOrigin( nRow ) )
+ return xResultSetOrigin->isFirst();
+ else
+ return sal_False;
+ }
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::isLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ sal_Int32 nRow = 0;
+ Reference< XResultSet > xResultSetOrigin;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bAfterLast )
+ return sal_False;
+ if( m_nRow < m_nKnownCount )
+ return sal_False;
+ if( m_bFinalCount )
+ return m_nKnownCount && m_nRow == m_nKnownCount;
+
+ nRow = m_nRow;
+ xResultSetOrigin = m_xResultSetOrigin;
+ }
+
+ //need to ask origin
+ {
+ if( applyPositionToOrigin( nRow ) )
+ return xResultSetOrigin->isLast();
+ else
+ return sal_False;
+ }
+}
+
+
+//virtual
+sal_Int32 SAL_CALL CachedContentResultSet
+ ::getRow()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bAfterLast )
+ return 0;
+ return m_nRow;
+}
+
+//virtual
+void SAL_CALL CachedContentResultSet
+ ::refreshRow()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //the ContentResultSet is static and will not change
+ //therefore we don't need to reload anything
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::rowUpdated()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //the ContentResultSet is static and will not change
+ return sal_False;
+}
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::rowInserted()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //the ContentResultSet is static and will not change
+ return sal_False;
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::rowDeleted()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //the ContentResultSet is static and will not change
+ return sal_False;
+}
+
+//virtual
+Reference< XInterface > SAL_CALL CachedContentResultSet
+ ::getStatement()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ //@todo ?return anything
+ return Reference< XInterface >();
+}
+
+//-----------------------------------------------------------------
+// XRow methods. ( inherited )
+//-----------------------------------------------------------------
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::wasNull()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xRowOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bLastReadWasFromCache )
+ return m_bLastCachedReadWasNull;
+ if( !m_xRowOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return sal_False;
+ }
+ }
+ return m_xRowOrigin->wasNull();
+}
+
+//virtual
+rtl::OUString SAL_CALL CachedContentResultSet
+ ::getString( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getString, OUString );
+}
+
+//virtual
+sal_Bool SAL_CALL CachedContentResultSet
+ ::getBoolean( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBoolean, sal_Bool );
+}
+
+//virtual
+sal_Int8 SAL_CALL CachedContentResultSet
+ ::getByte( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getByte, sal_Int8 );
+}
+
+//virtual
+sal_Int16 SAL_CALL CachedContentResultSet
+ ::getShort( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getShort, sal_Int16 );
+}
+
+//virtual
+sal_Int32 SAL_CALL CachedContentResultSet
+ ::getInt( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getInt, sal_Int32 );
+}
+
+//virtual
+sal_Int64 SAL_CALL CachedContentResultSet
+ ::getLong( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getLong, sal_Int64 );
+}
+
+//virtual
+float SAL_CALL CachedContentResultSet
+ ::getFloat( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getFloat, float );
+}
+
+//virtual
+double SAL_CALL CachedContentResultSet
+ ::getDouble( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getDouble, double );
+}
+
+//virtual
+Sequence< sal_Int8 > SAL_CALL CachedContentResultSet
+ ::getBytes( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBytes, Sequence< sal_Int8 > );
+}
+
+//virtual
+Date SAL_CALL CachedContentResultSet
+ ::getDate( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getDate, Date );
+}
+
+//virtual
+Time SAL_CALL CachedContentResultSet
+ ::getTime( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getTime, Time );
+}
+
+//virtual
+DateTime SAL_CALL CachedContentResultSet
+ ::getTimestamp( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getTimestamp, DateTime );
+}
+
+//virtual
+Reference< com::sun::star::io::XInputStream >
+ SAL_CALL CachedContentResultSet
+ ::getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBinaryStream, Reference< com::sun::star::io::XInputStream > );
+}
+
+//virtual
+Reference< com::sun::star::io::XInputStream >
+ SAL_CALL CachedContentResultSet
+ ::getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getCharacterStream, Reference< com::sun::star::io::XInputStream > );
+}
+
+//virtual
+Any SAL_CALL CachedContentResultSet
+ ::getObject( sal_Int32 columnIndex,
+ const Reference<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( SQLException,
+ RuntimeException )
+{
+ //if you change this macro please pay attention to
+ //define XROW_GETXXX, where this is similar implemented
+
+ ReacquireableGuard aGuard( m_aMutex );
+ sal_Int32 nRow = m_nRow;
+ sal_Int32 nFetchSize = m_nFetchSize;
+ sal_Int32 nFetchDirection = m_nFetchDirection;
+ if( !m_aCache.hasRow( nRow ) )
+ {
+ if( !m_aCache.hasCausedException( nRow ) )
+ {
+ if( !m_xFetchProvider.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return Any();
+ }
+ aGuard.clear();
+
+ impl_fetchData( nRow, nFetchSize, nFetchDirection );
+ }
+ aGuard.reacquire();
+ if( !m_aCache.hasRow( nRow ) )
+ {
+ m_bLastReadWasFromCache = sal_False;
+ aGuard.clear();
+ applyPositionToOrigin( nRow );
+ impl_init_xRowOrigin();
+ return m_xRowOrigin->getObject( columnIndex, typeMap );
+ }
+ }
+ //@todo: pay attention to typeMap
+ const Any& rValue = m_aCache.getAny( nRow, columnIndex );
+ Any aRet;
+ m_bLastReadWasFromCache = sal_True;
+ m_bLastCachedReadWasNull = !( rValue >>= aRet );
+ return aRet;
+}
+
+//virtual
+Reference< XRef > SAL_CALL CachedContentResultSet
+ ::getRef( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getRef, Reference< XRef > );
+}
+
+//virtual
+Reference< XBlob > SAL_CALL CachedContentResultSet
+ ::getBlob( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBlob, Reference< XBlob > );
+}
+
+//virtual
+Reference< XClob > SAL_CALL CachedContentResultSet
+ ::getClob( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getClob, Reference< XClob > );
+}
+
+//virtual
+Reference< XArray > SAL_CALL CachedContentResultSet
+ ::getArray( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getArray, Reference< XArray > );
+}
+
+//-----------------------------------------------------------------
+// Type Converter Support
+//-----------------------------------------------------------------
+
+const Reference< XTypeConverter >& CachedContentResultSet::getTypeConverter()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() )
+ {
+ m_bTriedToGetTypeConverter = sal_True;
+ m_xTypeConverter = Reference< XTypeConverter >(
+ m_xSMgr->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.script.Converter" ) ),
+ UNO_QUERY );
+
+ OSL_ENSURE( m_xTypeConverter.is(),
+ "PropertyValueSet::getTypeConverter() - "
+ "Service 'com.sun.star.script.Converter' n/a!" );
+ }
+ return m_xTypeConverter;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CachedContentResultSetFactory
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedContentResultSetFactory::CachedContentResultSetFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ m_xSMgr = rSMgr;
+}
+
+CachedContentResultSetFactory::~CachedContentResultSetFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetFactory XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( CachedContentResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedContentResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetFactory XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedContentResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetFactory XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( CachedContentResultSetFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
+ OUString::createFromAscii(
+ CACHED_CONTENT_RESULTSET_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetFactory XCachedContentResultSetFactory methods.
+//--------------------------------------------------------------------------
+
+ //virtual
+Reference< XResultSet > SAL_CALL CachedContentResultSetFactory
+ ::createCachedContentResultSet(
+ const Reference< XResultSet > & xSource,
+ const Reference< XContentIdentifierMapping > & xMapping )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ Reference< XResultSet > xRet;
+ xRet = new CachedContentResultSet( m_xSMgr, xSource, xMapping );
+ return xRet;
+}
+
diff --git a/ucb/source/cacher/cachedcontentresultset.hxx b/ucb/source/cacher/cachedcontentresultset.hxx
new file mode 100644
index 000000000000..f2ab5dce2505
--- /dev/null
+++ b/ucb/source/cacher/cachedcontentresultset.hxx
@@ -0,0 +1,521 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CACHED_CONTENT_RESULTSET_HXX
+#define _CACHED_CONTENT_RESULTSET_HXX
+
+#include <contentresultsetwrapper.hxx>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ucb/XFetchProvider.hpp>
+#include <com/sun/star/ucb/XFetchProviderForContentAccess.hpp>
+#include <com/sun/star/ucb/FetchResult.hpp>
+#include <com/sun/star/ucb/XContentIdentifierMapping.hpp>
+#include <com/sun/star/ucb/XCachedContentResultSetFactory.hpp>
+
+#define CACHED_CONTENT_RESULTSET_SERVICE_NAME "com.sun.star.ucb.CachedContentResultSet"
+#define CACHED_CONTENT_RESULTSET_FACTORY_NAME "com.sun.star.ucb.CachedContentResultSetFactory"
+
+//=========================================================================
+
+namespace com { namespace sun { namespace star { namespace script {
+ class XTypeConverter;
+} } } }
+
+class CCRS_PropertySetInfo;
+class CachedContentResultSet
+ : public ContentResultSetWrapper
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+{
+ //--------------------------------------------------------------------------
+ // class CCRS_Cache
+
+ class CCRS_Cache
+ {
+ private:
+ com::sun::star::ucb::FetchResult* m_pResult;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping >
+ m_xContentIdentifierMapping;
+ com::sun::star::uno::Sequence< sal_Bool >* m_pMappedReminder;
+
+ private:
+ com::sun::star::uno::Any& SAL_CALL
+ getRowAny( sal_Int32 nRow )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL clear();
+
+
+ void SAL_CALL remindMapped( sal_Int32 nRow );
+ sal_Bool SAL_CALL isRowMapped( sal_Int32 nRow );
+ void SAL_CALL clearMappedReminder();
+ com::sun::star::uno::Sequence< sal_Bool >* SAL_CALL getMappedReminder();
+
+ public:
+ CCRS_Cache( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping > & xMapping );
+ ~CCRS_Cache();
+
+ void SAL_CALL loadData(
+ const com::sun::star::ucb::FetchResult& rResult );
+
+ sal_Bool SAL_CALL
+ hasRow( sal_Int32 nRow );
+
+ sal_Bool SAL_CALL
+ hasCausedException( sal_Int32 nRow );
+
+ sal_Int32 SAL_CALL
+ getMaxRow();
+
+ sal_Bool SAL_CALL
+ hasKnownLast();
+
+ //---
+ const com::sun::star::uno::Any& SAL_CALL
+ getAny( sal_Int32 nRow, sal_Int32 nColumnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ const rtl::OUString& SAL_CALL
+ getContentIdentifierString( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException );
+
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& SAL_CALL
+ getContentIdentifier( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException );
+
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent >& SAL_CALL
+ getContent( sal_Int32 nRow )
+ throw( com::sun::star::uno::RuntimeException );
+ };
+ //-----------------------------------------------------------------
+ //members
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xSMgr;
+
+ //different Interfaces from Origin:
+ com::sun::star::uno::Reference< com::sun::star::ucb::XFetchProvider >
+ m_xFetchProvider; //XFetchProvider-interface from m_xOrigin
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XFetchProviderForContentAccess >
+ m_xFetchProviderForContentAccess; //XFetchProviderForContentAccess-interface from m_xOrigin
+
+ //my PropertySetInfo
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >
+ m_xMyPropertySetInfo;//holds m_pMyPropSetInfo alive
+ CCRS_PropertySetInfo* m_pMyPropSetInfo;
+
+
+ //
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifierMapping >
+ m_xContentIdentifierMapping;// can be used for remote optimized ContentAccess
+
+ //some Properties and helping variables
+ sal_Int32 m_nRow;
+ sal_Bool m_bAfterLast; // TRUE, if m_nRow is after final count; can be TRUE without knowing the exact final count
+
+ sal_Int32 m_nLastAppliedPos;
+ sal_Bool m_bAfterLastApplied;
+
+ sal_Int32 m_nKnownCount; // count we know from the Origin
+ sal_Bool m_bFinalCount; // TRUE if the Origin has reached final count and we got that count in m_nKnownCount
+
+ sal_Int32 m_nFetchSize;
+ sal_Int32 m_nFetchDirection;
+
+ sal_Bool m_bLastReadWasFromCache;
+ sal_Bool m_bLastCachedReadWasNull;
+
+ //cache:
+ CCRS_Cache m_aCache;
+ CCRS_Cache m_aCacheContentIdentifierString;
+ CCRS_Cache m_aCacheContentIdentifier;
+ CCRS_Cache m_aCacheContent;
+
+
+private:
+ //-----------------------------------------------------------------
+ //helping XPropertySet methods.
+ virtual void SAL_CALL impl_initPropertySetInfo();
+
+
+ //-----------------------------------------------------------------
+ sal_Bool SAL_CALL
+ applyPositionToOrigin( sal_Int32 nRow )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ impl_fetchData( sal_Int32 nRow, sal_Int32 nCount
+ , sal_Int32 nFetchDirection )
+ throw( com::sun::star::uno::RuntimeException );
+
+ sal_Bool SAL_CALL
+ impl_isKnownValidPosition( sal_Int32 nRow );
+
+ sal_Bool SAL_CALL
+ impl_isKnownInvalidPosition( sal_Int32 nRow );
+
+ void SAL_CALL
+ impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew );
+
+ void SAL_CALL
+ impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew );
+
+public:
+ CachedContentResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &
+ xSMgr,
+ const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > & xOrigin,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping > &
+ xContentIdentifierMapping );
+
+ virtual ~CachedContentResultSet();
+
+ //-----------------------------------------------------------------
+ // XInterface inherited
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ //-----------------------------------------------------------------
+ // XPropertySet inherited
+ //-----------------------------------------------------------------
+
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // own inherited
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_propertyChange( const com::sun::star::beans::PropertyChangeEvent& evt )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_vetoableChange( const com::sun::star::beans::PropertyChangeEvent& aEvent )
+ throw( com::sun::star::beans::PropertyVetoException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XContentAccess inherited
+ //-----------------------------------------------------------------
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent()
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XResultSet inherited
+ //-----------------------------------------------------------------
+ virtual sal_Bool SAL_CALL
+ next()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isAfterLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ beforeFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ afterLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ first()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ last()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Int32 SAL_CALL
+ getRow()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ absolute( sal_Int32 row )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ relative( sal_Int32 rows )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ previous()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ refreshRow()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowUpdated()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowInserted()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowDeleted()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ getStatement()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XRow inherited
+ //-----------------------------------------------------------------
+ virtual sal_Bool SAL_CALL
+ wasNull()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getString( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ getBoolean( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int8 SAL_CALL
+ getByte( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL
+ getShort( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ getInt( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL
+ getLong( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual float SAL_CALL
+ getFloat( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual double SAL_CALL
+ getDouble( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject( sal_Int32 columnIndex,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XRef > SAL_CALL
+ getRef( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XClob > SAL_CALL
+ getClob( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XArray > SAL_CALL
+ getArray( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // Type Converter support
+ //-----------------------------------------------------------------
+
+private:
+ sal_Bool m_bTriedToGetTypeConverter;
+ com::sun::star::uno::Reference<
+ com::sun::star::script::XTypeConverter > m_xTypeConverter;
+
+ const com::sun::star::uno::Reference<
+ com::sun::star::script::XTypeConverter >& getTypeConverter();
+};
+
+//=========================================================================
+
+class CachedContentResultSetFactory
+ : public cppu::OWeakObject
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+ , public com::sun::star::ucb::XCachedContentResultSetFactory
+{
+protected:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+
+public:
+
+ CachedContentResultSetFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr);
+
+ virtual ~CachedContentResultSetFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XCachedContentResultSetFactory
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > SAL_CALL
+ createCachedContentResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > & xSource,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping > & xMapping )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+#endif
+
diff --git a/ucb/source/cacher/cachedcontentresultsetstub.cxx b/ucb/source/cacher/cachedcontentresultsetstub.cxx
new file mode 100644
index 000000000000..cb0685a020f5
--- /dev/null
+++ b/ucb/source/cacher/cachedcontentresultsetstub.cxx
@@ -0,0 +1,631 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <cachedcontentresultsetstub.hxx>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/ucb/FetchError.hpp>
+#include <osl/diagnose.h>
+
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin )
+ : ContentResultSetWrapper( xOrigin )
+ , m_nColumnCount( 0 )
+ , m_bColumnCountCached( sal_False )
+ , m_bNeedToPropagateFetchSize( sal_True )
+ , m_bFirstFetchSizePropagationDone( sal_False )
+ , m_nLastFetchSize( 1 )//this value is not important at all
+ , m_bLastFetchDirection( sal_True )//this value is not important at all
+ , m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) )
+ , m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) )
+{
+ impl_init();
+}
+
+CachedContentResultSetStub::~CachedContentResultSetStub()
+{
+ impl_deinit();
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+XINTERFACE_COMMON_IMPL( CachedContentResultSetStub )
+
+Any SAL_CALL CachedContentResultSetStub
+ ::queryInterface( const Type& rType )
+ throw ( RuntimeException )
+{
+ //list all interfaces inclusive baseclasses of interfaces
+
+ Any aRet = ContentResultSetWrapper::queryInterface( rType );
+ if( aRet.hasValue() )
+ return aRet;
+
+ aRet = cppu::queryInterface( rType
+ , static_cast< XTypeProvider* >( this )
+ , static_cast< XServiceInfo* >( this )
+ , static_cast< XFetchProvider* >( this )
+ , static_cast< XFetchProviderForContentAccess* >( this )
+ );
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+//--------------------------------------------------------------------------
+// own methods. ( inherited )
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL CachedContentResultSetStub
+ ::impl_propertyChange( const PropertyChangeEvent& rEvt )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
+ //because it will ignore them anyway and we can save this remote calls
+ if( rEvt.PropertyName == m_aPropertyNameForFetchSize
+ || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
+ return;
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+
+ impl_notifyPropertyChangeListeners( aEvt );
+}
+
+
+//virtual
+void SAL_CALL CachedContentResultSetStub
+ ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
+ throw( PropertyVetoException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
+ //because it will ignore them anyway and we can save this remote calls
+ if( rEvt.PropertyName == m_aPropertyNameForFetchSize
+ || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
+ return;
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+
+ impl_notifyVetoableChangeListeners( aEvt );
+}
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
+//list all interfaces exclusive baseclasses
+Sequence< Type > SAL_CALL CachedContentResultSetStub
+ ::getTypes()
+ throw( RuntimeException )
+{
+ static Sequence< Type >* pTypes = NULL;
+ if( !pTypes )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pTypes )
+ {
+ pTypes = new Sequence< Type >(13);
+ (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
+ (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
+ (*pTypes)[2] = CPPU_TYPE_REF( XComponent );
+ (*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
+ (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
+ (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
+ (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
+ (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
+ (*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
+ (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
+ (*pTypes)[10] = CPPU_TYPE_REF( XRow );
+ (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
+ (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
+ }
+ }
+ return *pTypes;
+ /*
+ static cppu::OTypeCollection * pCollection = 0;
+ if (!pCollection)
+ {
+ osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
+ if (!pCollection)
+ {
+ static cppu::OTypeCollection
+ aTheCollection(
+ getCppuType(
+ static_cast< Reference< XTypeProvider >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XServiceInfo >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XComponent >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XCloseable >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XResultSetMetaDataSupplier >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XPropertySet >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XPropertyChangeListener >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XVetoableChangeListener >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XResultSet >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XContentAccess >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XRow >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XFetchProvider >
+ const * >(
+ 0)),
+ getCppuType(
+ static_cast< Reference< XFetchProviderForContentAccess >
+ const * >(
+ 0))
+ );
+ pCollection = &aTheCollection;
+ }
+ }
+ return pCollection->getTypes();
+ */
+}
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedContentResultSetStub" ),
+ OUString::createFromAscii(
+ CACHED_CRS_STUB_SERVICE_NAME ) );
+
+//-----------------------------------------------------------------
+// XFetchProvider methods.
+//-----------------------------------------------------------------
+
+#define FETCH_XXX( impl_loadRow, loadInterface ) \
+impl_EnsureNotDisposed(); \
+if( !m_xResultSetOrigin.is() ) \
+{ \
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \
+ throw RuntimeException(); \
+} \
+impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
+FetchResult aRet; \
+aRet.StartIndex = nRowStartPosition; \
+aRet.Orientation = bDirection; \
+aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
+sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
+if( impl_isForwardOnly() ) \
+{ \
+ if( nOldOriginal_Pos != nRowStartPosition ) \
+ { \
+ /*@todo*/ \
+ aRet.FetchError = FetchError::EXCEPTION; \
+ return aRet; \
+ } \
+ if( nRowCount != 1 ) \
+ aRet.FetchError = FetchError::EXCEPTION; \
+ \
+ aRet.Rows.realloc( 1 ); \
+ \
+ try \
+ { \
+ impl_loadRow( aRet.Rows[0], loadInterface ); \
+ } \
+ catch( SQLException& ) \
+ { \
+ aRet.Rows.realloc( 0 ); \
+ aRet.FetchError = FetchError::EXCEPTION; \
+ return aRet; \
+ } \
+ return aRet; \
+} \
+aRet.Rows.realloc( nRowCount ); \
+sal_Bool bOldOriginal_AfterLast = sal_False; \
+if( !nOldOriginal_Pos ) \
+ bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
+sal_Int32 nN = 1; \
+sal_Bool bValidNewPos = sal_False; \
+try \
+{ \
+ try \
+ { \
+ /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
+ bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
+ } \
+ catch( SQLException& ) \
+ { \
+ aRet.Rows.realloc( 0 ); \
+ aRet.FetchError = FetchError::EXCEPTION; \
+ return aRet; \
+ } \
+ if( !bValidNewPos ) \
+ { \
+ aRet.Rows.realloc( 0 ); \
+ aRet.FetchError = FetchError::EXCEPTION; \
+ \
+ /*restore old position*/ \
+ if( nOldOriginal_Pos ) \
+ m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
+ else if( bOldOriginal_AfterLast ) \
+ m_xResultSetOrigin->afterLast(); \
+ else \
+ m_xResultSetOrigin->beforeFirst(); \
+ \
+ return aRet; \
+ } \
+ for( ; nN <= nRowCount; ) \
+ { \
+ impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
+ nN++; \
+ if( nN <= nRowCount ) \
+ { \
+ if( bDirection ) \
+ { \
+ if( !m_xResultSetOrigin->next() ) \
+ { \
+ aRet.Rows.realloc( nN-1 ); \
+ aRet.FetchError = FetchError::ENDOFDATA; \
+ break; \
+ } \
+ } \
+ else \
+ { \
+ if( !m_xResultSetOrigin->previous() ) \
+ { \
+ aRet.Rows.realloc( nN-1 ); \
+ aRet.FetchError = FetchError::ENDOFDATA; \
+ break; \
+ } \
+ } \
+ } \
+ } \
+} \
+catch( SQLException& ) \
+{ \
+ aRet.Rows.realloc( nN-1 ); \
+ aRet.FetchError = FetchError::EXCEPTION; \
+} \
+/*restore old position*/ \
+if( nOldOriginal_Pos ) \
+ m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
+else if( bOldOriginal_AfterLast ) \
+ m_xResultSetOrigin->afterLast(); \
+else \
+ m_xResultSetOrigin->beforeFirst(); \
+return aRet;
+
+FetchResult SAL_CALL CachedContentResultSetStub
+ ::fetch( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( RuntimeException )
+{
+ impl_init_xRowOrigin();
+ FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
+}
+
+sal_Int32 SAL_CALL CachedContentResultSetStub
+ ::impl_getColumnCount()
+{
+ sal_Int32 nCount;
+ sal_Bool bCached;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ nCount = m_nColumnCount;
+ bCached = m_bColumnCountCached;
+ }
+ if( !bCached )
+ {
+ try
+ {
+ Reference< XResultSetMetaData > xMetaData = getMetaData();
+ if( xMetaData.is() )
+ nCount = xMetaData->getColumnCount();
+ }
+ catch( SQLException& )
+ {
+ OSL_ENSURE( sal_False, "couldn't determine the column count" );
+ nCount = 0;
+ }
+ }
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_nColumnCount = nCount;
+ m_bColumnCountCached = sal_True;
+ return m_nColumnCount;
+}
+
+void SAL_CALL CachedContentResultSetStub
+ ::impl_getCurrentRowContent( Any& rRowContent
+ , Reference< XRow > xRow )
+ throw ( SQLException, RuntimeException )
+{
+ sal_Int32 nCount = impl_getColumnCount();
+
+ Sequence< Any > aContent( nCount );
+ for( sal_Int32 nN = 1; nN <= nCount; nN++ )
+ {
+ aContent[nN-1] = xRow->getObject( nN, NULL );
+ }
+
+ rRowContent <<= aContent;
+}
+
+void SAL_CALL CachedContentResultSetStub
+ ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
+ throw ( RuntimeException )
+{
+ //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
+
+ //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
+
+ //if the underlying ResultSet has a property FetchSize and FetchDirection,
+ //we will set these properties, if the new given parameters are different from the last ones
+
+ if( !m_bNeedToPropagateFetchSize )
+ return;
+
+ sal_Bool bNeedAction;
+ sal_Int32 nLastSize;
+ sal_Bool bLastDirection;
+ sal_Bool bFirstPropagationDone;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ bNeedAction = m_bNeedToPropagateFetchSize;
+ nLastSize = m_nLastFetchSize;
+ bLastDirection = m_bLastFetchDirection;
+ bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
+ }
+ if( bNeedAction )
+ {
+ if( nLastSize == nFetchSize
+ && bLastDirection == bFetchDirection
+ && bFirstPropagationDone == sal_True )
+ return;
+
+ if(!bFirstPropagationDone)
+ {
+ //check wether the properties 'FetchSize' and 'FetchDirection' do exist
+
+ Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
+ sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
+ sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
+
+ if(!bHasSize || !bHasDirection)
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_bNeedToPropagateFetchSize = sal_False;
+ return;
+ }
+ }
+
+ sal_Bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
+ sal_Bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_bFirstFetchSizePropagationDone = sal_True;
+ m_nLastFetchSize = nFetchSize;
+ m_bLastFetchDirection = bFetchDirection;
+ }
+
+ if( bSetSize )
+ {
+ Any aValue;
+ aValue <<= nFetchSize;
+ try
+ {
+ setPropertyValue( m_aPropertyNameForFetchSize, aValue );
+ }
+ catch( com::sun::star::uno::Exception& ) {}
+ }
+ if( bSetDirection )
+ {
+ sal_Int32 nFetchDirection = FetchDirection::FORWARD;
+ if( !bFetchDirection )
+ nFetchDirection = FetchDirection::REVERSE;
+ Any aValue;
+ aValue <<= nFetchDirection;
+ try
+ {
+ setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
+ }
+ catch( com::sun::star::uno::Exception& ) {}
+ }
+
+ }
+}
+
+//-----------------------------------------------------------------
+// XFetchProviderForContentAccess methods.
+//-----------------------------------------------------------------
+
+void SAL_CALL CachedContentResultSetStub
+ ::impl_getCurrentContentIdentifierString( Any& rAny
+ , Reference< XContentAccess > xContentAccess )
+ throw ( RuntimeException )
+{
+ rAny <<= xContentAccess->queryContentIdentifierString();
+}
+
+void SAL_CALL CachedContentResultSetStub
+ ::impl_getCurrentContentIdentifier( Any& rAny
+ , Reference< XContentAccess > xContentAccess )
+ throw ( RuntimeException )
+{
+ rAny <<= xContentAccess->queryContentIdentifier();
+}
+
+void SAL_CALL CachedContentResultSetStub
+ ::impl_getCurrentContent( Any& rAny
+ , Reference< XContentAccess > xContentAccess )
+ throw ( RuntimeException )
+{
+ rAny <<= xContentAccess->queryContent();
+}
+
+//virtual
+FetchResult SAL_CALL CachedContentResultSetStub
+ ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ impl_init_xContentAccessOrigin();
+ FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
+}
+
+//virtual
+FetchResult SAL_CALL CachedContentResultSetStub
+ ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ impl_init_xContentAccessOrigin();
+ FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
+}
+
+//virtual
+FetchResult SAL_CALL CachedContentResultSetStub
+ ::fetchContents( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ impl_init_xContentAccessOrigin();
+ FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CachedContentResultSetStubFactory
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ m_xSMgr = rSMgr;
+}
+
+CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetStubFactory XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( CachedContentResultSetStubFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedContentResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetStubFactory XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedContentResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetStubFactory XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
+ OUString::createFromAscii(
+ CACHED_CRS_STUB_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
+//--------------------------------------------------------------------------
+
+ //virtual
+Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
+ ::createCachedContentResultSetStub(
+ const Reference< XResultSet > & xSource )
+ throw( RuntimeException )
+{
+ if( xSource.is() )
+ {
+ Reference< XResultSet > xRet;
+ xRet = new CachedContentResultSetStub( xSource );
+ return xRet;
+ }
+ return NULL;
+}
+
+
diff --git a/ucb/source/cacher/cachedcontentresultsetstub.hxx b/ucb/source/cacher/cachedcontentresultsetstub.hxx
new file mode 100644
index 000000000000..59394e232dde
--- /dev/null
+++ b/ucb/source/cacher/cachedcontentresultsetstub.hxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CACHED_CONTENT_RESULTSET_STUB_HXX
+#define _CACHED_CONTENT_RESULTSET_STUB_HXX
+
+#include <contentresultsetwrapper.hxx>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ucb/XFetchProvider.hpp>
+#include <com/sun/star/ucb/XFetchProviderForContentAccess.hpp>
+#include <com/sun/star/ucb/XCachedContentResultSetStubFactory.hpp>
+
+#define CACHED_CRS_STUB_SERVICE_NAME "com.sun.star.ucb.CachedContentResultSetStub"
+#define CACHED_CRS_STUB_FACTORY_NAME "com.sun.star.ucb.CachedContentResultSetStubFactory"
+
+//=========================================================================
+
+class CachedContentResultSetStub
+ : public ContentResultSetWrapper
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+ , public com::sun::star::ucb::XFetchProvider
+ , public com::sun::star::ucb::XFetchProviderForContentAccess
+{
+private:
+ sal_Int32 m_nColumnCount;
+ sal_Bool m_bColumnCountCached;
+
+ //members to propagate fetchsize and direction:
+ sal_Bool m_bNeedToPropagateFetchSize;
+ sal_Bool m_bFirstFetchSizePropagationDone;
+ sal_Int32 m_nLastFetchSize;
+ sal_Bool m_bLastFetchDirection;
+ const rtl::OUString m_aPropertyNameForFetchSize;
+ const rtl::OUString m_aPropertyNameForFetchDirection;
+
+
+ void SAL_CALL
+ impl_getCurrentRowContent(
+ com::sun::star::uno::Any& rRowContent,
+ com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XRow > xRow )
+ throw ( com::sun::star::sdbc::SQLException
+ , com::sun::star::uno::RuntimeException );
+
+ sal_Int32 SAL_CALL
+ impl_getColumnCount();
+
+ void SAL_CALL
+ impl_getCurrentContentIdentifierString(
+ com::sun::star::uno::Any& rAny
+ , com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentAccess > xContentAccess )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ impl_getCurrentContentIdentifier(
+ com::sun::star::uno::Any& rAny
+ , com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentAccess > xContentAccess )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ impl_getCurrentContent(
+ com::sun::star::uno::Any& rAny
+ , com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentAccess > xContentAccess )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
+ throw ( com::sun::star::uno::RuntimeException );
+
+public:
+ CachedContentResultSetStub( com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > xOrigin );
+
+ virtual ~CachedContentResultSetStub();
+
+
+ //-----------------------------------------------------------------
+ // XInterface inherited
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+ //-----------------------------------------------------------------
+ // own inherited
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_propertyChange( const com::sun::star::beans::PropertyChangeEvent& evt )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_vetoableChange( const com::sun::star::beans::PropertyChangeEvent& aEvent )
+ throw( com::sun::star::beans::PropertyVetoException,
+ com::sun::star::uno::RuntimeException );
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ //-----------------------------------------------------------------
+ // XFetchProvider
+ //-----------------------------------------------------------------
+
+ virtual com::sun::star::ucb::FetchResult SAL_CALL
+ fetch( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XFetchProviderForContentAccess
+ //-----------------------------------------------------------------
+ virtual com::sun::star::ucb::FetchResult SAL_CALL
+ fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::ucb::FetchResult SAL_CALL
+ fetchContentIdentifiers( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::ucb::FetchResult SAL_CALL
+ fetchContents( sal_Int32 nRowStartPosition
+ , sal_Int32 nRowCount, sal_Bool bDirection )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+//=========================================================================
+
+class CachedContentResultSetStubFactory
+ : public cppu::OWeakObject
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+ , public com::sun::star::ucb::XCachedContentResultSetStubFactory
+{
+protected:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+
+public:
+
+ CachedContentResultSetStubFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr);
+
+ virtual ~CachedContentResultSetStubFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XCachedContentResultSetStubFactory
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > SAL_CALL
+ createCachedContentResultSetStub(
+ const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > & xSource )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+#endif
+
diff --git a/ucb/source/cacher/cacheddynamicresultset.cxx b/ucb/source/cacher/cacheddynamicresultset.cxx
new file mode 100644
index 000000000000..ad7bf9f9686c
--- /dev/null
+++ b/ucb/source/cacher/cacheddynamicresultset.cxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <cacheddynamicresultset.hxx>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <cachedcontentresultset.hxx>
+#include <osl/diagnose.h>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace rtl;
+
+CachedDynamicResultSet::CachedDynamicResultSet(
+ Reference< XDynamicResultSet > xOrigin
+ , const Reference< XContentIdentifierMapping > & xContentMapping
+ , const Reference< XMultiServiceFactory > & xSMgr )
+ : DynamicResultSetWrapper( xOrigin, xSMgr )
+ , m_xContentIdentifierMapping( xContentMapping )
+{
+ impl_init();
+}
+
+CachedDynamicResultSet::~CachedDynamicResultSet()
+{
+ impl_deinit();
+}
+
+//virtual
+void SAL_CALL CachedDynamicResultSet
+ ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
+{
+ DynamicResultSetWrapper::impl_InitResultSetOne( xResultSet );
+ OSL_ENSURE( m_xSourceResultOne.is(), "need source resultset" );
+
+ Reference< XResultSet > xCache(
+ new CachedContentResultSet( m_xSMgr, m_xSourceResultOne, m_xContentIdentifierMapping ) );
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xMyResultOne = xCache;
+}
+
+//virtual
+void SAL_CALL CachedDynamicResultSet
+ ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
+{
+ DynamicResultSetWrapper::impl_InitResultSetTwo( xResultSet );
+ OSL_ENSURE( m_xSourceResultTwo.is(), "need source resultset" );
+
+ Reference< XResultSet > xCache(
+ new CachedContentResultSet( m_xSMgr, m_xSourceResultTwo, m_xContentIdentifierMapping ) );
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xMyResultTwo = xCache;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+XINTERFACE_COMMON_IMPL( CachedDynamicResultSet )
+
+Any SAL_CALL CachedDynamicResultSet
+ ::queryInterface( const Type& rType )
+ throw ( RuntimeException )
+{
+ //list all interfaces inclusive baseclasses of interfaces
+
+ Any aRet = DynamicResultSetWrapper::queryInterface( rType );
+ if( aRet.hasValue() )
+ return aRet;
+
+ aRet = cppu::queryInterface( rType,
+ static_cast< XTypeProvider* >( this )
+ , static_cast< XServiceInfo* >( this )
+ );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+//list all interfaces exclusive baseclasses
+XTYPEPROVIDER_IMPL_4( CachedDynamicResultSet
+ , XTypeProvider
+ , XServiceInfo
+ , XDynamicResultSet
+ , XSourceInitialization
+ );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( CachedDynamicResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedDynamicResultSet" ),
+ OUString::createFromAscii(
+ CACHED_DRS_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// own methds. ( inherited )
+//--------------------------------------------------------------------------
+//virtual
+void SAL_CALL CachedDynamicResultSet
+ ::impl_disposing( const EventObject& Source )
+ throw( RuntimeException )
+{
+ DynamicResultSetWrapper::impl_disposing( Source );
+ m_xContentIdentifierMapping.clear();
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CachedDynamicResultSetFactory
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedDynamicResultSetFactory::CachedDynamicResultSetFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ m_xSMgr = rSMgr;
+}
+
+CachedDynamicResultSetFactory::~CachedDynamicResultSetFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetFactory XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( CachedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetFactory XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( CachedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetFactory XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( CachedDynamicResultSetFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedDynamicResultSetFactory" ),
+ OUString::createFromAscii(
+ CACHED_DRS_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetFactory XCachedDynamicResultSetFactory methods.
+//--------------------------------------------------------------------------
+
+//virtual
+Reference< XDynamicResultSet > SAL_CALL CachedDynamicResultSetFactory
+ ::createCachedDynamicResultSet(
+ const Reference< XDynamicResultSet > & SourceStub
+ , const Reference< XContentIdentifierMapping > & ContentIdentifierMapping )
+ throw( RuntimeException )
+{
+ Reference< XDynamicResultSet > xRet;
+ xRet = new CachedDynamicResultSet( SourceStub, ContentIdentifierMapping, m_xSMgr );
+ return xRet;
+}
+
+
diff --git a/ucb/source/cacher/cacheddynamicresultset.hxx b/ucb/source/cacher/cacheddynamicresultset.hxx
new file mode 100644
index 000000000000..ba57238e47c0
--- /dev/null
+++ b/ucb/source/cacher/cacheddynamicresultset.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CACHED_DYNAMIC_RESULTSET_HXX
+#define _CACHED_DYNAMIC_RESULTSET_HXX
+
+#include <dynamicresultsetwrapper.hxx>
+#include <com/sun/star/ucb/XContentIdentifierMapping.hpp>
+#include <com/sun/star/ucb/XCachedDynamicResultSetFactory.hpp>
+
+#define CACHED_DRS_SERVICE_NAME "com.sun.star.ucb.CachedDynamicResultSet"
+#define CACHED_DRS_FACTORY_NAME "com.sun.star.ucb.CachedDynamicResultSetFactory"
+
+//=========================================================================
+
+class CachedDynamicResultSet
+ : public DynamicResultSetWrapper
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+{
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifierMapping >
+ m_xContentIdentifierMapping;
+
+protected:
+ virtual void SAL_CALL
+ impl_InitResultSetOne( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+ virtual void SAL_CALL
+ impl_InitResultSetTwo( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+
+public:
+ CachedDynamicResultSet( com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > xOrigin
+ , const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping > & xContentMapping
+ , const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr );
+
+ virtual ~CachedDynamicResultSet();
+
+
+ //-----------------------------------------------------------------
+ // XInterface inherited
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ //-----------------------------------------------------------------
+ // own methods ( inherited )
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+//=========================================================================
+
+class CachedDynamicResultSetFactory
+ : public cppu::OWeakObject
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+ , public com::sun::star::ucb::XCachedDynamicResultSetFactory
+{
+protected:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+
+public:
+
+ CachedDynamicResultSetFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr);
+
+ virtual ~CachedDynamicResultSetFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XCachedDynamicResultSetFactory
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > SAL_CALL
+ createCachedDynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > &
+ SourceStub
+ , const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifierMapping > &
+ ContentIdentifierMapping
+ )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+#endif
+
diff --git a/ucb/source/cacher/cacheddynamicresultsetstub.cxx b/ucb/source/cacher/cacheddynamicresultsetstub.cxx
new file mode 100644
index 000000000000..09c5f029d4ac
--- /dev/null
+++ b/ucb/source/cacher/cacheddynamicresultsetstub.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <cacheddynamicresultsetstub.hxx>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <cachedcontentresultsetstub.hxx>
+#include <com/sun/star/ucb/ContentResultSetCapability.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <osl/diagnose.h>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace rtl;
+
+CachedDynamicResultSetStub::CachedDynamicResultSetStub(
+ Reference< XDynamicResultSet > xOrigin
+ , const Reference< XMultiServiceFactory > & xSMgr )
+ : DynamicResultSetWrapper( xOrigin, xSMgr )
+{
+ OSL_ENSURE( m_xSMgr.is(), "need Multiservicefactory to create stub" );
+ impl_init();
+}
+
+CachedDynamicResultSetStub::~CachedDynamicResultSetStub()
+{
+ impl_deinit();
+}
+
+//virtual
+void SAL_CALL CachedDynamicResultSetStub
+ ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
+{
+ DynamicResultSetWrapper::impl_InitResultSetOne( xResultSet );
+ OSL_ENSURE( m_xSourceResultOne.is(), "need source resultset" );
+
+ Reference< XResultSet > xStub(
+ new CachedContentResultSetStub( m_xSourceResultOne ) );
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xMyResultOne = xStub;
+}
+
+//virtual
+void SAL_CALL CachedDynamicResultSetStub
+ ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
+{
+ DynamicResultSetWrapper::impl_InitResultSetTwo( xResultSet );
+ OSL_ENSURE( m_xSourceResultTwo.is(), "need source resultset" );
+
+ Reference< XResultSet > xStub(
+ new CachedContentResultSetStub( m_xSourceResultTwo ) );
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xMyResultTwo = xStub;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+XINTERFACE_COMMON_IMPL( CachedDynamicResultSetStub )
+
+Any SAL_CALL CachedDynamicResultSetStub
+ ::queryInterface( const Type& rType )
+ throw ( RuntimeException )
+{
+ //list all interfaces inclusive baseclasses of interfaces
+
+ Any aRet = DynamicResultSetWrapper::queryInterface( rType );
+ if( aRet.hasValue() )
+ return aRet;
+
+ aRet = cppu::queryInterface( rType,
+ static_cast< XTypeProvider* >( this )
+ , static_cast< XServiceInfo* >( this )
+ );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+//list all interfaces exclusive baseclasses
+XTYPEPROVIDER_IMPL_5( CachedDynamicResultSetStub
+ , XTypeProvider
+ , XServiceInfo
+ , XDynamicResultSet
+ , XDynamicResultSetListener
+ , XSourceInitialization
+ );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( CachedDynamicResultSetStub,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedDynamicResultSetStub" ),
+ OUString::createFromAscii(
+ CACHED_DRS_STUB_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class CachedDynamicResultSetStubFactory
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+CachedDynamicResultSetStubFactory::CachedDynamicResultSetStubFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ m_xSMgr = rSMgr;
+}
+
+CachedDynamicResultSetStubFactory::~CachedDynamicResultSetStubFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetStubFactory XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( CachedDynamicResultSetStubFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedDynamicResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetStubFactory XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( CachedDynamicResultSetStubFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XCachedDynamicResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetStubFactory XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( CachedDynamicResultSetStubFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.CachedDynamicResultSetStubFactory" ),
+ OUString::createFromAscii(
+ CACHED_DRS_STUB_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedDynamicResultSetStubFactory );
+
+//--------------------------------------------------------------------------
+// CachedDynamicResultSetStubFactory XCachedDynamicResultSetStubFactory methods.
+//--------------------------------------------------------------------------
+
+//virtual
+Reference< XDynamicResultSet > SAL_CALL CachedDynamicResultSetStubFactory
+ ::createCachedDynamicResultSetStub(
+ const Reference< XDynamicResultSet > & Source )
+ throw( RuntimeException )
+{
+ Reference< XDynamicResultSet > xRet;
+ xRet = new CachedDynamicResultSetStub( Source, m_xSMgr );
+ return xRet;
+}
+
+//virtual
+void SAL_CALL CachedDynamicResultSetStubFactory
+ ::connectToCache(
+ const Reference< XDynamicResultSet > & Source
+ , const Reference< XDynamicResultSet > & TargetCache
+ , const Sequence< NumberedSortingInfo > & SortingInfo
+ , const Reference< XAnyCompareFactory > & CompareFactory
+ )
+ throw ( ListenerAlreadySetException
+ , AlreadyInitializedException
+ , RuntimeException )
+{
+ OSL_ENSURE( Source.is(), "a Source is needed" );
+ OSL_ENSURE( TargetCache.is(), "a TargetCache is needed" );
+
+ Reference< XDynamicResultSet > xSource( Source );
+ if( SortingInfo.getLength() &&
+ !( xSource->getCapabilities() & ContentResultSetCapability::SORTED )
+ )
+ {
+ Reference< XSortedDynamicResultSetFactory > xSortFactory;
+ try
+ {
+ xSortFactory = Reference< XSortedDynamicResultSetFactory >(
+ m_xSMgr->createInstance( OUString::createFromAscii(
+ "com.sun.star.ucb.SortedDynamicResultSetFactory" ) ),
+ UNO_QUERY );
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ if( xSortFactory.is() )
+ {
+ Reference< XDynamicResultSet > xSorted(
+ xSortFactory->createSortedDynamicResultSet(
+ Source, SortingInfo, CompareFactory ) );
+ if( xSorted.is() )
+ xSource = xSorted;
+ }
+ }
+
+ Reference< XDynamicResultSet > xStub(
+ new CachedDynamicResultSetStub( xSource, m_xSMgr ) );
+
+ Reference< XSourceInitialization > xTarget( TargetCache, UNO_QUERY );
+ OSL_ENSURE( xTarget.is(), "Target must have interface XSourceInitialization" );
+
+ xTarget->setSource( xStub );
+}
+
diff --git a/ucb/source/cacher/cacheddynamicresultsetstub.hxx b/ucb/source/cacher/cacheddynamicresultsetstub.hxx
new file mode 100644
index 000000000000..33608e88f4e2
--- /dev/null
+++ b/ucb/source/cacher/cacheddynamicresultsetstub.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CACHED_DYNAMIC_RESULTSET_STUB_HXX
+#define _CACHED_DYNAMIC_RESULTSET_STUB_HXX
+
+#include <dynamicresultsetwrapper.hxx>
+#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
+
+#define CACHED_DRS_STUB_SERVICE_NAME "com.sun.star.ucb.CachedDynamicResultSetStub"
+#define CACHED_DRS_STUB_FACTORY_NAME "com.sun.star.ucb.CachedDynamicResultSetStubFactory"
+
+//=========================================================================
+
+class CachedDynamicResultSetStub
+ : public DynamicResultSetWrapper
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+{
+protected:
+ virtual void SAL_CALL
+ impl_InitResultSetOne( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+ virtual void SAL_CALL
+ impl_InitResultSetTwo( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+
+public:
+ CachedDynamicResultSetStub( com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > xOrigin
+ , const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr );
+
+ virtual ~CachedDynamicResultSetStub();
+
+
+ //-----------------------------------------------------------------
+ // XInterface inherited
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+};
+
+//=========================================================================
+
+class CachedDynamicResultSetStubFactory
+ : public cppu::OWeakObject
+ , public com::sun::star::lang::XTypeProvider
+ , public com::sun::star::lang::XServiceInfo
+ , public com::sun::star::ucb::XCachedDynamicResultSetStubFactory
+{
+protected:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+
+public:
+
+ CachedDynamicResultSetStubFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr);
+
+ virtual ~CachedDynamicResultSetStubFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XCachedDynamicResultSetStubFactory
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > SAL_CALL
+ createCachedDynamicResultSetStub(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > & Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ virtual void SAL_CALL connectToCache(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > & Source
+ , const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > & TargetCache
+ , const com::sun::star::uno::Sequence<
+ com::sun::star::ucb::NumberedSortingInfo > & SortingInfo
+ , const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XAnyCompareFactory > & CompareFactory
+ )
+ throw (
+ com::sun::star::ucb::ListenerAlreadySetException
+ , com::sun::star::ucb::AlreadyInitializedException
+ , com::sun::star::uno::RuntimeException
+ );
+};
+
+#endif
+
diff --git a/ucb/source/cacher/cacheserv.cxx b/ucb/source/cacher/cacheserv.cxx
new file mode 100644
index 000000000000..3aa0f1de5357
--- /dev/null
+++ b/ucb/source/cacher/cacheserv.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <cachedcontentresultset.hxx>
+#include <cachedcontentresultsetstub.hxx>
+#include <cacheddynamicresultset.hxx>
+#include <cacheddynamicresultsetstub.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const OUString & rImplementationName,
+ Sequence< OUString > const & rServiceNames )
+{
+ OUString aKeyName( OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedContentResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ CachedContentResultSetFactory::getImplementationName_Static(),
+ CachedContentResultSetFactory::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedContentResultSetStubFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ CachedContentResultSetStubFactory::getImplementationName_Static(),
+ CachedContentResultSetStubFactory::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedDynamicResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ CachedDynamicResultSetFactory::getImplementationName_Static(),
+ CachedDynamicResultSetFactory::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedDynamicResultSetStubFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ CachedDynamicResultSetStubFactory::getImplementationName_Static(),
+ CachedDynamicResultSetStubFactory::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedContentResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( CachedContentResultSetFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = CachedContentResultSetFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedContentResultSetStubFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( CachedContentResultSetStubFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = CachedContentResultSetStubFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedDynamicResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( CachedDynamicResultSetFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = CachedDynamicResultSetFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // CachedDynamicResultSetStubFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( CachedDynamicResultSetStubFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = CachedDynamicResultSetStubFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/cacher/contentresultsetwrapper.cxx b/ucb/source/cacher/contentresultsetwrapper.cxx
new file mode 100644
index 000000000000..092fc3faf29f
--- /dev/null
+++ b/ucb/source/cacher/contentresultsetwrapper.cxx
@@ -0,0 +1,1477 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <contentresultsetwrapper.hxx>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/ucb/FetchError.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class ContentResultSetWrapper
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+ContentResultSetWrapper::ContentResultSetWrapper(
+ Reference< XResultSet > xOrigin )
+ : m_xResultSetOrigin( xOrigin )
+ , m_xRowOrigin( NULL )
+ , m_xContentAccessOrigin( NULL )
+ , m_xPropertySetOrigin( NULL )
+ , m_xPropertySetInfo( NULL )
+ , m_nForwardOnly( 2 )
+ , m_xMetaDataFromOrigin( NULL )
+ , m_bDisposed( sal_False )
+ , m_bInDispose( sal_False )
+ , m_pDisposeEventListeners( NULL )
+ , m_pPropertyChangeListeners( NULL )
+ , m_pVetoableChangeListeners( NULL )
+{
+ m_pMyListenerImpl = new ContentResultSetWrapperListener( this );
+ m_xMyListenerImpl = Reference< XPropertyChangeListener >( m_pMyListenerImpl );
+
+ OSL_ENSURE( m_xResultSetOrigin.is(), "XResultSet is required" );
+
+ //!! call impl_init() at the end of constructor of derived class
+};
+
+
+void SAL_CALL ContentResultSetWrapper::impl_init_xRowOrigin()
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if(m_xRowOrigin.is())
+ return;
+ }
+
+ Reference< XRow > xOrgig =
+ Reference< XRow >( m_xResultSetOrigin, UNO_QUERY );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xRowOrigin = xOrgig;
+ OSL_ENSURE( m_xRowOrigin.is(), "interface XRow is required" );
+ }
+}
+
+void SAL_CALL ContentResultSetWrapper::impl_init_xContentAccessOrigin()
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if(m_xContentAccessOrigin.is())
+ return;
+ }
+
+ Reference< XContentAccess > xOrgig =
+ Reference< XContentAccess >( m_xResultSetOrigin, UNO_QUERY );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xContentAccessOrigin = xOrgig;
+ OSL_ENSURE( m_xContentAccessOrigin.is(), "interface XContentAccess is required" );
+ }
+}
+
+
+void SAL_CALL ContentResultSetWrapper::impl_init_xPropertySetOrigin()
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xPropertySetOrigin.is() )
+ return;
+ }
+
+ Reference< XPropertySet > xOrig =
+ Reference< XPropertySet >( m_xResultSetOrigin, UNO_QUERY );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xPropertySetOrigin = xOrig;
+ OSL_ENSURE( m_xPropertySetOrigin.is(), "interface XPropertySet is required" );
+ }
+}
+
+void SAL_CALL ContentResultSetWrapper::impl_init()
+{
+ //call this at the end of constructor of derived class
+ //
+
+ //listen to disposing from Origin:
+ Reference< XComponent > xComponentOrigin( m_xResultSetOrigin, UNO_QUERY );
+ OSL_ENSURE( xComponentOrigin.is(), "interface XComponent is required" );
+ xComponentOrigin->addEventListener( static_cast< XPropertyChangeListener * >( m_pMyListenerImpl ) );
+}
+
+ContentResultSetWrapper::~ContentResultSetWrapper()
+{
+ //call impl_deinit() at start of destructor of derived class
+
+ delete m_pDisposeEventListeners;
+ delete m_pPropertyChangeListeners;
+ delete m_pVetoableChangeListeners;
+};
+
+void SAL_CALL ContentResultSetWrapper::impl_deinit()
+{
+ //call this at start of destructor of derived class
+ //
+ m_pMyListenerImpl->impl_OwnerDies();
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::impl_initPropertySetInfo()
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xPropertySetInfo.is() )
+ return;
+
+ impl_init_xPropertySetOrigin();
+ if( !m_xPropertySetOrigin.is() )
+ return;
+ }
+
+ Reference< XPropertySetInfo > xOrig =
+ m_xPropertySetOrigin->getPropertySetInfo();
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xPropertySetInfo = xOrig;
+ }
+}
+
+void SAL_CALL ContentResultSetWrapper
+::impl_EnsureNotDisposed()
+ throw( DisposedException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bDisposed )
+ throw DisposedException();
+}
+
+ContentResultSetWrapper::PropertyChangeListenerContainer_Impl* SAL_CALL
+ ContentResultSetWrapper
+ ::impl_getPropertyChangeListenerContainer()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_pPropertyChangeListeners )
+ m_pPropertyChangeListeners =
+ new PropertyChangeListenerContainer_Impl( m_aContainerMutex );
+ return m_pPropertyChangeListeners;
+}
+
+ContentResultSetWrapper::PropertyChangeListenerContainer_Impl* SAL_CALL
+ ContentResultSetWrapper
+ ::impl_getVetoableChangeListenerContainer()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_pVetoableChangeListeners )
+ m_pVetoableChangeListeners =
+ new PropertyChangeListenerContainer_Impl( m_aContainerMutex );
+ return m_pVetoableChangeListeners;
+}
+
+void SAL_CALL ContentResultSetWrapper
+ ::impl_notifyPropertyChangeListeners(
+ const PropertyChangeEvent& rEvt )
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_pPropertyChangeListeners )
+ return;
+ }
+
+ // Notify listeners interested especially in the changed property.
+ OInterfaceContainerHelper* pContainer =
+ m_pPropertyChangeListeners->getContainer( rEvt.PropertyName );
+ if( pContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pContainer );
+ while( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+
+ // Notify listeners interested in all properties.
+ pContainer = m_pPropertyChangeListeners->getContainer( OUString() );
+ if( pContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pContainer );
+ while( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+}
+
+void SAL_CALL ContentResultSetWrapper
+ ::impl_notifyVetoableChangeListeners( const PropertyChangeEvent& rEvt )
+ throw( PropertyVetoException,
+ RuntimeException )
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_pVetoableChangeListeners )
+ return;
+ }
+
+ // Notify listeners interested especially in the changed property.
+ OInterfaceContainerHelper* pContainer =
+ m_pVetoableChangeListeners->getContainer( rEvt.PropertyName );
+ if( pContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pContainer );
+ while( aIter.hasMoreElements() )
+ {
+ Reference< XVetoableChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if( xListener.is() )
+ xListener->vetoableChange( rEvt );
+ }
+ }
+
+ // Notify listeners interested in all properties.
+ pContainer = m_pVetoableChangeListeners->getContainer( OUString() );
+ if( pContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pContainer );
+ while( aIter.hasMoreElements() )
+ {
+ Reference< XVetoableChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if( xListener.is() )
+ xListener->vetoableChange( rEvt );
+ }
+ }
+}
+
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::impl_isForwardOnly()
+{
+ //m_nForwardOnly == 2 -> don't know
+ //m_nForwardOnly == 1 -> YES
+ //m_nForwardOnly == 0 -> NO
+
+ //@todo replace this with lines in comment
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_nForwardOnly = 0;
+ return false;
+
+
+ /*
+ ReacquireableGuard aGuard( m_aMutex );
+ if( m_nForwardOnly == 2 )
+ {
+ aGuard.clear();
+ if( !getPropertySetInfo().is() )
+ {
+ aGuard.reacquire();
+ m_nForwardOnly = 0;
+ return m_nForwardOnly;
+ }
+ aGuard.reacquire();
+
+ rtl::OUString aName = OUString::createFromAscii( "ResultSetType" );
+ //find out, if we are ForwardOnly and cache the value:
+
+ impl_init_xPropertySetOrigin();
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ m_nForwardOnly = 0;
+ return m_nForwardOnly;
+ }
+
+ aGuard.clear();
+ Any aAny = m_xPropertySetOrigin->getPropertyValue( aName );
+
+ aGuard.reacquire();
+ long nResultSetType;
+ if( ( aAny >>= nResultSetType ) &&
+ ( nResultSetType == ResultSetType::FORWARD_ONLY ) )
+ m_nForwardOnly = 1;
+ else
+ m_nForwardOnly = 0;
+ }
+ return m_nForwardOnly;
+ */
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+//list all interfaces inclusive baseclasses of interfaces
+QUERYINTERFACE_IMPL_START( ContentResultSetWrapper )
+
+ SAL_STATIC_CAST( XComponent*, this ),
+ SAL_STATIC_CAST( XCloseable*, this ),
+ SAL_STATIC_CAST( XResultSetMetaDataSupplier*, this ),
+ SAL_STATIC_CAST( XPropertySet*, this ),
+
+ SAL_STATIC_CAST( XContentAccess*, this ),
+ SAL_STATIC_CAST( XResultSet*, this ),
+ SAL_STATIC_CAST( XRow*, this )
+
+QUERYINTERFACE_IMPL_END
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::dispose() throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( m_bInDispose || m_bDisposed )
+ return;
+ m_bInDispose = sal_True;
+
+ if( m_xPropertySetOrigin.is() )
+ {
+ aGuard.clear();
+ try
+ {
+ m_xPropertySetOrigin->removePropertyChangeListener(
+ OUString(), static_cast< XPropertyChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( sal_False, "could not remove PropertyChangeListener" );
+ }
+ try
+ {
+ m_xPropertySetOrigin->removeVetoableChangeListener(
+ OUString(), static_cast< XVetoableChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( sal_False, "could not remove VetoableChangeListener" );
+ }
+
+ Reference< XComponent > xComponentOrigin( m_xResultSetOrigin, UNO_QUERY );
+ OSL_ENSURE( xComponentOrigin.is(), "interface XComponent is required" );
+ xComponentOrigin->removeEventListener( static_cast< XPropertyChangeListener * >( m_pMyListenerImpl ) );
+ }
+
+ aGuard.reacquire();
+ if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+
+ aGuard.clear();
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ aGuard.reacquire();
+ if( m_pPropertyChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+
+ aGuard.clear();
+ m_pPropertyChangeListeners->disposeAndClear( aEvt );
+ }
+
+ aGuard.reacquire();
+ if( m_pVetoableChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+
+ aGuard.clear();
+ m_pVetoableChangeListeners->disposeAndClear( aEvt );
+ }
+
+ aGuard.reacquire();
+ m_bDisposed = sal_True;
+ m_bInDispose = sal_False;
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::addEventListener( const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners =
+ new OInterfaceContainerHelper( m_aContainerMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::removeEventListener( const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+//XCloseable methods.
+//--------------------------------------------------------------------------
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::close()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ dispose();
+}
+
+//--------------------------------------------------------------------------
+//XResultSetMetaDataSupplier methods.
+//--------------------------------------------------------------------------
+//virtual
+Reference< XResultSetMetaData > SAL_CALL ContentResultSetWrapper
+ ::getMetaData()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ ReacquireableGuard aGuard( m_aMutex );
+ if( !m_xMetaDataFromOrigin.is() && m_xResultSetOrigin.is() )
+ {
+ Reference< XResultSetMetaDataSupplier > xMetaDataSupplier
+ = Reference< XResultSetMetaDataSupplier >(
+ m_xResultSetOrigin, UNO_QUERY );
+
+ if( xMetaDataSupplier.is() )
+ {
+ aGuard.clear();
+
+ Reference< XResultSetMetaData > xMetaData
+ = xMetaDataSupplier->getMetaData();
+
+ aGuard.reacquire();
+ m_xMetaDataFromOrigin = xMetaData;
+ }
+ }
+ return m_xMetaDataFromOrigin;
+}
+
+
+//--------------------------------------------------------------------------
+// XPropertySet methods.
+//--------------------------------------------------------------------------
+// virtual
+Reference< XPropertySetInfo > SAL_CALL ContentResultSetWrapper
+ ::getPropertySetInfo() throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xPropertySetInfo.is() )
+ return m_xPropertySetInfo;
+ }
+ impl_initPropertySetInfo();
+ return m_xPropertySetInfo;
+}
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xPropertySetOrigin();
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+ m_xPropertySetOrigin->setPropertyValue( rPropertyName, rValue );
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Any SAL_CALL ContentResultSetWrapper
+ ::getPropertyValue( const OUString& rPropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xPropertySetOrigin();
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+ return m_xPropertySetOrigin->getPropertyValue( rPropertyName );
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::addPropertyChangeListener(
+ const OUString& aPropertyName,
+ const Reference< XPropertyChangeListener >& xListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !getPropertySetInfo().is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+
+ if( aPropertyName.getLength() )
+ {
+ m_xPropertySetInfo->getPropertyByName( aPropertyName );
+ //throws UnknownPropertyException, if so
+ }
+
+ impl_getPropertyChangeListenerContainer();
+ sal_Bool bNeedRegister = !m_pPropertyChangeListeners->
+ getContainedTypes().getLength();
+ m_pPropertyChangeListeners->addInterface( aPropertyName, xListener );
+ if( bNeedRegister )
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return;
+ }
+ }
+ try
+ {
+ m_xPropertySetOrigin->addPropertyChangeListener(
+ OUString(), static_cast< XPropertyChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& rEx )
+ {
+ m_pPropertyChangeListeners->removeInterface( aPropertyName, xListener );
+ throw rEx;
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::addVetoableChangeListener(
+ const OUString& rPropertyName,
+ const Reference< XVetoableChangeListener >& xListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !getPropertySetInfo().is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw UnknownPropertyException();
+ }
+ if( rPropertyName.getLength() )
+ {
+ m_xPropertySetInfo->getPropertyByName( rPropertyName );
+ //throws UnknownPropertyException, if so
+ }
+
+ impl_getVetoableChangeListenerContainer();
+ sal_Bool bNeedRegister = !m_pVetoableChangeListeners->
+ getContainedTypes().getLength();
+ m_pVetoableChangeListeners->addInterface( rPropertyName, xListener );
+ if( bNeedRegister )
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return;
+ }
+ }
+ try
+ {
+ m_xPropertySetOrigin->addVetoableChangeListener(
+ OUString(), static_cast< XVetoableChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& rEx )
+ {
+ m_pVetoableChangeListeners->removeInterface( rPropertyName, xListener );
+ throw rEx;
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const Reference< XPropertyChangeListener >& xListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ {
+ //noop, if no listener registered
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_pPropertyChangeListeners )
+ return;
+ }
+ OInterfaceContainerHelper* pContainer =
+ m_pPropertyChangeListeners->getContainer( rPropertyName );
+
+ if( !pContainer )
+ {
+ if( rPropertyName.getLength() )
+ {
+ if( !getPropertySetInfo().is() )
+ throw UnknownPropertyException();
+
+ m_xPropertySetInfo->getPropertyByName( rPropertyName );
+ //throws UnknownPropertyException, if so
+ }
+ return; //the listener was not registered
+ }
+
+ m_pPropertyChangeListeners->removeInterface( rPropertyName, xListener );
+
+ if( !m_pPropertyChangeListeners->getContainedTypes().getLength() )
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return;
+ }
+ }
+ try
+ {
+ m_xPropertySetOrigin->removePropertyChangeListener(
+ OUString(), static_cast< XPropertyChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( sal_False, "could not remove PropertyChangeListener" );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL ContentResultSetWrapper
+ ::removeVetoableChangeListener(
+ const OUString& rPropertyName,
+ const Reference< XVetoableChangeListener >& xListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ {
+ //noop, if no listener registered
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_pVetoableChangeListeners )
+ return;
+ }
+ OInterfaceContainerHelper* pContainer =
+ m_pVetoableChangeListeners->getContainer( rPropertyName );
+
+ if( !pContainer )
+ {
+ if( rPropertyName.getLength() )
+ {
+ if( !getPropertySetInfo().is() )
+ throw UnknownPropertyException();
+
+ m_xPropertySetInfo->getPropertyByName( rPropertyName );
+ //throws UnknownPropertyException, if so
+ }
+ return; //the listener was not registered
+ }
+
+ m_pVetoableChangeListeners->removeInterface( rPropertyName, xListener );
+
+ if( !m_pVetoableChangeListeners->getContainedTypes().getLength() )
+ {
+ impl_init_xPropertySetOrigin();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( !m_xPropertySetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ return;
+ }
+ }
+ try
+ {
+ m_xPropertySetOrigin->removeVetoableChangeListener(
+ OUString(), static_cast< XVetoableChangeListener * >( m_pMyListenerImpl ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( sal_False, "could not remove VetoableChangeListener" );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+// own methods.
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::impl_disposing( const EventObject& )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if( !m_xResultSetOrigin.is() )
+ return;
+
+ //release all references to the broadcaster:
+ m_xResultSetOrigin.clear();
+ if(m_xRowOrigin.is())
+ m_xRowOrigin.clear();
+ if(m_xContentAccessOrigin.is())
+ m_xContentAccessOrigin.clear();
+ if(m_xPropertySetOrigin.is())
+ m_xPropertySetOrigin.clear();
+ m_xMetaDataFromOrigin.clear();
+ if(m_xPropertySetInfo.is())
+ m_xPropertySetInfo.clear();
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::impl_propertyChange( const PropertyChangeEvent& rEvt )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+ impl_notifyPropertyChangeListeners( aEvt );
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
+ throw( PropertyVetoException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ PropertyChangeEvent aEvt( rEvt );
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ aEvt.Further = sal_False;
+
+ impl_notifyVetoableChangeListeners( aEvt );
+}
+
+//--------------------------------------------------------------------------
+// XContentAccess methods. ( -- position dependent )
+//--------------------------------------------------------------------------
+
+// virtual
+OUString SAL_CALL ContentResultSetWrapper
+ ::queryContentIdentifierString()
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xContentAccessOrigin();
+ if( !m_xContentAccessOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xContentAccessOrigin->queryContentIdentifierString();
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Reference< XContentIdentifier > SAL_CALL ContentResultSetWrapper
+ ::queryContentIdentifier()
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xContentAccessOrigin();
+ if( !m_xContentAccessOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xContentAccessOrigin->queryContentIdentifier();
+}
+
+//--------------------------------------------------------------------------
+// virtual
+Reference< XContent > SAL_CALL ContentResultSetWrapper
+ ::queryContent()
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xContentAccessOrigin();
+ if( !m_xContentAccessOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xContentAccessOrigin->queryContent();
+}
+
+//-----------------------------------------------------------------
+// XResultSet methods.
+//-----------------------------------------------------------------
+//virtual
+
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::next()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->next();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::previous()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->previous();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::absolute( sal_Int32 row )
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->absolute( row );
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::relative( sal_Int32 rows )
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->relative( rows );
+}
+
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::first()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->first();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::last()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->last();
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::beforeFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ m_xResultSetOrigin->beforeFirst();
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::afterLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ m_xResultSetOrigin->afterLast();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::isAfterLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->isAfterLast();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::isBeforeFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->isBeforeFirst();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::isFirst()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->isFirst();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::isLast()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->isLast();
+}
+
+
+//virtual
+sal_Int32 SAL_CALL ContentResultSetWrapper
+ ::getRow()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->getRow();
+}
+
+//virtual
+void SAL_CALL ContentResultSetWrapper
+ ::refreshRow()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ m_xResultSetOrigin->refreshRow();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::rowUpdated()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->rowUpdated();
+}
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::rowInserted()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->rowInserted();
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::rowDeleted()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( !m_xResultSetOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xResultSetOrigin->rowDeleted();
+}
+
+//virtual
+Reference< XInterface > SAL_CALL ContentResultSetWrapper
+ ::getStatement()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ //@todo ?return anything
+ return Reference< XInterface >();
+}
+
+//-----------------------------------------------------------------
+// XRow methods.
+//-----------------------------------------------------------------
+
+#define XROW_GETXXX( getXXX ) \
+impl_EnsureNotDisposed(); \
+impl_init_xRowOrigin(); \
+if( !m_xRowOrigin.is() ) \
+{ \
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );\
+ throw RuntimeException(); \
+} \
+return m_xRowOrigin->getXXX( columnIndex );
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::wasNull()
+ throw( SQLException,
+ RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ impl_init_xRowOrigin();
+ if( !m_xRowOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xRowOrigin->wasNull();
+}
+
+//virtual
+rtl::OUString SAL_CALL ContentResultSetWrapper
+ ::getString( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getString );
+}
+
+//virtual
+sal_Bool SAL_CALL ContentResultSetWrapper
+ ::getBoolean( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBoolean );
+}
+
+//virtual
+sal_Int8 SAL_CALL ContentResultSetWrapper
+ ::getByte( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getByte );
+}
+
+//virtual
+sal_Int16 SAL_CALL ContentResultSetWrapper
+ ::getShort( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getShort );
+}
+
+//virtual
+sal_Int32 SAL_CALL ContentResultSetWrapper
+ ::getInt( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getInt );
+}
+
+//virtual
+sal_Int64 SAL_CALL ContentResultSetWrapper
+ ::getLong( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getLong );
+}
+
+//virtual
+float SAL_CALL ContentResultSetWrapper
+ ::getFloat( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getFloat );
+}
+
+//virtual
+double SAL_CALL ContentResultSetWrapper
+ ::getDouble( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getDouble );
+}
+
+//virtual
+Sequence< sal_Int8 > SAL_CALL ContentResultSetWrapper
+ ::getBytes( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBytes );
+}
+
+//virtual
+Date SAL_CALL ContentResultSetWrapper
+ ::getDate( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getDate );
+}
+
+//virtual
+Time SAL_CALL ContentResultSetWrapper
+ ::getTime( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getTime );
+}
+
+//virtual
+DateTime SAL_CALL ContentResultSetWrapper
+ ::getTimestamp( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getTimestamp );
+}
+
+//virtual
+Reference< com::sun::star::io::XInputStream >
+ SAL_CALL ContentResultSetWrapper
+ ::getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBinaryStream );
+}
+
+//virtual
+Reference< com::sun::star::io::XInputStream >
+ SAL_CALL ContentResultSetWrapper
+ ::getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getCharacterStream );
+}
+
+//virtual
+Any SAL_CALL ContentResultSetWrapper
+ ::getObject( sal_Int32 columnIndex,
+ const Reference<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( SQLException,
+ RuntimeException )
+{
+ //if you change this macro please pay attention to
+ //define XROW_GETXXX, where this is similar implemented
+
+ impl_EnsureNotDisposed();
+ impl_init_xRowOrigin();
+ if( !m_xRowOrigin.is() )
+ {
+ OSL_ENSURE( sal_False, "broadcaster was disposed already" );
+ throw RuntimeException();
+ }
+ return m_xRowOrigin->getObject( columnIndex, typeMap );
+}
+
+//virtual
+Reference< XRef > SAL_CALL ContentResultSetWrapper
+ ::getRef( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getRef );
+}
+
+//virtual
+Reference< XBlob > SAL_CALL ContentResultSetWrapper
+ ::getBlob( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getBlob );
+}
+
+//virtual
+Reference< XClob > SAL_CALL ContentResultSetWrapper
+ ::getClob( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getClob );
+}
+
+//virtual
+Reference< XArray > SAL_CALL ContentResultSetWrapper
+ ::getArray( sal_Int32 columnIndex )
+ throw( SQLException,
+ RuntimeException )
+{
+ XROW_GETXXX( getArray );
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class ContentResultSetWrapperListener
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+ContentResultSetWrapperListener::ContentResultSetWrapperListener(
+ ContentResultSetWrapper* pOwner )
+ : m_pOwner( pOwner )
+{
+}
+
+ContentResultSetWrapperListener::~ContentResultSetWrapperListener()
+{
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+//list all interfaces inclusive baseclasses of interfaces
+XINTERFACE_COMMON_IMPL( ContentResultSetWrapperListener )
+QUERYINTERFACE_IMPL_START( ContentResultSetWrapperListener )
+
+ static_cast< XEventListener * >(
+ static_cast< XPropertyChangeListener * >(this))
+ , SAL_STATIC_CAST( XPropertyChangeListener*, this )
+ , SAL_STATIC_CAST( XVetoableChangeListener*, this )
+
+QUERYINTERFACE_IMPL_END
+
+
+//--------------------------------------------------------------------------
+//XEventListener methods.
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL ContentResultSetWrapperListener
+ ::disposing( const EventObject& rEventObject )
+ throw( RuntimeException )
+{
+ if( m_pOwner )
+ m_pOwner->impl_disposing( rEventObject );
+}
+
+//--------------------------------------------------------------------------
+//XPropertyChangeListener methods.
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL ContentResultSetWrapperListener
+ ::propertyChange( const PropertyChangeEvent& rEvt )
+ throw( RuntimeException )
+{
+ if( m_pOwner )
+ m_pOwner->impl_propertyChange( rEvt );
+}
+
+//--------------------------------------------------------------------------
+//XVetoableChangeListener methods.
+//--------------------------------------------------------------------------
+//virtual
+void SAL_CALL ContentResultSetWrapperListener
+ ::vetoableChange( const PropertyChangeEvent& rEvt )
+ throw( PropertyVetoException,
+ RuntimeException )
+{
+ if( m_pOwner )
+ m_pOwner->impl_vetoableChange( rEvt );
+}
+
+void SAL_CALL ContentResultSetWrapperListener
+ ::impl_OwnerDies()
+{
+ m_pOwner = NULL;
+}
+
diff --git a/ucb/source/cacher/contentresultsetwrapper.hxx b/ucb/source/cacher/contentresultsetwrapper.hxx
new file mode 100644
index 000000000000..b3608aca6f96
--- /dev/null
+++ b/ucb/source/cacher/contentresultsetwrapper.hxx
@@ -0,0 +1,587 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONTENT_RESULTSET_WRAPPER_HXX
+#define _CONTENT_RESULTSET_WRAPPER_HXX
+
+#include <rtl/ustring.hxx>
+#include <ucbhelper/macros.hxx>
+#include <osl/mutex.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/interfacecontainer.hxx>
+
+//=========================================================================
+
+class ContentResultSetWrapperListener;
+class ContentResultSetWrapper
+ : public cppu::OWeakObject
+ , public com::sun::star::lang::XComponent
+ , public com::sun::star::sdbc::XCloseable
+ , public com::sun::star::sdbc::XResultSetMetaDataSupplier
+ , public com::sun::star::beans::XPropertySet
+ , public com::sun::star::ucb::XContentAccess
+ , public com::sun::star::sdbc::XResultSet
+ , public com::sun::star::sdbc::XRow
+{
+protected:
+
+ //--------------------------------------------------------------------------
+ //class PropertyChangeListenerContainer_Impl.
+
+ struct equalStr_Impl
+ {
+ bool operator()( const rtl::OUString& s1, const rtl::OUString& s2 ) const
+ {
+ return !!( s1 == s2 );
+ }
+ };
+
+ struct hashStr_Impl
+ {
+ size_t operator()( const rtl::OUString& rName ) const
+ {
+ return rName.hashCode();
+ }
+ };
+
+ typedef cppu::OMultiTypeInterfaceContainerHelperVar
+ < rtl::OUString , hashStr_Impl , equalStr_Impl >
+ PropertyChangeListenerContainer_Impl;
+ //--------------------------------------------------------------------------
+ // class ReacquireableGuard
+
+ class ReacquireableGuard
+ {
+ protected:
+ osl::Mutex* pT;
+ public:
+
+ ReacquireableGuard(osl::Mutex * t) : pT(t)
+ {
+ pT->acquire();
+ }
+
+ ReacquireableGuard(osl::Mutex& t) : pT(&t)
+ {
+ pT->acquire();
+ }
+
+ /** Releases mutex. */
+ ~ReacquireableGuard()
+ {
+ if (pT)
+ pT->release();
+ }
+
+ /** Releases mutex. */
+ void clear()
+ {
+ if(pT)
+ {
+ pT->release();
+ pT = NULL;
+ }
+ }
+
+ /** Reacquire mutex. */
+ void reacquire()
+ {
+ if(pT)
+ {
+ pT->acquire();
+ }
+ }
+ };
+
+ //-----------------------------------------------------------------
+ //members
+
+ //my Mutex
+ osl::Mutex m_aMutex;
+
+ //different Interfaces from Origin:
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ m_xResultSetOrigin;
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ m_xRowOrigin; //XRow-interface from m_xOrigin
+ //!! call impl_init_xRowOrigin() bevor you access this member
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentAccess >
+ m_xContentAccessOrigin; //XContentAccess-interface from m_xOrigin
+ //!! call impl_init_xContentAccessOrigin() bevor you access this member
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >
+ m_xPropertySetOrigin; //XPropertySet-interface from m_xOrigin
+ //!! call impl_init_xPropertySetOrigin() bevor you access this member
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >
+ m_xPropertySetInfo;
+ //call impl_initPropertySetInfo() bevor you access this member
+
+ sal_Int32 m_nForwardOnly;
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >
+ m_xMyListenerImpl;
+ ContentResultSetWrapperListener*
+ m_pMyListenerImpl;
+
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData >
+ m_xMetaDataFromOrigin; //XResultSetMetaData from m_xOrigin
+
+ //management of listeners
+ sal_Bool m_bDisposed; ///Dispose call ready.
+ sal_Bool m_bInDispose;///In dispose call
+ osl::Mutex m_aContainerMutex;
+ cppu::OInterfaceContainerHelper*
+ m_pDisposeEventListeners;
+ PropertyChangeListenerContainer_Impl*
+ m_pPropertyChangeListeners;
+ PropertyChangeListenerContainer_Impl*
+ m_pVetoableChangeListeners;
+
+ //-----------------------------------------------------------------
+ //methods:
+private:
+ PropertyChangeListenerContainer_Impl* SAL_CALL
+ impl_getPropertyChangeListenerContainer();
+
+ PropertyChangeListenerContainer_Impl* SAL_CALL
+ impl_getVetoableChangeListenerContainer();
+
+protected:
+ //-----------------------------------------------------------------
+
+ ContentResultSetWrapper( com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet > xOrigin );
+
+ virtual ~ContentResultSetWrapper();
+
+ void SAL_CALL impl_init();
+ void SAL_CALL impl_deinit();
+
+ //--
+
+ void SAL_CALL impl_init_xRowOrigin();
+ void SAL_CALL impl_init_xContentAccessOrigin();
+ void SAL_CALL impl_init_xPropertySetOrigin();
+
+ //--
+
+ virtual void SAL_CALL impl_initPropertySetInfo(); //helping XPropertySet
+
+ void SAL_CALL
+ impl_EnsureNotDisposed()
+ throw( com::sun::star::lang::DisposedException,
+ com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ impl_notifyPropertyChangeListeners(
+ const com::sun::star::beans::PropertyChangeEvent& rEvt );
+
+ void SAL_CALL
+ impl_notifyVetoableChangeListeners(
+ const com::sun::star::beans::PropertyChangeEvent& rEvt )
+ throw( com::sun::star::beans::PropertyVetoException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Bool SAL_CALL impl_isForwardOnly();
+
+public:
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type & rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XComponent
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ dispose() throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ //XCloseable
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ close()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ //XResultSetMetaDataSupplier
+ //-----------------------------------------------------------------
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSetMetaData > SAL_CALL
+ getMetaData()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XPropertySet
+ //-----------------------------------------------------------------
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addPropertyChangeListener( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removePropertyChangeListener( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addVetoableChangeListener( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeVetoableChangeListener( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // own methods
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_propertyChange( const com::sun::star::beans::PropertyChangeEvent& evt )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_vetoableChange( const com::sun::star::beans::PropertyChangeEvent& aEvent )
+ throw( com::sun::star::beans::PropertyVetoException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XContentAccess
+ //-----------------------------------------------------------------
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent()
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XResultSet
+ //-----------------------------------------------------------------
+ virtual sal_Bool SAL_CALL
+ next()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isAfterLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ beforeFirst()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ afterLast()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ first()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ last()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Int32 SAL_CALL
+ getRow()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ absolute( sal_Int32 row )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ relative( sal_Int32 rows )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ previous()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ refreshRow()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowUpdated()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowInserted()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ rowDeleted()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ getStatement()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XRow
+ //-----------------------------------------------------------------
+ virtual sal_Bool SAL_CALL
+ wasNull()
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getString( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ getBoolean( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int8 SAL_CALL
+ getByte( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL
+ getShort( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ getInt( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL
+ getLong( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual float SAL_CALL
+ getFloat( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual double SAL_CALL
+ getDouble( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject( sal_Int32 columnIndex,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XRef > SAL_CALL
+ getRef( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XClob > SAL_CALL
+ getClob( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XArray > SAL_CALL
+ getArray( sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+};
+
+//=========================================================================
+
+class ContentResultSetWrapperListener
+ : public cppu::OWeakObject
+ , public com::sun::star::beans::XPropertyChangeListener
+ , public com::sun::star::beans::XVetoableChangeListener
+{
+protected:
+ ContentResultSetWrapper* m_pOwner;
+
+public:
+ ContentResultSetWrapperListener( ContentResultSetWrapper* pOwner );
+
+ virtual ~ContentResultSetWrapperListener();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ //XEventListener
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ //XPropertyChangeListener
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ propertyChange( const com::sun::star::beans::PropertyChangeEvent& evt )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ //XVetoableChangeListener
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ vetoableChange( const com::sun::star::beans::PropertyChangeEvent& aEvent )
+ throw( com::sun::star::beans::PropertyVetoException,
+ com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ void SAL_CALL impl_OwnerDies();
+};
+
+#endif
+
diff --git a/ucb/source/cacher/dynamicresultsetwrapper.cxx b/ucb/source/cacher/dynamicresultsetwrapper.cxx
new file mode 100644
index 000000000000..ab98c97bc4e2
--- /dev/null
+++ b/ucb/source/cacher/dynamicresultsetwrapper.cxx
@@ -0,0 +1,528 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <dynamicresultsetwrapper.hxx>
+#include <ucbhelper/macros.hxx>
+#include <osl/diagnose.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
+#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace rtl;
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class DynamicResultSetWrapper
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+DynamicResultSetWrapper::DynamicResultSetWrapper(
+ Reference< XDynamicResultSet > xOrigin
+ , const Reference< XMultiServiceFactory > & xSMgr )
+
+ : m_bDisposed( sal_False )
+ , m_bInDispose( sal_False )
+ , m_pDisposeEventListeners( NULL )
+ , m_xSMgr( xSMgr )
+ , m_bStatic( sal_False )
+ , m_bGotWelcome( sal_False )
+ , m_xSource( xOrigin )
+ , m_xSourceResultOne( NULL )
+ , m_xSourceResultTwo( NULL )
+ // , m_xSourceResultCurrent( NULL )
+ // , m_bUseOne( NULL )
+ , m_xMyResultOne( NULL )
+ , m_xMyResultTwo( NULL )
+ , m_xListener( NULL )
+{
+ m_pMyListenerImpl = new DynamicResultSetWrapperListener( this );
+ m_xMyListenerImpl = Reference< XDynamicResultSetListener >( m_pMyListenerImpl );
+ //call impl_init() at the end of constructor of derived class
+};
+
+void SAL_CALL DynamicResultSetWrapper::impl_init()
+{
+ //call this at the end of constructor of derived class
+ //
+
+ Reference< XDynamicResultSet > xSource = NULL;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xSource = m_xSource;
+ m_xSource = NULL;
+ }
+ if( xSource.is() )
+ setSource( xSource );
+}
+
+DynamicResultSetWrapper::~DynamicResultSetWrapper()
+{
+ //call impl_deinit() at start of destructor of derived class
+
+ delete m_pDisposeEventListeners;
+};
+
+void SAL_CALL DynamicResultSetWrapper::impl_deinit()
+{
+ //call this at start of destructor of derived class
+ //
+ m_pMyListenerImpl->impl_OwnerDies();
+}
+
+void SAL_CALL DynamicResultSetWrapper
+::impl_EnsureNotDisposed()
+ throw( DisposedException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bDisposed )
+ throw DisposedException();
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
+ m_xSourceResultOne = xResultSet;
+ m_xMyResultOne = xResultSet;
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
+ m_xSourceResultTwo = xResultSet;
+ m_xMyResultTwo = xResultSet;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+//list all interfaces inclusive baseclasses of interfaces
+QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
+ SAL_STATIC_CAST( XComponent*, this ) //base of XDynamicResultSet
+ , SAL_STATIC_CAST( XDynamicResultSet*, this )
+ , SAL_STATIC_CAST( XSourceInitialization*, this )
+QUERYINTERFACE_IMPL_END
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::dispose() throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ Reference< XComponent > xSourceComponent;
+ {
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+ if( m_bInDispose || m_bDisposed )
+ return;
+ m_bInDispose = sal_True;
+
+ xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);
+
+ if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+
+ aGuard.clear();
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+ }
+
+ /* //@todo ?? ( only if java collection needs to long )
+ if( xSourceComponent.is() )
+ xSourceComponent->dispose();
+ */
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_bDisposed = sal_True;
+ m_bInDispose = sal_False;
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::addEventListener( const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners =
+ new OInterfaceContainerHelper( m_aContainerMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::removeEventListener( const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// own methods
+//--------------------------------------------------------------------------
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::impl_disposing( const EventObject& )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if( !m_xSource.is() )
+ return;
+
+ //release all references to the broadcaster:
+ m_xSource.clear();
+ m_xSourceResultOne.clear();//?? or only when not static??
+ m_xSourceResultTwo.clear();//??
+ //@todo m_xMyResultOne.clear(); ???
+ //@todo m_xMyResultTwo.clear(); ???
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::impl_notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ //@todo
+ /*
+ <p>The Listener is allowed to blockade this call, until he really want to go
+ to the new version. The only situation, where the listener has to return the
+ update call at once is, while he disposes his broadcaster or while he is
+ removing himsef as listener (otherwise you deadlock)!!!
+ */
+ // handle the actions in the list
+
+ ListEvent aNewEvent;
+ aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
+ aNewEvent.Changes = Changes.Changes;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
+ {
+ ListAction& rAction = aNewEvent.Changes[i];
+ switch( rAction.ListActionType )
+ {
+ case ListActionType::WELCOME:
+ {
+ WelcomeDynamicResultSetStruct aWelcome;
+ if( rAction.ActionInfo >>= aWelcome )
+ {
+ impl_InitResultSetOne( aWelcome.Old );
+ impl_InitResultSetTwo( aWelcome.New );
+ m_bGotWelcome = sal_True;
+
+ aWelcome.Old = m_xMyResultOne;
+ aWelcome.New = m_xMyResultTwo;
+
+ rAction.ActionInfo <<= aWelcome;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
+ //throw RuntimeException();
+ }
+ break;
+ }
+ }
+ }
+ OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
+ }
+
+ if( !m_xListener.is() )
+ m_aListenerSet.wait();
+ m_xListener->notify( aNewEvent );
+
+ /*
+ m_bUseOne = !m_bUseOne;
+ if( m_bUseOne )
+ m_xSourceResultCurrent = m_xSourceResultOne;
+ else
+ m_xSourceResultCurrent = m_xSourceResultTwo;
+ */
+}
+
+//--------------------------------------------------------------------------
+// XSourceInitialization
+//--------------------------------------------------------------------------
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::setSource( const Reference< XInterface > & Source )
+ throw( AlreadyInitializedException, RuntimeException )
+{
+ impl_EnsureNotDisposed();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xSource.is() )
+ {
+ throw AlreadyInitializedException();
+ }
+ }
+
+ Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
+ OSL_ENSURE( xSourceDynamic.is(),
+ "the given source is not of required type XDynamicResultSet" );
+
+ Reference< XDynamicResultSetListener > xListener = NULL;
+ Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
+
+ sal_Bool bStatic = sal_False;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xSource = xSourceDynamic;
+ xListener = m_xListener;
+ bStatic = m_bStatic;
+ xMyListenerImpl = m_xMyListenerImpl;
+ }
+ if( xListener.is() )
+ xSourceDynamic->setListener( m_xMyListenerImpl );
+ else if( bStatic )
+ {
+ Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
+ xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
+ }
+ m_aSourceSet.set();
+}
+
+//--------------------------------------------------------------------------
+// XDynamicResultSet
+//--------------------------------------------------------------------------
+//virtual
+Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
+ ::getStaticResultSet()
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ Reference< XDynamicResultSet > xSource = NULL;
+ Reference< XEventListener > xMyListenerImpl = NULL;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xListener.is() )
+ throw ListenerAlreadySetException();
+
+ xSource = m_xSource;
+ m_bStatic = sal_True;
+ xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
+ }
+
+ if( xSource.is() )
+ {
+ Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
+ xSourceComponent->addEventListener( xMyListenerImpl );
+ }
+ if( !xSource.is() )
+ m_aSourceSet.wait();
+
+
+ Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
+ impl_InitResultSetOne( xResultSet );
+ return m_xMyResultOne;
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::setListener( const Reference<
+ XDynamicResultSetListener > & Listener )
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ Reference< XDynamicResultSet > xSource = NULL;
+ Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if( m_xListener.is() )
+ throw ListenerAlreadySetException();
+ if( m_bStatic )
+ throw ListenerAlreadySetException();
+
+ m_xListener = Listener;
+ addEventListener( Reference< XEventListener >::query( Listener ) );
+
+ xSource = m_xSource;
+ xMyListenerImpl = m_xMyListenerImpl;
+ }
+ if ( xSource.is() )
+ xSource->setListener( xMyListenerImpl );
+
+ m_aListenerSet.set();
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapper
+ ::connectToCache( const Reference< XDynamicResultSet > & xCache )
+ throw( ListenerAlreadySetException, AlreadyInitializedException, ServiceNotFoundException, RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ if( m_xListener.is() )
+ throw ListenerAlreadySetException();
+ if( m_bStatic )
+ throw ListenerAlreadySetException();
+
+ Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
+ OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
+ if( xTarget.is() && m_xSMgr.is() )
+ {
+ //@todo m_aSourceSet.wait();?
+
+ Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
+ try
+ {
+ xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
+ m_xSMgr->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
+ UNO_QUERY );
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ if( xStubFactory.is() )
+ {
+ xStubFactory->connectToCache(
+ this, xCache, Sequence< NumberedSortingInfo > (), NULL );
+ return;
+ }
+ }
+ OSL_ENSURE( sal_False, "could not connect to cache" );
+ throw ServiceNotFoundException();
+}
+
+//virtual
+sal_Int16 SAL_CALL DynamicResultSetWrapper
+ ::getCapabilities()
+ throw( RuntimeException )
+{
+ impl_EnsureNotDisposed();
+
+ m_aSourceSet.wait();
+ Reference< XDynamicResultSet > xSource = NULL;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xSource = m_xSource;
+ }
+ return xSource->getCapabilities();
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// class DynamicResultSetWrapperListener
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
+ DynamicResultSetWrapper* pOwner )
+ : m_pOwner( pOwner )
+{
+
+}
+
+DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
+{
+
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+//list all interfaces inclusive baseclasses of interfaces
+XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
+ , XDynamicResultSetListener
+ , XEventListener //base of XDynamicResultSetListener
+ );
+
+//--------------------------------------------------------------------------
+// XDynamicResultSetListener methods:
+//--------------------------------------------------------------------------
+//virtual
+void SAL_CALL DynamicResultSetWrapperListener
+ ::disposing( const EventObject& rEventObject )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if( m_pOwner )
+ m_pOwner->impl_disposing( rEventObject );
+}
+
+//virtual
+void SAL_CALL DynamicResultSetWrapperListener
+ ::notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if( m_pOwner )
+ m_pOwner->impl_notify( Changes );
+}
+
+//--------------------------------------------------------------------------
+// own methods:
+//--------------------------------------------------------------------------
+
+void SAL_CALL DynamicResultSetWrapperListener
+ ::impl_OwnerDies()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ m_pOwner = NULL;
+}
+
diff --git a/ucb/source/cacher/dynamicresultsetwrapper.hxx b/ucb/source/cacher/dynamicresultsetwrapper.hxx
new file mode 100644
index 000000000000..47ff822a6ce1
--- /dev/null
+++ b/ucb/source/cacher/dynamicresultsetwrapper.hxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DYNAMIC_RESULTSET_WRAPPER_HXX
+#define _DYNAMIC_RESULTSET_WRAPPER_HXX
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <ucbhelper/macros.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XSourceInitialization.hpp>
+
+#ifndef __com_sun_star_lang_DisposedException_idl__
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#include <com/sun/star/ucb/XDynamicResultSetListener.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//#define CACHED_CRS_STUB_SERVICE_NAME "com.sun.star.ucb.CachedContentResultSetStub"
+//#define CACHED_CRS_STUB_FACTORY_NAME "com.sun.star.ucb.CachedContentResultSetStubFactory"
+
+//=========================================================================
+
+class DynamicResultSetWrapperListener;
+class DynamicResultSetWrapper
+ : public cppu::OWeakObject
+ , public com::sun::star::ucb::XDynamicResultSet
+ , public com::sun::star::ucb::XSourceInitialization
+{
+private:
+ //management of listeners
+ sal_Bool m_bDisposed; ///Dispose call ready.
+ sal_Bool m_bInDispose;///In dispose call
+ osl::Mutex m_aContainerMutex;
+ cppu::OInterfaceContainerHelper*
+ m_pDisposeEventListeners;
+protected:
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSetListener >
+ m_xMyListenerImpl;
+ DynamicResultSetWrapperListener*
+ m_pMyListenerImpl;
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xSMgr;
+
+ osl::Mutex m_aMutex;
+ sal_Bool m_bStatic;
+ sal_Bool m_bGotWelcome;
+
+ //different Interfaces from Origin:
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet >
+ m_xSource;
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ m_xSourceResultOne;
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ m_xSourceResultTwo;
+ //com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ // m_xSourceResultCurrent;
+ //sal_Bool m_bUseOne;
+ //
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ m_xMyResultOne;
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet >
+ m_xMyResultTwo;
+ //
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSetListener >
+ m_xListener;
+
+ osl::Condition m_aSourceSet;
+ osl::Condition m_aListenerSet;
+
+protected:
+ void SAL_CALL impl_init();
+ void SAL_CALL impl_deinit();
+ void SAL_CALL
+ impl_EnsureNotDisposed()
+ throw( com::sun::star::lang::DisposedException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_InitResultSetOne( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+ virtual void SAL_CALL
+ impl_InitResultSetTwo( const com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSet >& xResultSet );
+
+public:
+
+ DynamicResultSetWrapper(
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > xOrigin
+ , const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr );
+
+ virtual ~DynamicResultSetWrapper();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type & rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XDynamicResultSet
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > SAL_CALL
+ getStaticResultSet()
+ throw( com::sun::star::ucb::ListenerAlreadySetException
+ , com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ setListener( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSetListener > & Listener )
+ throw( com::sun::star::ucb::ListenerAlreadySetException
+ , com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ connectToCache( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSet > & xCache )
+ throw( com::sun::star::ucb::ListenerAlreadySetException
+ , com::sun::star::ucb::AlreadyInitializedException
+ , com::sun::star::ucb::ServiceNotFoundException
+ , com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL
+ getCapabilities() throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XComponent ( base of XDynamicResultSet )
+ virtual void SAL_CALL
+ dispose() throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // XSourceInitialization
+
+ virtual void SAL_CALL
+ setSource( const com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > & Source )
+ throw( com::sun::star::ucb::AlreadyInitializedException
+ , com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ virtual void SAL_CALL
+ impl_disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ impl_notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+//=========================================================================
+
+class DynamicResultSetWrapperListener
+ : public cppu::OWeakObject
+ , public com::sun::star::ucb::XDynamicResultSetListener
+{
+protected:
+ DynamicResultSetWrapper* m_pOwner;
+ osl::Mutex m_aMutex;
+
+public:
+ DynamicResultSetWrapperListener( DynamicResultSetWrapper* pOwner );
+
+ virtual ~DynamicResultSetWrapperListener();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XEventListener ( base of XDynamicResultSetListener )
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+ //-----------------------------------------------------------------
+ // XDynamicResultSetListener
+ virtual void SAL_CALL
+ notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ void SAL_CALL impl_OwnerDies();
+};
+
+
+#endif
+
diff --git a/ucb/source/cacher/makefile.mk b/ucb/source/cacher/makefile.mk
new file mode 100644
index 000000000000..600fefc174f7
--- /dev/null
+++ b/ucb/source/cacher/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=ucb
+TARGET=cached
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCB_MAJOR=1
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/contentresultsetwrapper.obj \
+ $(SLO)$/cachedcontentresultsetstub.obj \
+ $(SLO)$/cachedcontentresultset.obj \
+ $(SLO)$/dynamicresultsetwrapper.obj \
+ $(SLO)$/cacheddynamicresultsetstub.obj \
+ $(SLO)$/cacheddynamicresultset.obj \
+ $(SLO)$/cacheserv.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(UCB_MAJOR)
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+DEF1NAME=$(SHL1TARGET)
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/core/cmdenv.cxx b/ucb/source/core/cmdenv.cxx
new file mode 100644
index 000000000000..0f425e814400
--- /dev/null
+++ b/ucb/source/core/cmdenv.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "cppuhelper/factory.hxx"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+
+#include "cmdenv.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+using namespace com::sun::star;
+using namespace ucb_cmdenv;
+
+//=========================================================================
+//=========================================================================
+//
+// UcbCommandEnvironment Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+UcbCommandEnvironment::UcbCommandEnvironment(
+ const uno::Reference< lang::XMultiServiceFactory >& /*xSMgr*/ )
+//: m_xSMgr( xSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+UcbCommandEnvironment::~UcbCommandEnvironment()
+{
+}
+
+//=========================================================================
+//
+// XInitialization methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL UcbCommandEnvironment::initialize(
+ const uno::Sequence< uno::Any >& aArguments )
+ throw( uno::Exception,
+ uno::RuntimeException )
+{
+ if ( ( aArguments.getLength() < 2 ) ||
+ !( aArguments[ 0 ] >>= m_xIH ) ||
+ !( aArguments[ 1 ] >>= m_xPH ))
+ throw lang::IllegalArgumentException();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+::rtl::OUString SAL_CALL UcbCommandEnvironment::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL
+UcbCommandEnvironment::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
+ const rtl::OUString * pArray = aSNL.getConstArray();
+ for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ {
+ if ( pArray[ i ] == ServiceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ::rtl::OUString > SAL_CALL
+UcbCommandEnvironment::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+//=========================================================================
+// static
+rtl::OUString UcbCommandEnvironment::getImplementationName_Static()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.CommandEnvironment" ) );
+}
+
+//=========================================================================
+// static
+uno::Sequence< rtl::OUString >
+UcbCommandEnvironment::getSupportedServiceNames_Static()
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb.CommandEnvironment" ) );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XCommandInfo methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< task::XInteractionHandler > SAL_CALL
+UcbCommandEnvironment::getInteractionHandler()
+ throw ( uno::RuntimeException )
+{
+ return m_xIH;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XProgressHandler > SAL_CALL
+UcbCommandEnvironment::getProgressHandler()
+ throw ( uno::RuntimeException )
+{
+ return m_xPH;
+}
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+static uno::Reference< uno::XInterface > SAL_CALL
+UcbCommandEnvironment_CreateInstance(
+ const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
+ throw( uno::Exception )
+{
+ lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
+ new UcbCommandEnvironment( rSMgr ) );
+ return uno::Reference< uno::XInterface >::query( pX );
+}
+
+//=========================================================================
+// static
+uno::Reference< lang::XSingleServiceFactory >
+UcbCommandEnvironment::createServiceFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
+{
+ return uno::Reference< lang::XSingleServiceFactory >(
+ cppu::createOneInstanceFactory(
+ rxServiceMgr,
+ UcbCommandEnvironment::getImplementationName_Static(),
+ UcbCommandEnvironment_CreateInstance,
+ UcbCommandEnvironment::getSupportedServiceNames_Static() ) );
+}
diff --git a/ucb/source/core/cmdenv.hxx b/ucb/source/core/cmdenv.hxx
new file mode 100644
index 000000000000..419ce6afb560
--- /dev/null
+++ b/ucb/source/core/cmdenv.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CMDENV_HXX
+#define INCLUDED_CMDENV_HXX
+
+#include "cppuhelper/implbase3.hxx"
+
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+
+namespace ucb_cmdenv {
+
+class UcbCommandEnvironment :
+ public cppu::WeakImplHelper3< com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::ucb::XCommandEnvironment >
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionHandler > m_xIH;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XProgressHandler > m_xPH;
+
+public:
+ UcbCommandEnvironment(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~UcbCommandEnvironment();
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any >& aArguments )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XCommandEnvironment
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XProgressHandler > SAL_CALL
+ getProgressHandler()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // Non-UNO interfaces
+ static rtl::OUString
+ getImplementationName_Static();
+ static com::sun::star::uno::Sequence< rtl::OUString >
+ getSupportedServiceNames_Static();
+
+ static com::sun::star::uno::Reference<
+ com::sun::star::lang::XSingleServiceFactory >
+ createServiceFactory( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rxServiceMgr );
+private:
+ //com::sun::star::uno::Reference<
+ // com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+};
+
+} // namespace ucb_cmdenv
+
+#endif // INCLUDED_CMDENV_HXX
diff --git a/ucb/source/core/exports2.dxp b/ucb/source/core/exports2.dxp
new file mode 100644
index 000000000000..a1936474f752
--- /dev/null
+++ b/ucb/source/core/exports2.dxp
@@ -0,0 +1,5 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
+
+_ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE
diff --git a/ucb/source/core/identify.cxx b/ucb/source/core/identify.cxx
new file mode 100644
index 000000000000..ece9211c1ac3
--- /dev/null
+++ b/ucb/source/core/identify.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "identify.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+
+//=========================================================================
+//
+// ContentIdentifier Implementation.
+//
+//=========================================================================
+
+ContentIdentifier::ContentIdentifier(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const OUString& ContentId )
+: m_xSMgr( rxSMgr ),
+ m_aContentId( ContentId )
+{
+}
+
+//=========================================================================
+// virtual
+ContentIdentifier::~ContentIdentifier()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_2( ContentIdentifier,
+ XTypeProvider,
+ XContentIdentifier );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_2( ContentIdentifier,
+ XTypeProvider,
+ XContentIdentifier );
+
+//=========================================================================
+//
+// XContentIdentifier methods.
+//
+//=========================================================================
+
+// virtual
+OUString SAL_CALL ContentIdentifier::getContentIdentifier()
+ throw( RuntimeException )
+{
+ return m_aContentId;
+}
+
+//=========================================================================
+// virtual
+OUString SAL_CALL ContentIdentifier::getContentProviderScheme()
+ throw( RuntimeException )
+{
+ if ( !m_aProviderScheme.getLength() && m_aContentId.getLength() )
+ {
+ // The content provider scheme is the part before the first ':'
+ // within the content id.
+ sal_Int32 nPos = m_aContentId.indexOf( ':', 0 );
+ if ( nPos != -1 )
+ {
+ OUString aScheme( m_aContentId.copy( 0, nPos ) );
+ m_aProviderScheme = aScheme.toAsciiLowerCase();
+ }
+ }
+
+ return m_aProviderScheme;
+}
+
diff --git a/ucb/source/core/identify.hxx b/ucb/source/core/identify.hxx
new file mode 100644
index 000000000000..d8ea23b1eee5
--- /dev/null
+++ b/ucb/source/core/identify.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _IDENTIFY_HXX
+#define _IDENTIFY_HXX
+
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+
+//=========================================================================
+
+class ContentIdentifier :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XContentIdentifier
+{
+public:
+ ContentIdentifier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::OUString& ContentId );
+ virtual ~ContentIdentifier();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XContentIdentifier
+ virtual rtl::OUString SAL_CALL getContentIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual rtl::OUString SAL_CALL getContentProviderScheme()
+ throw( com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ rtl::OUString m_aContentId;
+ rtl::OUString m_aProviderScheme;
+};
+
+#endif /* !_IDENTIFY_HXX */
diff --git a/ucb/source/core/makefile.mk b/ucb/source/core/makefile.mk
new file mode 100644
index 000000000000..34765eb74289
--- /dev/null
+++ b/ucb/source/core/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=ucb
+TARGET=ucb
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCB_MAJOR=1
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/identify.obj \
+ $(SLO)$/ucb.obj \
+ $(SLO)$/ucbserv.obj \
+ $(SLO)$/ucbstore.obj \
+ $(SLO)$/ucbprops.obj \
+ $(SLO)$/provprox.obj \
+ $(SLO)$/ucbcmds.obj \
+ $(SLO)$/cmdenv.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(UCB_MAJOR)
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB)
+SHL1LIBS=\
+ $(LIB1TARGET) \
+ $(SLB)$/regexp.lib
+SHL1IMPLIB=i$(TARGET)
+
+.IF "$(GUI)" == "OS2"
+DEF1EXPORTFILE=exports2.dxp
+.ELSE
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+.ENDIF
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/core/providermap.hxx b/ucb/source/core/providermap.hxx
new file mode 100644
index 000000000000..a7fec30a42bf
--- /dev/null
+++ b/ucb/source/core/providermap.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCB_PROVIDERMAP_HXX_
+#define _UCB_PROVIDERMAP_HXX_
+
+#include <list>
+#include <com/sun/star/uno/Reference.h>
+#include <regexpmap.hxx>
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ class XContentProvider;
+} } } }
+
+//============================================================================
+class ProviderListEntry_Impl
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > m_xProvider;
+ mutable com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > m_xResolvedProvider;
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > resolveProvider() const;
+
+public:
+ ProviderListEntry_Impl(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider >& xProvider )
+ : m_xProvider( xProvider ) {}
+
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > getProvider() const
+ { return m_xProvider; }
+ inline com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > getResolvedProvider() const;
+};
+
+inline com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >
+ProviderListEntry_Impl::getResolvedProvider() const
+{
+ return m_xResolvedProvider.is() ? m_xResolvedProvider : resolveProvider();
+}
+
+//============================================================================
+typedef std::list< ProviderListEntry_Impl > ProviderList_Impl;
+
+//============================================================================
+typedef ucb_impl::RegexpMap< ProviderList_Impl > ProviderMap_Impl;
+
+#endif // _UCB_PROVIDERMAP_HXX_
+
diff --git a/ucb/source/core/provprox.cxx b/ucb/source/core/provprox.cxx
new file mode 100644
index 000000000000..feab9ce4f95e
--- /dev/null
+++ b/ucb/source/core/provprox.cxx
@@ -0,0 +1,401 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <osl/diagnose.h>
+#include "provprox.hxx"
+#include <com/sun/star/lang/XInitialization.hpp>
+
+using namespace rtl;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+//=========================================================================
+//=========================================================================
+//
+// UcbContentProviderProxyFactory Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+UcbContentProviderProxyFactory::UcbContentProviderProxyFactory(
+ const Reference< XMultiServiceFactory >& rxSMgr )
+: m_xSMgr( rxSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+UcbContentProviderProxyFactory::~UcbContentProviderProxyFactory()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3( UcbContentProviderProxyFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XContentProviderFactory );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3( UcbContentProviderProxyFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XContentProviderFactory );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( UcbContentProviderProxyFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.UcbContentProviderProxyFactory" ),
+ OUString::createFromAscii(
+ PROVIDER_FACTORY_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbContentProviderProxyFactory );
+
+//=========================================================================
+//
+// XContentProviderFactory methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContentProvider > SAL_CALL
+UcbContentProviderProxyFactory::createContentProvider(
+ const OUString& Service )
+ throw( RuntimeException )
+{
+ return Reference< XContentProvider >(
+ new UcbContentProviderProxy( m_xSMgr, Service ) );
+}
+
+//=========================================================================
+//=========================================================================
+//
+// UcbContentProviderProxy Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+UcbContentProviderProxy::UcbContentProviderProxy(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const OUString& Service )
+: m_aService( Service ),
+ m_bReplace( sal_False ),
+ m_bRegister( sal_False ),
+ m_xSMgr( rxSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+UcbContentProviderProxy::~UcbContentProviderProxy()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_COMMON_IMPL( UcbContentProviderProxy );
+
+//============================================================================
+// virtual
+Any SAL_CALL
+UcbContentProviderProxy::queryInterface( const Type & rType )
+ throw ( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ static_cast< XTypeProvider * >( this ),
+ static_cast< XServiceInfo * >( this ),
+ static_cast< XContentProvider * >( this ),
+ static_cast< XParameterizedContentProvider * >( this ),
+ static_cast< XContentProviderSupplier * >( this ) );
+
+ if ( !aRet.hasValue() )
+ aRet = OWeakObject::queryInterface( rType );
+
+ if ( !aRet.hasValue() )
+ {
+ // Get original provider an forward the call...
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ Reference< XContentProvider > xProvider = getContentProvider();
+ if ( xProvider.is() )
+ aRet = xProvider->queryInterface( rType );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( UcbContentProviderProxy );
+
+//=========================================================================
+
+Sequence< Type > SAL_CALL UcbContentProviderProxy::getTypes() \
+ throw( RuntimeException )
+{
+ // Get original provider an forward the call...
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ Reference< XTypeProvider > xProvider( getContentProvider(), UNO_QUERY );
+ if ( xProvider.is() )
+ {
+ return xProvider->getTypes();
+ }
+ else
+ {
+ static cppu::OTypeCollection collection(
+ CPPU_TYPE_REF( XTypeProvider ),
+ CPPU_TYPE_REF( XServiceInfo ),
+ CPPU_TYPE_REF( XContentProvider ),
+ CPPU_TYPE_REF( XParameterizedContentProvider ),
+ CPPU_TYPE_REF( XContentProviderSupplier ) );
+ return collection.getTypes();
+ }
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_NOFACTORY_IMPL_1( UcbContentProviderProxy,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.UcbContentProviderProxy" ),
+ OUString::createFromAscii(
+ PROVIDER_PROXY_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContent > SAL_CALL UcbContentProviderProxy::queryContent(
+ const Reference< XContentIdentifier >& Identifier )
+ throw( IllegalIdentifierException,
+ RuntimeException )
+{
+ // Get original provider an forward the call...
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ Reference< XContentProvider > xProvider = getContentProvider();
+ if ( xProvider.is() )
+ return xProvider->queryContent( Identifier );
+
+ return Reference< XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL UcbContentProviderProxy::compareContentIds(
+ const Reference< XContentIdentifier >& Id1,
+ const Reference< XContentIdentifier >& Id2 )
+ throw( RuntimeException )
+{
+ // Get original provider an forward the call...
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ Reference< XContentProvider > xProvider = getContentProvider();
+ if ( xProvider.is() )
+ return xProvider->compareContentIds( Id1, Id2 );
+
+ // OSL_ENSURE( sal_False,
+ // "UcbContentProviderProxy::compareContentIds - No provider!" );
+
+ // @@@ What else?
+ return 0;
+}
+
+//=========================================================================
+//
+// XParameterizedContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContentProvider > SAL_CALL
+UcbContentProviderProxy::registerInstance( const OUString& Template,
+ const OUString& Arguments,
+ sal_Bool ReplaceExisting )
+ throw( IllegalArgumentException,
+ RuntimeException )
+{
+ // Just remember that this method was called ( and the params ).
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_bRegister )
+ {
+// m_xTargetProvider = 0;
+ m_aTemplate = Template;
+ m_aArguments = Arguments;
+ m_bReplace = ReplaceExisting;
+
+ m_bRegister = sal_True;
+ }
+ return this;
+}
+
+//=========================================================================
+// virtual
+Reference< XContentProvider > SAL_CALL
+UcbContentProviderProxy::deregisterInstance( const OUString& Template,
+ const OUString& Arguments )
+ throw( IllegalArgumentException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // registerInstance called at proxy and at original?
+ if ( m_bRegister && m_xTargetProvider.is() )
+ {
+ m_bRegister = sal_False;
+ m_xTargetProvider = 0;
+
+ Reference< XParameterizedContentProvider >
+ xParamProvider( m_xProvider, UNO_QUERY );
+ if ( xParamProvider.is() )
+ {
+ try
+ {
+ xParamProvider->deregisterInstance( Template, Arguments );
+ }
+ catch ( IllegalIdentifierException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "UcbContentProviderProxy::deregisterInstance - "
+ "Caught IllegalIdentifierException!" );
+ }
+ }
+ }
+
+ return this;
+}
+
+//=========================================================================
+//
+// XContentProviderSupplier methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContentProvider > SAL_CALL
+UcbContentProviderProxy::getContentProvider()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_xProvider.is() )
+ {
+ try
+ {
+ m_xProvider
+ = Reference< XContentProvider >(
+ m_xSMgr->createInstance( m_aService ), UNO_QUERY );
+ if(m_aArguments.compareToAscii("NoConfig") == 0)
+ {
+ Reference<XInitialization> xInit(m_xProvider,UNO_QUERY);
+ if(xInit.is()) {
+ Sequence<Any> aArgs(1);
+ aArgs[0] <<= m_aArguments;
+ xInit->initialize(aArgs);
+ }
+ }
+ }
+ catch ( RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ // registerInstance called at proxy, but not yet at original?
+ if ( m_xProvider.is() && m_bRegister )
+ {
+ Reference< XParameterizedContentProvider >
+ xParamProvider( m_xProvider, UNO_QUERY );
+ if ( xParamProvider.is() )
+ {
+ try
+ {
+ m_xTargetProvider
+ = xParamProvider->registerInstance( m_aTemplate,
+ m_aArguments,
+ m_bReplace );
+ }
+ catch ( IllegalIdentifierException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "UcbContentProviderProxy::getContentProvider - "
+ "Caught IllegalIdentifierException!" );
+ }
+
+ OSL_ENSURE( m_xTargetProvider.is(),
+ "UcbContentProviderProxy::getContentProvider - "
+ "No provider!" );
+ }
+ }
+ if ( !m_xTargetProvider.is() )
+ m_xTargetProvider = m_xProvider;
+ }
+
+ OSL_ENSURE( m_xProvider.is(),
+ "UcbContentProviderProxy::getContentProvider - No provider!" );
+ return m_xTargetProvider;
+}
diff --git a/ucb/source/core/provprox.hxx b/ucb/source/core/provprox.hxx
new file mode 100644
index 000000000000..cdc85251e96e
--- /dev/null
+++ b/ucb/source/core/provprox.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PROVPROX_HXX
+#define _PROVPROX_HXX
+
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ucb/XContentProviderFactory.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XParameterizedContentProvider.hpp>
+#include <com/sun/star/ucb/XContentProviderSupplier.hpp>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+
+//=========================================================================
+
+#define PROVIDER_FACTORY_SERVICE_NAME \
+ "com.sun.star.ucb.ContentProviderProxyFactory"
+#define PROVIDER_PROXY_SERVICE_NAME \
+ "com.sun.star.ucb.ContentProviderProxy"
+
+//============================================================================
+//
+// class UcbContentProviderProxyFactory.
+//
+//============================================================================
+
+class UcbContentProviderProxyFactory :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XContentProviderFactory
+{
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xSMgr;
+
+public:
+ UcbContentProviderProxyFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr );
+ virtual ~UcbContentProviderProxyFactory();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProviderFactory
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentProvider > SAL_CALL
+ createContentProvider( const ::rtl::OUString& Service )
+ throw( ::com::sun::star::uno::RuntimeException );
+};
+
+//============================================================================
+//
+// class UcbContentProviderProxy.
+//
+//============================================================================
+
+class UcbContentProviderProxy :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XContentProviderSupplier,
+ public com::sun::star::ucb::XContentProvider,
+ public com::sun::star::ucb::XParameterizedContentProvider
+{
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_aService;
+ ::rtl::OUString m_aTemplate;
+ ::rtl::OUString m_aArguments;
+ sal_Bool m_bReplace;
+ sal_Bool m_bRegister;
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xSMgr;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >
+ m_xProvider;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >
+ m_xTargetProvider;
+
+public:
+ UcbContentProviderProxy(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const ::rtl::OUString& Service );
+ virtual ~UcbContentProviderProxy();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ // XContentProviderSupplier
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentProvider > SAL_CALL
+ getContentProvider()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual sal_Int32 SAL_CALL
+ compareContentIds( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Id1,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Id2 )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XParameterizedContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentProvider > SAL_CALL
+ registerInstance( const ::rtl::OUString& Template,
+ const ::rtl::OUString& Arguments,
+ sal_Bool ReplaceExisting )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentProvider > SAL_CALL
+ deregisterInstance( const ::rtl::OUString& Template,
+ const ::rtl::OUString& Arguments )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+#endif /* !_PROVPROX_HXX */
diff --git a/ucb/source/core/ucb.cxx b/ucb/source/core/ucb.cxx
new file mode 100644
index 000000000000..c13ec9d367c8
--- /dev/null
+++ b/ucb/source/core/ucb.cxx
@@ -0,0 +1,956 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentProviderSupplier.hpp>
+#include <com/sun/star/ucb/XParameterizedContentProvider.hpp>
+#include <com/sun/star/ucb/XContentProviderFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include "identify.hxx"
+#include "ucbcmds.hxx"
+
+#include "ucb.hxx"
+
+// Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template
+// instantiations for these in another compilation unit...):
+#ifndef _UCB_REGEXPMAP_TPT_
+#include <regexpmap.tpt>
+#endif
+
+using namespace rtl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace ucb_impl;
+using namespace com::sun::star;
+using namespace ucbhelper;
+
+
+#define CONFIG_CONTENTPROVIDERS_KEY \
+ "/org.openoffice.ucb.Configuration/ContentProviders"
+
+
+namespace {
+
+bool fillPlaceholders(rtl::OUString const & rInput,
+ uno::Sequence< uno::Any > const & rReplacements,
+ rtl::OUString * pOutput)
+{
+ sal_Unicode const * p = rInput.getStr();
+ sal_Unicode const * pEnd = p + rInput.getLength();
+ sal_Unicode const * pCopy = p;
+ rtl::OUStringBuffer aBuffer;
+ while (p != pEnd)
+ switch (*p++)
+ {
+ case '&':
+ if (pEnd - p >= 4
+ && p[0] == 'a' && p[1] == 'm' && p[2] == 'p'
+ && p[3] == ';')
+ {
+ aBuffer.append(pCopy, p - 1 - pCopy);
+ aBuffer.append(sal_Unicode('&'));
+ p += 4;
+ pCopy = p;
+ }
+ else if (pEnd - p >= 3
+ && p[0] == 'l' && p[1] == 't' && p[2] == ';')
+ {
+ aBuffer.append(pCopy, p - 1 - pCopy);
+ aBuffer.append(sal_Unicode('<'));
+ p += 3;
+ pCopy = p;
+ }
+ else if (pEnd - p >= 3
+ && p[0] == 'g' && p[1] == 't' && p[2] == ';')
+ {
+ aBuffer.append(pCopy, p - 1 - pCopy);
+ aBuffer.append(sal_Unicode('>'));
+ p += 3;
+ pCopy = p;
+ }
+ break;
+
+ case '<':
+ sal_Unicode const * q = p;
+ while (q != pEnd && *q != '>')
+ ++q;
+ if (q == pEnd)
+ break;
+ rtl::OUString aKey(p, q - p);
+ rtl::OUString aValue;
+ bool bFound = false;
+ for (sal_Int32 i = 2; i + 1 < rReplacements.getLength();
+ i += 2)
+ {
+ rtl::OUString aReplaceKey;
+ if ((rReplacements[i] >>= aReplaceKey)
+ && aReplaceKey == aKey
+ && (rReplacements[i + 1] >>= aValue))
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ return false;
+ aBuffer.append(pCopy, p - 1 - pCopy);
+ aBuffer.append(aValue);
+ p = q + 1;
+ pCopy = p;
+ break;
+ }
+ aBuffer.append(pCopy, pEnd - pCopy);
+ *pOutput = aBuffer.makeStringAndClear();
+ return true;
+}
+
+void makeAndAppendXMLName(
+ rtl::OUStringBuffer & rBuffer, const rtl::OUString & rIn )
+{
+ sal_Int32 nCount = rIn.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = rIn.getStr()[ n ];
+ switch ( c )
+ {
+ case '&':
+ rBuffer.appendAscii( "&amp;" );
+ break;
+
+ case '"':
+ rBuffer.appendAscii( "&quot;" );
+ break;
+
+ case '\'':
+ rBuffer.appendAscii( "&apos;" );
+ break;
+
+ case '<':
+ rBuffer.appendAscii( "&lt;" );
+ break;
+
+ case '>':
+ rBuffer.appendAscii( "&gt;" );
+ break;
+
+ default:
+ rBuffer.append( c );
+ break;
+ }
+ }
+}
+
+}
+
+//=========================================================================
+//
+// UniversalContentBroker Implementation.
+//
+//=========================================================================
+
+UniversalContentBroker::UniversalContentBroker(
+ const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr )
+: m_xSMgr( rXSMgr ),
+ m_pDisposeEventListeners( NULL ),
+ m_nInitCount( 0 ), //@@@ see initialize() method
+ m_nCommandId( 0 )
+{
+ OSL_ENSURE( m_xSMgr.is(),
+ "UniversalContentBroker ctor: No service manager" );
+}
+
+//=========================================================================
+// virtual
+UniversalContentBroker::~UniversalContentBroker()
+{
+ delete m_pDisposeEventListeners;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_8( UniversalContentBroker,
+ XTypeProvider,
+ XComponent,
+ XServiceInfo,
+ XInitialization,
+ XContentProviderManager,
+ XContentProvider,
+ XContentIdentifierFactory,
+ XCommandProcessor );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_8( UniversalContentBroker,
+ XTypeProvider,
+ XComponent,
+ XServiceInfo,
+ XInitialization,
+ XContentProviderManager,
+ XContentProvider,
+ XContentIdentifierFactory,
+ XCommandProcessor );
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL UniversalContentBroker::dispose()
+ throw( com::sun::star::uno::RuntimeException )
+{
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = SAL_STATIC_CAST( XComponent*, this );
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ if ( m_xNotifier.is() )
+ m_xNotifier->removeChangesListener( this );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+
+ // Note: Don't want to delete empty container here -> performance.
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( UniversalContentBroker,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.UniversalContentBroker" ),
+ OUString::createFromAscii(
+ UCB_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker );
+
+//=========================================================================
+//
+// XInitialization methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL UniversalContentBroker::initialize(
+ const com::sun::star::uno::Sequence< Any >& aArguments )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException )
+{
+ //@@@ At the moment, there's a problem when one (non-one-instance) factory
+ // 'wraps' another (one-instance) factory, causing this method to be
+ // called several times:
+ m_aArguments = aArguments;
+
+ oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount);
+ if (nCount == 1)
+ configureUcb();
+ else
+ osl_decrementInterlockedCount(&m_nInitCount);
+ // make the possibility of overflow less likely...
+}
+
+//=========================================================================
+//
+// XContentProviderManager methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContentProvider > SAL_CALL
+UniversalContentBroker::registerContentProvider(
+ const Reference< XContentProvider >& Provider,
+ const OUString& Scheme,
+ sal_Bool ReplaceExisting )
+ throw( DuplicateProviderException, com::sun::star::uno::RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ ProviderMap_Impl::iterator aIt;
+ try
+ {
+ aIt = m_aProviders.find(Scheme);
+ }
+ catch (IllegalArgumentException const &)
+ {
+ return 0; //@@@
+ }
+
+ Reference< XContentProvider > xPrevious;
+ if (aIt == m_aProviders.end())
+ {
+ ProviderList_Impl aList;
+ aList.push_front(Provider);
+ try
+ {
+ m_aProviders.add(Scheme, aList, false);
+ }
+ catch (IllegalArgumentException const &)
+ {
+ return 0; //@@@
+ }
+ }
+ else
+ {
+ if (!ReplaceExisting)
+ throw DuplicateProviderException();
+
+ ProviderList_Impl & rList = aIt->getValue();
+ xPrevious = rList.front().getProvider();
+ rList.push_front(Provider);
+ }
+
+ return xPrevious;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::deregisterContentProvider(
+ const Reference< XContentProvider >& Provider,
+ const OUString& Scheme )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ ProviderMap_Impl::iterator aMapIt;
+ try
+ {
+ aMapIt = m_aProviders.find(Scheme);
+ }
+ catch (IllegalArgumentException const &)
+ {
+ return; //@@@
+ }
+
+ if (aMapIt != m_aProviders.end())
+ {
+ ProviderList_Impl & rList = aMapIt->getValue();
+
+ ProviderList_Impl::iterator aListEnd(rList.end());
+ for (ProviderList_Impl::iterator aListIt(rList.begin());
+ aListIt != aListEnd; ++aListIt)
+ {
+ if ((*aListIt).getProvider() == Provider)
+ {
+ rList.erase(aListIt);
+ break;
+ }
+ }
+
+ if (rList.empty())
+ m_aProviders.erase(aMapIt);
+ }
+}
+
+//=========================================================================
+// virtual
+com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL
+ UniversalContentBroker::queryContentProviders()
+ throw( com::sun::star::uno::RuntimeException )
+{
+ // Return a list with information about active(!) content providers.
+
+ osl::MutexGuard aGuard(m_aMutex);
+
+ com::sun::star::uno::Sequence< ContentProviderInfo > aSeq(
+ m_aProviders.size() );
+ ContentProviderInfo* pInfo = aSeq.getArray();
+
+ ProviderMap_Impl::const_iterator end = m_aProviders.end();
+ for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end;
+ ++it)
+ {
+ // Note: Active provider is always the first list element.
+ pInfo->ContentProvider = it->getValue().front().getProvider();
+ pInfo->Scheme = it->getRegexp();
+ ++pInfo;
+ }
+
+ return aSeq;
+}
+
+//=========================================================================
+// virtual
+Reference< XContentProvider > SAL_CALL
+ UniversalContentBroker::queryContentProvider( const OUString&
+ Identifier )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ return queryContentProvider( Identifier, sal_False );
+}
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContent > SAL_CALL UniversalContentBroker::queryContent(
+ const Reference< XContentIdentifier >& Identifier )
+ throw( IllegalIdentifierException, com::sun::star::uno::RuntimeException )
+{
+ //////////////////////////////////////////////////////////////////////
+ // Let the content provider for the scheme given with the content
+ // identifier create the XContent instance.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( !Identifier.is() )
+ return Reference< XContent >();
+
+ Reference< XContentProvider > xProv =
+ queryContentProvider( Identifier->getContentIdentifier(), sal_True );
+ if ( xProv.is() )
+ return xProv->queryContent( Identifier );
+
+ return Reference< XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds(
+ const Reference< XContentIdentifier >& Id1,
+ const Reference< XContentIdentifier >& Id2 )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ OUString aURI1( Id1->getContentIdentifier() );
+ OUString aURI2( Id2->getContentIdentifier() );
+
+ Reference< XContentProvider > xProv1
+ = queryContentProvider( aURI1, sal_True );
+ Reference< XContentProvider > xProv2
+ = queryContentProvider( aURI2, sal_True );
+
+ // When both identifiers belong to the same provider, let that provider
+ // compare them; otherwise, simply compare the URI strings (which must
+ // be different):
+ if ( xProv1.is() && ( xProv1 == xProv2 ) )
+ return xProv1->compareContentIds( Id1, Id2 );
+ else
+ return aURI1.compareTo( aURI2 );
+}
+
+//=========================================================================
+//
+// XContentIdentifierFactory methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XContentIdentifier > SAL_CALL
+ UniversalContentBroker::createContentIdentifier(
+ const OUString& ContentId )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ //////////////////////////////////////////////////////////////////////
+ // Let the content provider for the scheme given with content
+ // identifier create the XContentIdentifier instance, if he supports
+ // the XContentIdentifierFactory interface. Otherwise create standard
+ // implementation object for XContentIdentifier.
+ //////////////////////////////////////////////////////////////////////
+
+ Reference< XContentIdentifier > xIdentifier;
+
+ Reference< XContentProvider > xProv
+ = queryContentProvider( ContentId, sal_True );
+ if ( xProv.is() )
+ {
+ Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY );
+ if ( xFac.is() )
+ xIdentifier = xFac->createContentIdentifier( ContentId );
+ }
+
+ if ( !xIdentifier.is() )
+ xIdentifier = new ContentIdentifier( m_xSMgr, ContentId );
+
+ return xIdentifier;
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier()
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Just increase counter on every call to generate an identifier.
+ return ++m_nCommandId;
+}
+
+//=========================================================================
+// virtual
+Any SAL_CALL UniversalContentBroker::execute(
+ const Command& aCommand,
+ sal_Int32,
+ const Reference< XCommandEnvironment >& Environment )
+ throw( Exception, CommandAbortedException, RuntimeException )
+{
+ Any aRet;
+
+ //////////////////////////////////////////////////////////////////////
+ // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo
+ // ctor in ucbcmds.cxx when adding new commands!
+ //////////////////////////////////////////////////////////////////////
+
+ if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) ||
+ aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getCommandInfo();
+ }
+ else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) ||
+ aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // globalTransfer
+ //////////////////////////////////////////////////////////////////
+
+ GlobalTransferCommandArgument aTransferArg;
+ if ( !( aCommand.Argument >>= aTransferArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ makeAny( IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ globalTransfer( aTransferArg, Environment );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unknown command
+ //////////////////////////////////////////////////////////////////
+
+ ucbhelper::cancelCommandExecution(
+ makeAny( UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::abort( sal_Int32 )
+ throw( RuntimeException )
+{
+ // @@@ Not implemeted ( yet).
+}
+
+//=========================================================================
+//
+// XChangesListener methods
+//
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event )
+ throw( uno::RuntimeException )
+{
+ sal_Int32 nCount = Event.Changes.getLength();
+ if ( nCount )
+ {
+
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv(
+ m_xSMgr->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.configuration.ConfigurationProvider" ) ),
+ uno::UNO_QUERY_THROW );
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aProperty.Value <<= Event.Base;
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< uno::XInterface > xInterface(
+ xConfigProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" ) ),
+ aArguments ) );
+
+ uno::Reference< container::XHierarchicalNameAccess >
+ xHierNameAccess( xInterface, uno::UNO_QUERY_THROW );
+
+ const util::ElementChange* pElementChanges
+ = Event.Changes.getConstArray();
+
+ ContentProviderDataList aData;
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const util::ElementChange& rElem = pElementChanges[ n ];
+ rtl::OUString aKey;
+ rElem.Accessor >>= aKey;
+
+ ContentProviderData aInfo;
+
+ createContentProviderData(aKey, xHierNameAccess, aInfo);
+
+ aData.push_back(aInfo);
+ }
+
+ prepareAndRegister(aData);
+ }
+}
+
+//=========================================================================
+//
+// XEventListener methods
+//
+//=========================================================================
+// virtual
+void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&)
+ throw( uno::RuntimeException )
+{
+ if ( m_xNotifier.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_xNotifier.is() )
+ m_xNotifier.clear();
+ }
+}
+
+//=========================================================================
+//
+// Non-interface methods
+//
+//=========================================================================
+
+Reference< XContentProvider > UniversalContentBroker::queryContentProvider(
+ const OUString& Identifier,
+ sal_Bool bResolved )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ProviderList_Impl const * pList = m_aProviders.map( Identifier );
+ return pList ? bResolved ? pList->front().getResolvedProvider()
+ : pList->front().getProvider()
+ : Reference< XContentProvider >();
+}
+
+bool UniversalContentBroker::configureUcb()
+ throw (uno::RuntimeException)
+{
+ rtl::OUString aKey1;
+ rtl::OUString aKey2;
+ if (m_aArguments.getLength() < 2
+ || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2))
+ {
+ OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): Bad arguments");
+ return false;
+ }
+
+ ContentProviderDataList aData;
+ if (!getContentProviderData(aKey1, aKey2, aData))
+ {
+ OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): No configuration");
+ return false;
+ }
+
+ prepareAndRegister(aData);
+
+ return true;
+}
+
+void UniversalContentBroker::prepareAndRegister(
+ const ContentProviderDataList& rData)
+{
+ ContentProviderDataList::const_iterator aEnd(rData.end());
+ for (ContentProviderDataList::const_iterator aIt(rData.begin());
+ aIt != aEnd; ++aIt)
+ {
+ rtl::OUString aProviderArguments;
+ if (fillPlaceholders(aIt->Arguments,
+ m_aArguments,
+ &aProviderArguments))
+ {
+ registerAtUcb(this,
+ m_xSMgr,
+ aIt->ServiceName,
+ aProviderArguments,
+ aIt->URLTemplate,
+ 0);
+
+ }
+ else
+ OSL_ENSURE(false,
+ "UniversalContentBroker::prepareAndRegister(): Bad argument placeholders");
+ }
+}
+
+//=========================================================================
+bool UniversalContentBroker::getContentProviderData(
+ const rtl::OUString & rKey1,
+ const rtl::OUString & rKey2,
+ ContentProviderDataList & rListToFill )
+{
+ if ( !m_xSMgr.is() || !rKey1.getLength() || !rKey2.getLength() )
+ {
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - Invalid argument!" );
+ return false;
+ }
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv(
+ m_xSMgr->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.configuration.ConfigurationProvider" ) ),
+ uno::UNO_QUERY_THROW );
+
+ rtl::OUStringBuffer aFullPath;
+ aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" );
+ makeAndAppendXMLName( aFullPath, rKey1 );
+ aFullPath.appendAscii( "']/SecondaryKeys/['" );
+ makeAndAppendXMLName( aFullPath, rKey2 );
+ aFullPath.appendAscii( "']/ProviderData" );
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aProperty.Value <<= aFullPath.makeStringAndClear();
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< uno::XInterface > xInterface(
+ xConfigProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" ) ),
+ aArguments ) );
+
+ if ( !m_xNotifier.is() )
+ {
+ m_xNotifier = uno::Reference< util::XChangesNotifier >(
+ xInterface, uno::UNO_QUERY_THROW );
+
+ m_xNotifier->addChangesListener( this );
+ }
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xInterface, uno::UNO_QUERY_THROW );
+
+ uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames();
+ const rtl::OUString* pElems = aElems.getConstArray();
+ sal_Int32 nCount = aElems.getLength();
+
+ if ( nCount > 0 )
+ {
+ uno::Reference< container::XHierarchicalNameAccess >
+ xHierNameAccess( xInterface, uno::UNO_QUERY_THROW );
+
+ // Iterate over children.
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+
+ try
+ {
+
+ ContentProviderData aInfo;
+
+ rtl::OUStringBuffer aElemBuffer;
+ aElemBuffer.appendAscii( "['" );
+ makeAndAppendXMLName( aElemBuffer, pElems[ n ] );
+ aElemBuffer.appendAscii( "']" );
+
+ createContentProviderData(aElemBuffer.makeStringAndClear(), xHierNameAccess, aInfo);
+
+ rListToFill.push_back( aInfo );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // getByHierarchicalName
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - "
+ "caught NoSuchElementException!" );
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException& )
+ {
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - caught RuntimeException!" );
+ return false;
+ }
+ catch ( uno::Exception& )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - caught Exception!" );
+ return false;
+ }
+
+ return true;
+}
+
+void UniversalContentBroker::createContentProviderData(
+ const rtl::OUString & rProvider,
+ const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess,
+ ContentProviderData & rInfo)
+{
+ // Obtain service name.
+ rtl::OUStringBuffer aKeyBuffer (rProvider);
+ aKeyBuffer.appendAscii( "/ServiceName" );
+
+ rtl::OUString aValue;
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
+ {
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+
+ rInfo.ServiceName = aValue;
+
+ // Obtain URL Template.
+ aKeyBuffer.append(rProvider);
+ aKeyBuffer.appendAscii( "/URLTemplate" );
+
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
+ {
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+
+ rInfo.URLTemplate = aValue;
+
+ // Obtain Arguments.
+ aKeyBuffer.append(rProvider);
+ aKeyBuffer.appendAscii( "/Arguments" );
+
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
+ {
+ OSL_ENSURE( false,
+ "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+
+ rInfo.Arguments = aValue;
+}
+
+//=========================================================================
+//
+// ProviderListEntry_Impl implementation.
+//
+//=========================================================================
+
+Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const
+{
+ if ( !m_xResolvedProvider.is() )
+ {
+ Reference< XContentProviderSupplier > xSupplier(
+ m_xProvider, UNO_QUERY );
+ if ( xSupplier.is() )
+ m_xResolvedProvider = xSupplier->getContentProvider();
+
+ if ( !m_xResolvedProvider.is() )
+ m_xResolvedProvider = m_xProvider;
+ }
+
+ return m_xResolvedProvider;
+}
diff --git a/ucb/source/core/ucb.hxx b/ucb/source/core/ucb.hxx
new file mode 100644
index 000000000000..0e44c5bc99b5
--- /dev/null
+++ b/ucb/source/core/ucb.hxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCB_HXX
+#define _UCB_HXX
+
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+#include <osl/interlck.h>
+#include <ucbhelper/macros.hxx>
+#include "providermap.hxx"
+#include <ucbhelper/registerucb.hxx>
+
+#include <vector>
+//=========================================================================
+
+#define UCB_SERVICE_NAME "com.sun.star.ucb.UniversalContentBroker"
+
+//=========================================================================
+
+namespace cppu { class OInterfaceContainerHelper; }
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ class XCommandInfo;
+ struct GlobalTransferCommandArgument;
+} } } }
+
+class UniversalContentBroker :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XInitialization,
+ public com::sun::star::ucb::XContentProviderManager,
+ public com::sun::star::ucb::XContentProvider,
+ public com::sun::star::ucb::XContentIdentifierFactory,
+ public com::sun::star::ucb::XCommandProcessor,
+ public com::sun::star::util::XChangesListener
+{
+public:
+ UniversalContentBroker( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~UniversalContentBroker();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any >& aArguments )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ // XContentProviderManager
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > SAL_CALL
+ registerContentProvider( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider >&
+ Provider,
+ const rtl::OUString& Scheme,
+ sal_Bool ReplaceExisting )
+ throw( com::sun::star::ucb::DuplicateProviderException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ deregisterContentProvider( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider >&
+ Provider,
+ const rtl::OUString& Scheme )
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentProviderInfo > SAL_CALL
+ queryContentProviders()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > SAL_CALL
+ queryContentProvider( const rtl::OUString& Identifier )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Int32 SAL_CALL
+ compareContentIds( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Id1,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Id2 )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XContentIdentifierFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ createContentIdentifier( const rtl::OUString& ContentId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual sal_Int32 SAL_CALL
+ createCommandIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XChangesListener
+ virtual void SAL_CALL changesOccurred( const com::sun::star::util::ChangesEvent& Event )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XEventListener ( base of XChangesLisetenr )
+ virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >
+ queryContentProvider( const rtl::OUString& Identifier,
+ sal_Bool bResolved );
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo >
+ getCommandInfo();
+
+ void
+ globalTransfer(
+ const com::sun::star::ucb::GlobalTransferCommandArgument & rArg,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( com::sun::star::uno::Exception );
+
+
+ bool configureUcb()
+ throw ( com::sun::star::uno::RuntimeException);
+
+ bool getContentProviderData(
+ const rtl::OUString & rKey1,
+ const rtl::OUString & rKey2,
+ ucbhelper::ContentProviderDataList & rListToFill);
+
+ void prepareAndRegister( const ucbhelper::ContentProviderDataList& rData);
+
+ void createContentProviderData(
+ const rtl::OUString& rProvider,
+ const com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >& rxHierNameAccess,
+ ucbhelper::ContentProviderData& rInfo);
+
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XChangesNotifier > m_xNotifier;
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_aArguments;
+ ProviderMap_Impl m_aProviders;
+ osl::Mutex m_aMutex;
+ cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
+ oslInterlockedCount m_nInitCount; //@@@ see initialize() method
+ sal_Int32 m_nCommandId;
+};
+
+#endif /* !_UCB_HXX */
diff --git a/ucb/source/core/ucb.xml b/ucb/source/core/ucb.xml
new file mode 100644
index 000000000000..1473c035ba83
--- /dev/null
+++ b/ucb/source/core/ucb.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucb
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.UniversalContentBroker
+ </name>
+ <description>
+ This component provides access to a set of Contents via Content Providers.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.UniversalContentBroker
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.io.Pipe
+ </service-dependency>
+ </component-description>
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.UcbStore
+ </name>
+ <description>
+ This component is a factory for components managing persistent data.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.Store
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationAccess
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationUpdateAccess
+ </service-dependency>
+ </component-description>
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.UcbPropertiesManager
+ </name>
+ <description>
+ This component provides access to the meta data of the properties
+ known to the UCB.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.PropertiesManager
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.UcbContentProviderProxyFactory
+ </name>
+ <description>
+ This component is a factory for proxy objects for Content Providers.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.ContentProviderProxyFactory
+ </supported-service>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper1$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertySetInfoChange </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XNamed </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.CrossReference </type>
+ <type> com.sun.star.ucb.DocumentHeaderField </type>
+ <type> com.sun.star.ucb.GlobalTransferCommandArgument </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.RecipientInfo </type>
+ <type> com.sun.star.ucb.RuleSet </type>
+ <type> com.sun.star.ucb.SendInfo </type>
+ <type> com.sun.star.ucb.SendMediaTypes </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentIdentifier </type>
+ <type> com.sun.star.ucb.XContentIdentifierFactory </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XContentProviderFactory </type>
+ <type> com.sun.star.ucb.XContentProviderManager </type>
+ <type> com.sun.star.ucb.XContentProviderSupplier </type>
+ <type> com.sun.star.ucb.XDataContainer </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XParameterizedContentProvider </type>
+ <type> com.sun.star.ucb.XPropertySetRegistryFactory </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.util.DateTime </type>
+ <type> com.sun.star.util.XChangesBatch </type>
+</module-description>
diff --git a/ucb/source/core/ucbcmds.cxx b/ucb/source/core/ucbcmds.cxx
new file mode 100644
index 000000000000..fd3f0f73c772
--- /dev/null
+++ b/ucb/source/core/ucbcmds.cxx
@@ -0,0 +1,2090 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/ucb/CommandEnvironment.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <ucbhelper/simplenameclashresolverequest.hxx>
+#include "ucbcmds.hxx"
+#include "ucb.hxx"
+
+using namespace com::sun::star;
+
+namespace
+{
+
+//=========================================================================
+//
+// struct TransferCommandContext.
+//
+//=========================================================================
+
+struct TransferCommandContext
+{
+ uno::Reference< lang::XMultiServiceFactory > xSMgr;
+ uno::Reference< ucb::XCommandProcessor > xProcessor;
+ uno::Reference< ucb::XCommandEnvironment > xEnv;
+ uno::Reference< ucb::XCommandEnvironment > xOrigEnv;
+ ucb::GlobalTransferCommandArgument aArg;
+
+ TransferCommandContext(
+ const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
+ const uno::Reference< ucb::XCommandProcessor > & rxProcessor,
+ const uno::Reference< ucb::XCommandEnvironment > & rxEnv,
+ const uno::Reference< ucb::XCommandEnvironment > & rxOrigEnv,
+ const ucb::GlobalTransferCommandArgument & rArg )
+ : xSMgr( rxSMgr ), xProcessor( rxProcessor ), xEnv( rxEnv ),
+ xOrigEnv( rxOrigEnv ), aArg( rArg ) {}
+};
+
+//=========================================================================
+//
+// class InteractionHandlerProxy.
+//
+//=========================================================================
+
+class InteractionHandlerProxy :
+ public cppu::WeakImplHelper1< task::XInteractionHandler >
+{
+ uno::Reference< task::XInteractionHandler > m_xOrig;
+
+public:
+ InteractionHandlerProxy(
+ const uno::Reference< task::XInteractionHandler > & xOrig )
+ : m_xOrig( xOrig ) {}
+
+ // XInteractionHandler methods.
+ virtual void SAL_CALL handle(
+ const uno::Reference< task::XInteractionRequest >& Request )
+ throw ( uno::RuntimeException );
+};
+
+//=========================================================================
+// virtual
+void SAL_CALL InteractionHandlerProxy::handle(
+ const uno::Reference< task::XInteractionRequest >& Request )
+ throw ( uno::RuntimeException )
+{
+ if ( !m_xOrig.is() )
+ return;
+
+ // Filter unwanted requests by just not handling them.
+ uno::Any aRequest = Request->getRequest();
+
+ // "transfer"
+ ucb::InteractiveBadTransferURLException aBadTransferURLEx;
+ if ( aRequest >>= aBadTransferURLEx )
+ {
+ return;
+ }
+ else
+ {
+ // "transfer"
+ ucb::UnsupportedNameClashException aUnsupportedNameClashEx;
+ if ( aRequest >>= aUnsupportedNameClashEx )
+ {
+ if ( aUnsupportedNameClashEx.NameClash
+ != ucb::NameClash::ERROR )
+ return;
+ }
+ else
+ {
+ // "insert"
+ ucb::NameClashException aNameClashEx;
+ if ( aRequest >>= aNameClashEx )
+ {
+ return;
+ }
+ else
+ {
+ // "transfer"
+ ucb::UnsupportedCommandException aUnsupportedCommandEx;
+ if ( aRequest >>= aUnsupportedCommandEx )
+ {
+ return;
+ }
+ }
+ }
+ }
+
+ // not filtered; let the original handler do the work.
+ m_xOrig->handle( Request );
+}
+
+//=========================================================================
+//
+// class ActiveDataSink.
+//
+//=========================================================================
+
+class ActiveDataSink : public cppu::WeakImplHelper1< io::XActiveDataSink >
+{
+ uno::Reference< io::XInputStream > m_xStream;
+
+public:
+ // XActiveDataSink methods.
+ virtual void SAL_CALL setInputStream(
+ const uno::Reference< io::XInputStream >& aStream )
+ throw( uno::RuntimeException );
+ virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
+ throw( uno::RuntimeException );
+};
+
+//=========================================================================
+// virtual
+void SAL_CALL ActiveDataSink::setInputStream(
+ const uno::Reference< io::XInputStream >& aStream )
+ throw( uno::RuntimeException )
+{
+ m_xStream = aStream;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream()
+ throw( uno::RuntimeException )
+{
+ return m_xStream;
+}
+
+//=========================================================================
+//
+// class CommandProcessorInfo.
+//
+//=========================================================================
+
+class CommandProcessorInfo :
+ public cppu::WeakImplHelper1< ucb::XCommandInfo >
+{
+ uno::Sequence< ucb::CommandInfo > * m_pInfo;
+
+public:
+ CommandProcessorInfo();
+ virtual ~CommandProcessorInfo();
+
+ // XCommandInfo methods
+ virtual uno::Sequence< ucb::CommandInfo > SAL_CALL getCommands()
+ throw( uno::RuntimeException );
+ virtual ucb::CommandInfo SAL_CALL
+ getCommandInfoByName( const rtl::OUString& Name )
+ throw( ucb::UnsupportedCommandException, uno::RuntimeException );
+ virtual ucb::CommandInfo SAL_CALL
+ getCommandInfoByHandle( sal_Int32 Handle )
+ throw( ucb::UnsupportedCommandException, uno::RuntimeException );
+ virtual sal_Bool SAL_CALL hasCommandByName( const rtl::OUString& Name )
+ throw( uno::RuntimeException );
+ virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle )
+ throw( uno::RuntimeException );
+};
+
+//=========================================================================
+CommandProcessorInfo::CommandProcessorInfo()
+{
+ m_pInfo = new uno::Sequence< ucb::CommandInfo >( 2 );
+
+ (*m_pInfo)[ 0 ]
+ = ucb::CommandInfo(
+ rtl::OUString::createFromAscii( GETCOMMANDINFO_NAME ), // Name
+ GETCOMMANDINFO_HANDLE, // Handle
+ getCppuVoidType() ); // ArgType
+ (*m_pInfo)[ 1 ]
+ = ucb::CommandInfo(
+ rtl::OUString::createFromAscii( GLOBALTRANSFER_NAME ), // Name
+ GLOBALTRANSFER_HANDLE, // Handle
+ getCppuType(
+ static_cast<
+ ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType
+}
+
+//=========================================================================
+// virtual
+CommandProcessorInfo::~CommandProcessorInfo()
+{
+ delete m_pInfo;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > SAL_CALL
+CommandProcessorInfo::getCommands()
+ throw( uno::RuntimeException )
+{
+ return uno::Sequence< ucb::CommandInfo >( *m_pInfo );
+}
+
+//=========================================================================
+// virtual
+ucb::CommandInfo SAL_CALL
+CommandProcessorInfo::getCommandInfoByName( const rtl::OUString& Name )
+ throw( ucb::UnsupportedCommandException, uno::RuntimeException )
+{
+ for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
+ {
+ if ( (*m_pInfo)[ n ].Name == Name )
+ return ucb::CommandInfo( (*m_pInfo)[ n ] );
+ }
+
+ throw ucb::UnsupportedCommandException();
+}
+
+//=========================================================================
+// virtual
+ucb::CommandInfo SAL_CALL
+CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle )
+ throw( ucb::UnsupportedCommandException, uno::RuntimeException )
+{
+ for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
+ {
+ if ( (*m_pInfo)[ n ].Handle == Handle )
+ return ucb::CommandInfo( (*m_pInfo)[ n ] );
+ }
+
+ throw ucb::UnsupportedCommandException();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName(
+ const rtl::OUString& Name )
+ throw( uno::RuntimeException )
+{
+ for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
+ {
+ if ( (*m_pInfo)[ n ].Name == Name )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle )
+ throw( uno::RuntimeException )
+{
+ for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
+ {
+ if ( (*m_pInfo)[ n ].Handle == Handle )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+//=========================================================================
+//=========================================================================
+
+rtl::OUString createDesiredName(
+ const rtl::OUString & rSourceURL, const rtl::OUString & rNewTitle )
+{
+ rtl::OUString aName( rNewTitle );
+ if ( aName.getLength() == 0 )
+ {
+ // calculate name using source URL
+
+ // @@@ It's not guaranteed that slashes contained in the URL are
+ // actually path separators. This depends on the fact whether the
+ // URL is hierarchical. Only then the slashes are path separators.
+ // Therefore this algorithm is not guaranteed to work! But, ATM
+ // I don't know a better solution. It would have been better to
+ // have a member for the clashing name in
+ // UnsupportedNameClashException...
+
+ sal_Int32 nLastSlash = rSourceURL.lastIndexOf( '/' );
+ bool bTrailingSlash = false;
+ if ( nLastSlash == rSourceURL.getLength() - 1 )
+ {
+ nLastSlash = rSourceURL.lastIndexOf( '/', nLastSlash );
+ bTrailingSlash = true;
+ }
+
+ if ( nLastSlash != -1 )
+ {
+ if ( bTrailingSlash )
+ aName = rSourceURL.copy(
+ nLastSlash + 1,
+ rSourceURL.getLength() - nLastSlash - 2 );
+ else
+ aName = rSourceURL.copy( nLastSlash + 1 );
+ }
+ else
+ {
+ aName = rSourceURL;
+ }
+
+ // query, fragment present?
+ sal_Int32 nPos = aName.indexOf( '?' );
+ if ( nPos == -1 )
+ nPos = aName.indexOf( '#' );
+
+ if ( nPos != -1 )
+ aName = aName.copy( 0, nPos );
+ }
+ return rtl::OUString( aName );
+}
+
+rtl::OUString createDesiredName(
+ const ucb::GlobalTransferCommandArgument & rArg )
+{
+ return createDesiredName( rArg.SourceURL, rArg.NewTitle );
+}
+
+rtl::OUString createDesiredName(
+ const ucb::TransferInfo & rArg )
+{
+ return createDesiredName( rArg.SourceURL, rArg.NewTitle );
+}
+
+//=========================================================================
+enum NameClashContinuation { NOT_HANDLED, ABORT, OVERWRITE, NEW_NAME, UNKNOWN };
+
+NameClashContinuation interactiveNameClashResolve(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ const rtl::OUString & rTargetURL,
+ const rtl::OUString & rClashingName,
+ /* [out] */ uno::Any & rException,
+ /* [out] */ rtl::OUString & rNewName )
+{
+ rtl::Reference< ucbhelper::SimpleNameClashResolveRequest > xRequest(
+ new ucbhelper::SimpleNameClashResolveRequest(
+ rTargetURL, // target folder URL
+ rClashingName, // clashing name
+ rtl::OUString(), // no proposal for new name
+ sal_True /* bSupportsOverwriteData */ ) );
+
+ rException = xRequest->getRequest();
+ if ( xEnv.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = xEnv->getInteractionHandler();
+ if ( xIH.is() )
+ {
+
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation >
+ xSelection( xRequest->getSelection() );
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ // Abort.
+ return ABORT;
+ }
+ else
+ {
+ uno::Reference<
+ ucb::XInteractionReplaceExistingData >
+ xReplace(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xReplace.is() )
+ {
+ // Try again: Replace existing data.
+ return OVERWRITE;
+ }
+ else
+ {
+ uno::Reference<
+ ucb::XInteractionSupplyName >
+ xSupplyName(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xSupplyName.is() )
+ {
+ // Try again: Use new name.
+ rNewName = xRequest->getNewName();
+ return NEW_NAME;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "Unknown interaction continuation!" );
+ return UNKNOWN;
+ }
+ }
+ }
+ }
+ }
+ }
+ return NOT_HANDLED;
+}
+
+//=========================================================================
+bool setTitle(
+ const uno::Reference< ucb::XCommandProcessor > & xCommandProcessor,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ const rtl::OUString & rNewTitle )
+ throw( uno::RuntimeException )
+{
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aPropValues( 1 );
+ aPropValues[ 0 ].Name
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
+ aPropValues[ 0 ].Handle = -1;
+ aPropValues[ 0 ].Value = uno::makeAny( rNewTitle );
+
+ ucb::Command aSetPropsCommand(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ uno::makeAny( aPropValues ) );
+
+ uno::Any aResult
+ = xCommandProcessor->execute( aSetPropsCommand, 0, xEnv );
+
+ uno::Sequence< uno::Any > aErrors;
+ aResult >>= aErrors;
+
+ OSL_ENSURE( aErrors.getLength() == 1,
+ "getPropertyValues return value invalid!" );
+
+ if ( aErrors[ 0 ].hasValue() )
+ {
+ // error occured.
+ OSL_ENSURE( sal_False, "error setting Title property!" );
+ return false;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//=========================================================================
+uno::Reference< ucb::XContent > createNew(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XContent > & xTarget,
+ sal_Bool bSourceIsFolder,
+ sal_Bool bSourceIsDocument,
+ sal_Bool bSourceIsLink )
+ throw( uno::Exception )
+{
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (1) Obtain creatable types from target.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ // First, try it using "CreatabeleContentsInfo" property and
+ // "createNewContent" command -> the "new" way.
+
+ uno::Reference< ucb::XCommandProcessor > xCommandProcessorT(
+ xTarget, uno::UNO_QUERY );
+ if ( !xCommandProcessorT.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(rContext.aArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii( "Target is no XCommandProcessor!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ uno::Sequence< beans::Property > aPropsToObtain( 1 );
+ aPropsToObtain[ 0 ].Name
+ = rtl::OUString::createFromAscii( "CreatableContentsInfo" );
+ aPropsToObtain[ 0 ].Handle
+ = -1;
+
+ ucb::Command aGetPropsCommand(
+ rtl::OUString::createFromAscii( "getPropertyValues" ),
+ -1,
+ uno::makeAny( aPropsToObtain ) );
+
+ uno::Reference< sdbc::XRow > xRow;
+ xCommandProcessorT->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow;
+
+ uno::Sequence< ucb::ContentInfo > aTypesInfo;
+ bool bGotTypesInfo = false;
+
+ if ( xRow.is() )
+ {
+ uno::Any aValue = xRow->getObject(
+ 1, uno::Reference< container::XNameAccess >() );
+ if ( aValue.hasValue() && ( aValue >>= aTypesInfo ) )
+ {
+ bGotTypesInfo = true;
+ }
+ }
+
+ uno::Reference< ucb::XContentCreator > xCreator;
+
+ if ( !bGotTypesInfo )
+ {
+ // Second, try it using XContentCreator interface -> the "old" way (not
+ // providing the chance to supply an XCommandEnvironment.
+
+ xCreator.set( xTarget, uno::UNO_QUERY );
+
+ if ( !xCreator.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(rContext.aArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii( "Target is no XContentCreator!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ aTypesInfo = xCreator->queryCreatableContentsInfo();
+ }
+
+ sal_Int32 nCount = aTypesInfo.getLength();
+ if ( !nCount )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Folder")),
+ -1,
+ uno::makeAny(rContext.aArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii( "No types creatable!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (2) Try to find a matching target type for the source object.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContent > xNew;
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ sal_Int32 nAttribs = aTypesInfo[ n ].Attributes;
+ sal_Bool bMatch = sal_False;
+
+ if ( rContext.aArg.Operation == ucb::TransferCommandOperation_LINK )
+ {
+ // Create link
+
+ if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
+ {
+ // Match!
+ bMatch = sal_True;
+ }
+ }
+ else if ( ( rContext.aArg.Operation
+ == ucb::TransferCommandOperation_COPY ) ||
+ ( rContext.aArg.Operation
+ == ucb::TransferCommandOperation_MOVE ) )
+ {
+ // Copy / Move
+
+ // Is source a link? Create link in target folder then.
+ if ( bSourceIsLink )
+ {
+ if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
+ {
+ // Match!
+ bMatch = sal_True;
+ }
+ }
+ else
+ {
+ // (not a and not b) or (a and b)
+ // not( a or b) or (a and b)
+ //
+ if ( ( !!bSourceIsFolder ==
+ !!( nAttribs
+ & ucb::ContentInfoAttribute::KIND_FOLDER ) )
+ &&
+ ( !!bSourceIsDocument ==
+ !!( nAttribs
+ & ucb::ContentInfoAttribute::KIND_DOCUMENT ) )
+ )
+ {
+ // Match!
+ bMatch = sal_True;
+ }
+ }
+ }
+ else
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Unknown transfer operation!" ),
+ rContext.xProcessor,
+ -1 ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+
+ if ( bMatch )
+ {
+ //////////////////////////////////////////////////////////////
+ //
+ // (3) Create a new, empty object of matched type.
+ //
+ //////////////////////////////////////////////////////////////
+
+ if ( !xCreator.is() )
+ {
+ // First, try it using "CreatabeleContentsInfo" property and
+ // "createNewContent" command -> the "new" way.
+ ucb::Command aCreateNewCommand(
+ rtl::OUString::createFromAscii( "createNewContent" ),
+ -1,
+ uno::makeAny( aTypesInfo[ n ] ) );
+
+ xCommandProcessorT->execute( aCreateNewCommand, 0, rContext.xEnv )
+ >>= xNew;
+ }
+ else
+ {
+ // Second, try it using XContentCreator interface -> the "old"
+ // way (not providing the chance to supply an XCommandEnvironment.
+
+ xNew = xCreator->createNewContent( aTypesInfo[ n ] );
+ }
+
+ if ( !xNew.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(rContext.aArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "createNewContent failed!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+ break; // escape from 'for' loop
+ }
+ } // for
+
+ return xNew;
+}
+
+//=========================================================================
+void transferProperties(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS,
+ const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorN )
+ throw( uno::Exception )
+{
+ ucb::Command aGetPropertySetInfoCommand(
+ rtl::OUString::createFromAscii( "getPropertySetInfo" ),
+ -1,
+ uno::Any() );
+
+ uno::Reference< beans::XPropertySetInfo > xInfo;
+ xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv )
+ >>= xInfo;
+
+ if ( !xInfo.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rContext.aArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get propertyset info from source object!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ uno::Sequence< beans::Property > aAllProps = xInfo->getProperties();
+
+ ucb::Command aGetPropsCommand1(
+ rtl::OUString::createFromAscii( "getPropertyValues" ),
+ -1,
+ uno::makeAny( aAllProps ) );
+
+ uno::Reference< sdbc::XRow > xRow1;
+ xCommandProcessorS->execute(
+ aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1;
+
+ if ( !xRow1.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rContext.aArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get properties from source object!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ // Assemble data structure for setPropertyValues command.
+
+ // Note: Make room for additional Title and TargetURL too. -> + 2
+ uno::Sequence< beans::PropertyValue > aPropValues(
+ aAllProps.getLength() + 2 );
+
+ sal_Bool bHasTitle = ( rContext.aArg.NewTitle.getLength() == 0 );
+ sal_Bool bHasTargetURL = ( rContext.aArg.Operation
+ != ucb::TransferCommandOperation_LINK );
+
+ sal_Int32 nWritePos = 0;
+ for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m )
+ {
+ const beans::Property & rCurrProp = aAllProps[ m ];
+ beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ];
+
+ uno::Any aValue;
+
+ if ( rCurrProp.Name.compareToAscii( "Title" ) == 0 )
+ {
+ // Supply new title, if given.
+ if ( !bHasTitle )
+ {
+ bHasTitle = sal_True;
+ aValue <<= rContext.aArg.NewTitle;
+ }
+ }
+ else if ( rCurrProp.Name.compareToAscii( "TargetURL" ) == 0 )
+ {
+ // Supply source URL as link target for the new link to create.
+ if ( !bHasTargetURL )
+ {
+ bHasTargetURL = sal_True;
+ aValue <<= rContext.aArg.SourceURL;
+ }
+ }
+
+ if ( !aValue.hasValue() )
+ {
+ try
+ {
+ aValue = xRow1->getObject(
+ m + 1, uno::Reference< container::XNameAccess >() );
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ // Argh! But try to bring things to an end. Perhaps the
+ // mad property is not really important...
+ }
+ }
+
+ if ( aValue.hasValue() )
+ {
+ rCurrValue.Name = rCurrProp.Name;
+ rCurrValue.Handle = rCurrProp.Handle;
+ rCurrValue.Value = aValue;
+// rCurrValue.State =
+
+ nWritePos++;
+ }
+ }
+
+ // Title needed, but not set yet?
+ if ( !bHasTitle && ( rContext.aArg.NewTitle.getLength() > 0 ) )
+ {
+ aPropValues[ nWritePos ].Name
+ = rtl::OUString::createFromAscii( "Title" );
+ aPropValues[ nWritePos ].Handle = -1;
+ aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle;
+
+ nWritePos++;
+ }
+
+ // TargetURL needed, but not set yet?
+ if ( !bHasTargetURL && ( rContext.aArg.Operation
+ == ucb::TransferCommandOperation_LINK ) )
+ {
+ aPropValues[ nWritePos ].Name
+ = rtl::OUString::createFromAscii( "TargetURL" );
+ aPropValues[ nWritePos ].Handle = -1;
+ aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL;
+
+ nWritePos++;
+ }
+
+ aPropValues.realloc( nWritePos );
+
+ // Set properties at new object.
+
+ ucb::Command aSetPropsCommand(
+ rtl::OUString::createFromAscii( "setPropertyValues" ),
+ -1,
+ uno::makeAny( aPropValues ) );
+
+ xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv );
+
+ // @@@ What to do with source props that are not supported by the
+ // new object? addProperty ???
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > getInputStream(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
+ throw( uno::Exception )
+{
+ uno::Reference< io::XInputStream > xInputStream;
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (1) Try to get data as XInputStream via XActiveDataSink.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink;
+
+ ucb::OpenCommandArgument2 aArg;
+ aArg.Mode = ucb::OpenMode::DOCUMENT;
+ aArg.Priority = 0; // unused
+ aArg.Sink = xSink;
+ aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused
+
+ ucb::Command aOpenCommand(
+ rtl::OUString::createFromAscii( "open" ),
+ -1,
+ uno::makeAny( aArg ) );
+
+ xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
+ xInputStream = xSink->getInputStream();
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // will be handled below.
+ }
+
+ if ( !xInputStream.is() )
+ {
+ //////////////////////////////////////////////////////////////////
+ //
+ // (2) Try to get data via XOutputStream.
+ //
+ //////////////////////////////////////////////////////////////////
+
+ try
+ {
+ uno::Reference< io::XOutputStream > xOutputStream(
+ rContext.xSMgr->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.io.Pipe" ) ),
+ uno::UNO_QUERY );
+
+ if ( xOutputStream.is() )
+ {
+ ucb::OpenCommandArgument2 aArg;
+ aArg.Mode = ucb::OpenMode::DOCUMENT;
+ aArg.Priority = 0; // unused
+ aArg.Sink = xOutputStream;
+ aArg.Properties = uno::Sequence< beans::Property >( 0 );
+
+ ucb::Command aOpenCommand(
+ rtl::OUString::createFromAscii( "open" ),
+ -1,
+ uno::makeAny( aArg ) );
+
+ xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
+
+ xInputStream = uno::Reference< io::XInputStream >(
+ xOutputStream, uno::UNO_QUERY );
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False, "unable to get input stream from document!" );
+ }
+ }
+
+ return xInputStream;
+}
+
+//=========================================================================
+uno::Reference< sdbc::XResultSet > getResultSet(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
+ throw( uno::Exception )
+{
+ uno::Reference< sdbc::XResultSet > xResultSet;
+
+ uno::Sequence< beans::Property > aProps( 3 );
+
+ aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" );
+ aProps[ 0 ].Handle = -1; /* unknown */
+ aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" );
+ aProps[ 1 ].Handle = -1; /* unknown */
+ aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" );
+ aProps[ 2 ].Handle = -1; /* unknown */
+
+ ucb::OpenCommandArgument2 aArg;
+ aArg.Mode = ucb::OpenMode::ALL;
+ aArg.Priority = 0; // unused
+ aArg.Sink = 0;
+ aArg.Properties = aProps;
+
+ ucb::Command aOpenCommand( rtl::OUString::createFromAscii( "open" ),
+ -1,
+ uno::makeAny( aArg ) );
+ try
+ {
+ uno::Reference< ucb::XDynamicResultSet > xSet;
+ xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet;
+
+ if ( xSet.is() )
+ xResultSet = xSet->getStaticResultSet();
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False, "unable to get result set from folder!" );
+ }
+
+ return xResultSet;
+}
+
+//=========================================================================
+void handleNameClashRename(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XContent > & xNew,
+ const uno::Reference<
+ ucb::XCommandProcessor > & xCommandProcessorN,
+ const uno::Reference<
+ ucb::XCommandProcessor > & xCommandProcessorS,
+ /* [inout] */ uno::Reference< io::XInputStream > & xInputStream )
+ throw( uno::Exception )
+{
+ sal_Int32 nTry = 0;
+
+ // Obtain old title.
+ uno::Sequence< beans::Property > aProps( 1 );
+ aProps[ 0 ].Name = rtl::OUString::createFromAscii( "Title" );
+ aProps[ 0 ].Handle = -1;
+
+ ucb::Command aGetPropsCommand(
+ rtl::OUString::createFromAscii( "getPropertyValues" ),
+ -1,
+ uno::makeAny( aProps ) );
+
+ uno::Reference< sdbc::XRow > xRow;
+ xCommandProcessorN->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow;
+
+ if ( !xRow.is() )
+ {
+ uno::Any aProps2
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
+ -1,
+ uno::makeAny(
+ xNew->getIdentifier()->getContentIdentifier() ),
+ beans::PropertyState_DIRECT_VALUE ) );
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >( &aProps2, 1 ),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get properties from new object!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ rtl::OUString aOldTitle = xRow->getString( 1 );
+ if ( !aOldTitle.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Unable to get property 'Title' "
+ "from new object!" ),
+ rContext.xProcessor ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+
+ // Some pseudo-intelligence for not destroying file extensions.
+ rtl::OUString aOldTitlePre;
+ rtl::OUString aOldTitlePost;
+ sal_Int32 nPos = aOldTitle.lastIndexOf( '.' );
+ if ( nPos != -1 )
+ {
+ aOldTitlePre = aOldTitle.copy( 0, nPos );
+ aOldTitlePost = aOldTitle.copy( nPos );
+ }
+ else
+ aOldTitlePre = aOldTitle;
+
+ if ( nPos > 0 )
+ aOldTitlePre += rtl::OUString::createFromAscii( "_" );
+
+ sal_Bool bContinue = sal_True;
+ do
+ {
+ nTry++;
+
+ rtl::OUString aNewTitle = aOldTitlePre;
+ aNewTitle += rtl::OUString::valueOf( nTry );
+ aNewTitle += aOldTitlePost;
+
+ // Set new title
+ setTitle( xCommandProcessorN, rContext.xEnv, aNewTitle );
+
+ // Retry inserting the content.
+ try
+ {
+ // Previous try may have read from stream. Seek to begin (if
+ // optional interface XSeekable is supported) or get a new stream.
+ if ( xInputStream.is() )
+ {
+ uno::Reference< io::XSeekable > xSeekable(
+ xInputStream, uno::UNO_QUERY );
+ if ( xSeekable.is() )
+ {
+ try
+ {
+ xSeekable->seek( 0 );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ xInputStream.clear();
+ }
+ catch ( io::IOException const & )
+ {
+ xInputStream.clear();
+ }
+ }
+ else
+ xInputStream.clear();
+
+ if ( !xInputStream.is() )
+ {
+ xInputStream
+ = getInputStream( rContext, xCommandProcessorS );
+ if ( !xInputStream.is() )
+ {
+ uno::Any aProps2
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
+ -1,
+ uno::makeAny(
+ xNew->getIdentifier()->
+ getContentIdentifier() ),
+ beans::PropertyState_DIRECT_VALUE ) );
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >( &aProps2, 1 ),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Got no data stream from source!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+ }
+ }
+
+ ucb::InsertCommandArgument aArg;
+ aArg.Data = xInputStream;
+ aArg.ReplaceExisting = sal_False;
+
+ ucb::Command aInsertCommand(
+ rtl::OUString::createFromAscii( "insert" ),
+ -1,
+ uno::makeAny( aArg ) );
+
+ xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
+
+ // Success!
+ bContinue = sal_False;
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+ }
+ while ( bContinue && ( nTry < 50 ) );
+
+ if ( nTry == 50 )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clash!" ),
+ rContext.xProcessor,
+ ucb::NameClash::RENAME ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+}
+
+//=========================================================================
+void globalTransfer_(
+ const TransferCommandContext & rContext,
+ const uno::Reference< ucb::XContent > & xSource,
+ const uno::Reference< ucb::XContent > & xTarget,
+ const uno::Reference< sdbc::XRow > & xSourceProps )
+ throw( uno::Exception )
+{
+ // IsFolder: property is required.
+ sal_Bool bSourceIsFolder = xSourceProps->getBoolean( 1 );
+ if ( !bSourceIsFolder && xSourceProps->wasNull() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Unable to get property 'IsFolder' "
+ "from source object!" ),
+ rContext.xProcessor ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+
+ // IsDocument: property is required.
+ sal_Bool bSourceIsDocument = xSourceProps->getBoolean( 2 );
+ if ( !bSourceIsDocument && xSourceProps->wasNull() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Unable to get property 'IsDocument' "
+ "from source object!" ),
+ rContext.xProcessor ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+
+ // TargetURL: property is optional.
+ sal_Bool bSourceIsLink = ( xSourceProps->getString( 3 ).getLength() > 0 );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (1) Try to find a matching target type for the source object and
+ // create a new, empty object of that type.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContent > xNew = createNew( rContext,
+ xTarget,
+ bSourceIsFolder,
+ bSourceIsDocument,
+ bSourceIsLink );
+ if ( !xNew.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(rContext.aArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "No matching content type at target!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (2) Transfer property values from source to new object.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XCommandProcessor > xCommandProcessorN(
+ xNew, uno::UNO_QUERY );
+ if ( !xCommandProcessorN.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(
+ xNew->getIdentifier()->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "New content is not a XCommandProcessor!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ // Obtain all properties from source.
+
+ uno::Reference< ucb::XCommandProcessor > xCommandProcessorS(
+ xSource, uno::UNO_QUERY );
+ if ( !xCommandProcessorS.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rContext.aArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Source content is not a XCommandProcessor!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ transferProperties( rContext, xCommandProcessorS, xCommandProcessorN );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (3) Try to obtain a data stream from source.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< io::XInputStream > xInputStream;
+
+ if ( bSourceIsDocument && ( rContext.aArg.Operation
+ != ucb::TransferCommandOperation_LINK ) )
+ xInputStream = getInputStream( rContext, xCommandProcessorS );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (4) Try to obtain a resultset (children) from source.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< sdbc::XResultSet > xResultSet;
+
+ if ( bSourceIsFolder && ( rContext.aArg.Operation
+ != ucb::TransferCommandOperation_LINK ) )
+ xResultSet = getResultSet( rContext, xCommandProcessorS );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (5) Insert (store) new content.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ ucb::InsertCommandArgument aArg;
+ aArg.Data = xInputStream;
+
+ switch ( rContext.aArg.NameClash )
+ {
+ case ucb::NameClash::OVERWRITE:
+ aArg.ReplaceExisting = sal_True;
+ break;
+
+ case ucb::NameClash::ERROR:
+ case ucb::NameClash::RENAME:
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ aArg.ReplaceExisting = sal_False;
+ break;
+
+ default:
+ aArg.ReplaceExisting = sal_False;
+ OSL_ENSURE( sal_False, "Unknown nameclash directive!" );
+ break;
+ }
+
+ rtl::OUString aDesiredName = createDesiredName( rContext.aArg );
+
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+
+ try
+ {
+ ucb::Command aInsertCommand(
+ rtl::OUString::createFromAscii( "insert" ),
+ -1,
+ uno::makeAny( aArg ) );
+
+ xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
+ }
+ catch ( ucb::UnsupportedNameClashException const & exc )
+ {
+ OSL_ENSURE( !aArg.ReplaceExisting,
+ "BUG: UnsupportedNameClashException not allowed here!" );
+
+ if (exc.NameClash != ucb::NameClash::ERROR) {
+ OSL_ENSURE( false, "BUG: NameClash::ERROR expected!" );
+ }
+
+ // No chance to solve name clashes, because I'm not able to detect
+ // whether there is one.
+ throw ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clashes, no chance to detect "
+ "that there is one!" ),
+ rContext.xProcessor,
+ rContext.aArg.NameClash );
+ }
+ catch ( ucb::NameClashException const & )
+ {
+ // The 'insert' command throws a NameClashException if the parameter
+ // ReplaceExisting of the command's argument was set to false and
+ // there exists a resource with a clashing name in the target folder
+ // of the operation.
+
+ // 'insert' command has no direct support for name clashes other
+ // than ERROR ( ReplaceExisting == false ) and OVERWRITE
+ // ( ReplaceExisting == true ). So we have to implement the
+ // other name clash handling directives on top of the content.
+
+ // @@@ 'insert' command should be extended that it accepts a
+ // name clash handling directive, exactly like 'transfer' command.
+
+ switch ( rContext.aArg.NameClash )
+ {
+ case ucb::NameClash::OVERWRITE:
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "BUG: insert + replace == true MUST NOT "
+ "throw NameClashException." ),
+ rContext.xProcessor,
+ rContext.aArg.NameClash ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+
+ case ucb::NameClash::ERROR:
+ throw;
+
+ case ucb::NameClash::RENAME:
+ {
+ // "invent" a new valid title.
+ handleNameClashRename( rContext,
+ xNew,
+ xCommandProcessorN,
+ xCommandProcessorS,
+ xInputStream );
+ break;
+ }
+
+ case ucb::NameClash::ASK:
+ {
+ uno::Any aExc;
+ rtl::OUString aNewTitle;
+ NameClashContinuation eCont
+ = interactiveNameClashResolve(
+ rContext.xOrigEnv, // always use original environment!
+ rContext.aArg.TargetURL, // target folder URL
+ aDesiredName,
+ aExc,
+ aNewTitle );
+
+ switch ( eCont )
+ {
+ case NOT_HANDLED:
+ // Not handled.
+ cppu::throwException( aExc );
+ // break;
+
+ case UNKNOWN:
+ // Handled, but not clear, how...
+ // fall-thru intended.
+
+ case ABORT:
+ throw ucb::CommandFailedException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "abort requested via interaction "
+ "handler" ) ),
+ uno::Reference< uno::XInterface >(),
+ aExc );
+ // break;
+
+ case OVERWRITE:
+ OSL_ENSURE( aArg.ReplaceExisting == sal_False,
+ "Hu? ReplaceExisting already true?"
+ );
+ aArg.ReplaceExisting = sal_True;
+ bRetry = true;
+ break;
+
+ case NEW_NAME:
+ {
+ // set new name -> set "Title" property...
+ if ( setTitle( xCommandProcessorN,
+ rContext.xEnv,
+ aNewTitle ) )
+ {
+ // remember suggested title...
+ aDesiredName = aNewTitle;
+
+ // ... and try again.
+ bRetry = true;
+ }
+ else
+ {
+ // error setting title. Abort.
+ throw ucb::CommandFailedException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "error setting Title property!"
+ ) ),
+ uno::Reference< uno::XInterface >(),
+ aExc );
+ }
+ break;
+ }
+ }
+
+ OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ default:
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "default action, don't know how to "
+ "handle name clash" ) ),
+ rContext.xProcessor,
+ rContext.aArg.NameClash ) ),
+ rContext.xOrigEnv );
+ // Unreachable
+ }
+ }
+ }
+ }
+ while ( bRetry );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (6) Process children of source.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xResultSet.is() )
+ {
+ try
+ {
+ // Iterate over children...
+
+ uno::Reference< sdbc::XRow > xChildRow(
+ xResultSet, uno::UNO_QUERY );
+
+ if ( !xChildRow.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rContext.aArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get properties from children of source!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ uno::Reference< ucb::XContentAccess > xChildAccess(
+ xResultSet, uno::UNO_QUERY );
+
+ if ( !xChildAccess.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rContext.aArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ rContext.xOrigEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get children of source!" ),
+ rContext.xProcessor );
+ // Unreachable
+ }
+
+ if ( xResultSet->first() )
+ {
+ ucb::GlobalTransferCommandArgument aTransArg(
+ rContext.aArg.Operation, // Operation
+ rtl::OUString(), // SourceURL; filled later
+ xNew->getIdentifier()
+ ->getContentIdentifier(), // TargetURL
+ rtl::OUString(), // NewTitle;
+ rContext.aArg.NameClash ); // NameClash
+
+ TransferCommandContext aSubCtx(
+ rContext.xSMgr,
+ rContext.xProcessor,
+ rContext.xEnv,
+ rContext.xOrigEnv,
+ aTransArg );
+ do
+ {
+ uno::Reference< ucb::XContent > xChild
+ = xChildAccess->queryContent();
+ if ( xChild.is() )
+ {
+ // Recursion!
+
+ aSubCtx.aArg.SourceURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ globalTransfer_( aSubCtx,
+ xChild,
+ xNew,
+ xChildRow );
+ }
+ }
+ while ( xResultSet->next() );
+ }
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ }
+ }
+
+ try {
+ uno::Reference< ucb::XCommandProcessor > xcp(
+ xTarget, uno::UNO_QUERY );
+
+ uno::Any aAny;
+ uno::Reference< ucb::XCommandInfo > xci;
+ if(xcp.is())
+ aAny =
+ xcp->execute(
+ ucb::Command(
+ rtl::OUString::createFromAscii("getCommandInfo"),
+ -1,
+ uno::Any()),
+ 0,
+ rContext.xEnv );
+
+ const rtl::OUString cmdName =
+ rtl::OUString::createFromAscii("flush");
+ if((aAny >>= xci) && xci->hasCommandByName(cmdName))
+ xcp->execute(
+ ucb::Command(
+ cmdName,
+ -1,
+ uno::Any()) ,
+ 0,
+ rContext.xEnv );
+ }
+ catch( uno::Exception const & )
+ {
+ }
+}
+
+} /* namescpace */
+
+//=========================================================================
+//
+// UniversalContentBroker implementation ( XCommandProcessor commands ).
+//
+//=========================================================================
+
+uno::Reference< ucb::XCommandInfo >
+UniversalContentBroker::getCommandInfo()
+{
+ return uno::Reference< ucb::XCommandInfo >( new CommandProcessorInfo() );
+}
+
+//=========================================================================
+void UniversalContentBroker::globalTransfer(
+ const ucb::GlobalTransferCommandArgument & rArg,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ // Use own command environment with own interaction handler intercepting
+ // some interaction requests that shall not be handled by the user-supplied
+ // interaction handler.
+ uno::Reference< ucb::XCommandEnvironment > xLocalEnv;
+ if (xEnv.is())
+ {
+ uno::Reference< beans::XPropertySet > const xProps(
+ m_xSMgr, uno::UNO_QUERY_THROW );
+ uno::Reference< uno::XComponentContext > xCtx;
+ xCtx.set( xProps->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
+ uno::UNO_QUERY_THROW );
+
+ xLocalEnv.set( ucb::CommandEnvironment::create(
+ xCtx,
+ new InteractionHandlerProxy( xEnv->getInteractionHandler() ),
+ xEnv->getProgressHandler() ) );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (1) Try to transfer the content using 'transfer' command.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContent > xTarget;
+ uno::Reference< ucb::XContentIdentifier > xId
+ = createContentIdentifier( rArg.TargetURL );
+ if ( xId.is() )
+ {
+ try
+ {
+ xTarget = queryContent( xId );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ }
+ }
+
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Can't instanciate target object!" ),
+ this );
+ // Unreachable
+ }
+
+ if ( ( rArg.Operation == ucb::TransferCommandOperation_COPY ) ||
+ ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) )
+ {
+ uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
+ xTarget, uno::UNO_QUERY );
+ if ( !xCommandProcessor.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rArg.TargetURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Target content is not a XCommandProcessor!" ),
+ this );
+ // Unreachable
+ }
+
+ ucb::TransferInfo aTransferArg(
+ ( rArg.Operation
+ == ucb::TransferCommandOperation_MOVE ), // MoveData
+ rArg.SourceURL, // SourceURL
+ rArg.NewTitle, // NewTitle
+ rArg.NameClash ); // NameClash
+
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+
+ try
+ {
+ ucb::Command aCommand(
+ rtl::OUString::createFromAscii( "transfer" ), // Name
+ -1, // Handle
+ uno::makeAny( aTransferArg ) ); // Argument
+
+ xCommandProcessor->execute( aCommand, 0, xLocalEnv );
+
+ // Command succeeded. We're done.
+ return;
+ }
+ catch ( ucb::InteractiveBadTransferURLException const & )
+ {
+ // Source URL is not supported by target. Try to transfer
+ // the content "manually".
+ }
+ catch ( ucb::UnsupportedCommandException const & )
+ {
+ // 'transfer' command is not supported by commandprocessor.
+ // Try to transfer manually.
+ }
+ catch ( ucb::UnsupportedNameClashException const & exc )
+ {
+ OSL_ENSURE( aTransferArg.NameClash == exc.NameClash,
+ "nameclash mismatch!" );
+ if ( exc.NameClash == ucb::NameClash::ASK )
+ {
+ // Try to detect a name clash by invoking "transfer" with
+ // NameClash::ERROR.
+ try
+ {
+ ucb::TransferInfo aTransferArg1(
+ aTransferArg.MoveData,
+ aTransferArg.SourceURL,
+ aTransferArg.NewTitle,
+ ucb::NameClash::ERROR );
+
+ ucb::Command aCommand1(
+ rtl::OUString::createFromAscii( "transfer" ),
+ -1,
+ uno::makeAny( aTransferArg1 ) );
+
+ xCommandProcessor->execute( aCommand1, 0, xLocalEnv );
+
+ // Command succeeded. We're done.
+ return;
+ }
+ catch ( ucb::UnsupportedNameClashException const & )
+ {
+ // No chance to solve name clashes, because I'm not
+ // able to detect whether there is one.
+ throw exc; // Not just 'throw;'!
+ }
+ catch ( ucb::NameClashException const & )
+ {
+ // There's a clash. Use interaction handler to solve it.
+
+ uno::Any aExc;
+ rtl::OUString aNewTitle;
+ NameClashContinuation eCont
+ = interactiveNameClashResolve(
+ xEnv, // always use original environment!
+ rArg.TargetURL, // target folder URL
+ createDesiredName(
+ aTransferArg ), // clashing name
+ aExc,
+ aNewTitle );
+
+ switch ( eCont )
+ {
+ case NOT_HANDLED:
+ // Not handled.
+ cppu::throwException( aExc );
+// break;
+
+ case UNKNOWN:
+ // Handled, but not clear, how...
+ // fall-thru intended.
+
+ case ABORT:
+ throw ucb::CommandFailedException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "abort requested via interaction "
+ "handler" ) ),
+ uno::Reference< uno::XInterface >(),
+ aExc );
+// break;
+
+ case OVERWRITE:
+ aTransferArg.NameClash
+ = ucb::NameClash::OVERWRITE;
+ bRetry = true;
+ break;
+
+ case NEW_NAME:
+ aTransferArg.NewTitle = aNewTitle;
+ bRetry = true;
+ break;
+ }
+
+ OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
+ }
+ }
+ else
+ {
+ throw;
+ }
+ }
+ }
+ while ( bRetry );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (2) Try to transfer the content "manually".
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContent > xSource;
+ try
+ {
+ uno::Reference< ucb::XContentIdentifier > xId2
+ = createContentIdentifier( rArg.SourceURL );
+ if ( xId2.is() )
+ xSource = queryContent( xId2 );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // Error handling via "if ( !xSource.is() )" below.
+ }
+
+ if ( !xSource.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Can't instanciate source object!" ),
+ this );
+ // Unreachable
+ }
+
+ uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
+ xSource, uno::UNO_QUERY );
+ if ( !xCommandProcessor.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Source content is not a XCommandProcessor!" ),
+ this );
+ // Unreachable
+ }
+
+ // Obtain interesting property values from source...
+
+ uno::Sequence< beans::Property > aProps( 4 );
+
+ aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" );
+ aProps[ 0 ].Handle = -1; /* unknown */
+ aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" );
+ aProps[ 1 ].Handle = -1; /* unknown */
+ aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" );
+ aProps[ 2 ].Handle = -1; /* unknown */
+ aProps[ 3 ].Name = rtl::OUString::createFromAscii( "BaseURI" );
+ aProps[ 3 ].Handle = -1; /* unknown */
+
+ ucb::Command aGetPropsCommand(
+ rtl::OUString::createFromAscii( "getPropertyValues" ),
+ -1,
+ uno::makeAny( aProps ) );
+
+ uno::Reference< sdbc::XRow > xRow;
+ xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow;
+
+ if ( !xRow.is() )
+ {
+ uno::Any aProps2
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(rArg.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps2, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Unable to get properties from source object!" ),
+ this );
+ // Unreachable
+ }
+
+ TransferCommandContext aTransferCtx(
+ m_xSMgr, this, xLocalEnv, xEnv, rArg );
+
+ if ( rArg.NewTitle.getLength() == 0 )
+ {
+ // BaseURI: property is optional.
+ rtl::OUString aBaseURI( xRow->getString( 4 ) );
+ if ( aBaseURI.getLength() )
+ {
+ aTransferCtx.aArg.NewTitle
+ = createDesiredName( aBaseURI, rtl::OUString() );
+ }
+ }
+
+ // Do it!
+ globalTransfer_( aTransferCtx, xSource, xTarget, xRow );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // (3) Delete source, if operation is MOVE.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ if ( rArg.Operation == ucb::TransferCommandOperation_MOVE )
+ {
+ try
+ {
+ ucb::Command aCommand(
+ rtl::OUString::createFromAscii( "delete" ), // Name
+ -1, // Handle
+ uno::makeAny( sal_Bool( sal_True ) ) ); // Argument
+
+ xCommandProcessor->execute( aCommand, 0, xLocalEnv );
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False, "Cannot delete source object!" );
+ throw;
+ }
+ }
+}
diff --git a/ucb/source/core/ucbcmds.hxx b/ucb/source/core/ucbcmds.hxx
new file mode 100644
index 000000000000..7e50bcceef93
--- /dev/null
+++ b/ucb/source/core/ucbcmds.hxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCBCMDS_HXX
+#define _UCBCMDS_HXX
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Definitions for the commands supported by the UCB.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#define GETCOMMANDINFO_NAME "getCommandInfo"
+#define GETCOMMANDINFO_HANDLE 1024
+
+#define GLOBALTRANSFER_NAME "globalTransfer"
+#define GLOBALTRANSFER_HANDLE 1025
+
+#endif /* !_UCBCMDS_HXX */
diff --git a/ucb/source/core/ucbprops.cxx b/ucb/source/core/ucbprops.cxx
new file mode 100644
index 000000000000..564383fd528a
--- /dev/null
+++ b/ucb/source/core/ucbprops.cxx
@@ -0,0 +1,477 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/ucb/CrossReference.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/ucb/DocumentHeaderField.hpp>
+#include <com/sun/star/ucb/RecipientInfo.hpp>
+#include <com/sun/star/ucb/RuleSet.hpp>
+#include <com/sun/star/ucb/SendInfo.hpp>
+#include <com/sun/star/ucb/SendMediaTypes.hpp>
+#include <com/sun/star/ucb/XDataContainer.hpp>
+#include "ucbprops.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+
+//=========================================================================
+//
+// struct PropertyTableEntry
+//
+//=========================================================================
+
+struct PropertyTableEntry
+{
+ const char* pName;
+ sal_Int32 nHandle;
+ sal_Int16 nAttributes;
+ const com::sun::star::uno::Type& (*pGetCppuType)();
+};
+
+//////////////////////////////////////////////////////////////////////////
+//
+// CPPU type access functions.
+//
+//////////////////////////////////////////////////////////////////////////
+
+static const com::sun::star::uno::Type& OUString_getCppuType()
+{
+ return getCppuType( static_cast< const rtl::OUString * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& sal_uInt16_getCppuType()
+{
+ // ! uInt -> Int, because of Java !!!
+ return getCppuType( static_cast< const sal_Int16 * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& sal_uInt32_getCppuType()
+{
+ // ! uInt -> Int, because of Java !!!
+ return getCppuType( static_cast< const sal_Int32 * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& sal_uInt64_getCppuType()
+{
+ // ! uInt -> Int, because of Java !!!
+ return getCppuType( static_cast< const sal_Int64 * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& enum_getCppuType()
+{
+ // ! enum -> Int, because of Java !!!
+ return getCppuType( static_cast< const sal_Int16 * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& sal_Bool_getCppuType()
+{
+ return getCppuBooleanType();
+}
+
+static const com::sun::star::uno::Type& byte_getCppuType()
+{
+ return getCppuType( static_cast< const sal_Int8 * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_CrossReference_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence<
+ com::sun::star::ucb::CrossReference > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& DateTime_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::util::DateTime * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_byte_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence< sal_Int8 > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_DocumentHeaderField_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence<
+ com::sun::star::ucb::DocumentHeaderField > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& XDataContainer_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDataContainer > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_RecipientInfo_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence<
+ com::sun::star::ucb::RecipientInfo > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& RuleSet_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::ucb::RuleSet * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_SendInfo_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence<
+ com::sun::star::ucb::SendInfo > * >( 0 ) );
+}
+
+static const com::sun::star::uno::Type& Sequence_SendMediaTypes_getCppuType()
+{
+ return getCppuType(
+ static_cast< com::sun::star::uno::Sequence<
+ com::sun::star::ucb::SendMediaTypes > * >( 0 ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// A table with all well-known UCB properties.
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define ATTR_DEFAULT ( PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID | PropertyAttribute::MAYBEDEFAULT )
+
+static PropertyTableEntry __aPropertyTable[] =
+{
+ { "Account", -1 /* WID_ACCOUNT */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "AutoUpdateInterval", -1 /* WID_AUTOUPDATE_INTERVAL */, ATTR_DEFAULT, &sal_uInt32_getCppuType },
+ { "ConfirmEmpty", -1 /* WID_TRASHCAN_FLAG_CONFIRMEMPTY */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "ConnectionLimit", -1 /* WID_HTTP_CONNECTION_LIMIT */, ATTR_DEFAULT, &byte_getCppuType },
+ { "ConnectionMode", -1 /* WID_CONNECTION_MODE */, ATTR_DEFAULT, &enum_getCppuType },
+ { "ContentCountLimit", -1 /* WID_SHOW_MSGS_TIMELIMIT */, ATTR_DEFAULT, &sal_uInt16_getCppuType },
+ { "ContentType", -1 /* WID_CONTENT_TYPE */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Cookie", -1 /* WID_HTTP_COOKIE */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "CrossReferences", -1 /* WID_NEWS_XREFLIST */, ATTR_DEFAULT, &Sequence_CrossReference_getCppuType },
+ { "DateCreated", -1 /* WID_DATE_CREATED */, ATTR_DEFAULT, &DateTime_getCppuType },
+ { "DateModified", -1 /* WID_DATE_MODIFIED */, ATTR_DEFAULT, &DateTime_getCppuType },
+ { "DeleteOnServer", -1 /* WID_DELETE_ON_SERVER */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "DocumentBody", -1 /* WID_DOCUMENT_BODY */, ATTR_DEFAULT, &Sequence_byte_getCppuType },
+ { "DocumentCount", -1 /* WID_TOTALCONTENTCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt32_getCppuType },
+ { "DocumentCountMarked",
+ -1 /* WID_MARKED_DOCUMENT_COUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt32_getCppuType },
+ { "DocumentHeader", -1 /* WID_DOCUMENT_HEADER */, ATTR_DEFAULT, &Sequence_DocumentHeaderField_getCppuType },
+ { "DocumentStoreMode", -1 /* WID_MESSAGE_STOREMODE */, ATTR_DEFAULT, &enum_getCppuType },
+ { "DocumentViewMode", -1 /* WID_MESSAGEVIEW_MODE */, ATTR_DEFAULT, &enum_getCppuType },
+ { "FTPAccount", -1 /* WID_FTP_ACCOUNT */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Flags", -1 /* WID_FSYS_FLAGS */, ATTR_DEFAULT, &sal_uInt32_getCppuType },
+ { "FolderCount", -1 /* WID_FOLDER_COUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt32_getCppuType },
+ { "FolderViewMode", -1 /* WID_FOLDERVIEW_MODE */, ATTR_DEFAULT, &enum_getCppuType },
+ { "FreeSpace", -1 /* WID_FSYS_DISKSPACE_LEFT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt64_getCppuType },
+ { "HasDocuments", -1 /* WID_FLAG_HAS_MESSAGES */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_Bool_getCppuType },
+ { "HasFolders", -1 /* WID_FLAG_HAS_FOLDER */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_Bool_getCppuType },
+ { "IsAutoDelete", -1 /* WID_TRASHCAN_FLAG_AUTODELETE */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsAutoUpdate", -1 /* WID_UPDATE_ENABLED */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsDocument", -1 /* WID_FLAG_IS_MESSAGE */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_Bool_getCppuType },
+ { "IsFolder", -1 /* WID_FLAG_IS_FOLDER */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_Bool_getCppuType },
+ { "IsKeepExpired", -1 /* WID_HTTP_KEEP_EXPIRED */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsLimitedContentCount",
+ -1 /* WID_SHOW_MSGS_HAS_TIMELIMIT */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsMarked", -1 /* WID_IS_MARKED */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsRead", -1 /* WID_IS_READ */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsReadOnly", -1 /* WID_FLAG_READONLY */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsSubscribed", -1 /* WID_FLAG_SUBSCRIBED */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+// { "IsThreaded", -1 /* WID_THREADED */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "IsTimeLimitedStore", -1 /* WID_STORE_MSGS_HAS_TIMELIMIT */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "Keywords", -1 /* WID_KEYWORDS */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "LocalBase", -1 /* WID_LOCALBASE */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageBCC", -1 /* WID_BCC */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageBody", -1 /* WID_MESSAGEBODY */, ATTR_DEFAULT, &XDataContainer_getCppuType },
+ { "MessageCC", -1 /* WID_CC */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageFrom", -1 /* WID_FROM */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageId", -1 /* WID_MESSAGE_ID */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageInReplyTo", -1 /* WID_IN_REPLY_TO */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageReplyTo", -1 /* WID_REPLY_TO */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "MessageTo", -1 /* WID_TO */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "NewsGroups", -1 /* WID_NEWSGROUPS */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "NoCacheList", -1 /* WID_HTTP_NOCACHE_LIST */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Origin", -1 /* WID_TRASH_ORIGIN */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &OUString_getCppuType },
+ { "OutgoingMessageRecipients",
+ -1 /* WID_RECIPIENTLIST */, ATTR_DEFAULT, &Sequence_RecipientInfo_getCppuType },
+ { "OutgoingMessageState",
+ -1 /* WID_OUTMSGINTERNALSTATE */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &enum_getCppuType },
+ { "OutgoingMessageViewMode",
+ -1 /* WID_SENTMESSAGEVIEW_MODE */,
+ ATTR_DEFAULT, &enum_getCppuType },
+// { "OwnURL", -1 /* WID_OWN_URL */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Password", -1 /* WID_PASSWORD */, ATTR_DEFAULT, &OUString_getCppuType },
+// { "PresentationURL", -1 /* WID_REAL_URL */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+// &OUString_getCppuType },
+ { "Priority", -1 /* WID_PRIORITY */, ATTR_DEFAULT, &enum_getCppuType },
+ { "References", -1 /* WID_REFERENCES */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Referer", -1 /* WID_HTTP_REFERER */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "Rules", -1 /* WID_RULES */, ATTR_DEFAULT, &RuleSet_getCppuType },
+ { "SearchCriteria", -1 /* WID_SEARCH_CRITERIA */, ATTR_DEFAULT, &RuleSet_getCppuType },
+ { "SearchIndirections", -1 /* WID_SEARCH_INDIRECTIONS */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "SearchLocations", -1 /* WID_SEARCH_LOCATIONS */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "SearchRecursive", -1 /* WID_SEARCH_RECURSIVE */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "SeenCount", -1 /* WID_SEENCONTENTCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt32_getCppuType },
+ { "SendCopyTarget", -1 /* WID_SEND_COPY_TARGET */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendFormats", -1 /* WID_SEND_FORMATS */, ATTR_DEFAULT, &Sequence_SendMediaTypes_getCppuType },
+ { "SendFroms", -1 /* WID_SEND_FROM_DEFAULT */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendPasswords", -1 /* WID_SEND_PASSWORD */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendProtocolPrivate",-1 /* WID_SEND_PRIVATE_PROT_ID */, ATTR_DEFAULT, &sal_uInt16_getCppuType },
+ { "SendProtocolPublic", -1 /* WID_SEND_PUBLIC_PROT_ID */, ATTR_DEFAULT, &sal_uInt16_getCppuType },
+ { "SendReplyTos", -1 /* WID_SEND_REPLY_TO_DEFAULT */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendServerNames", -1 /* WID_SEND_SERVERNAME */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendUserNames", -1 /* WID_SEND_USERNAME */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType },
+ { "SendVIMPostOfficePath",
+ -1 /* WID_SEND_VIM_POPATH */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "ServerBase", -1 /* WID_SERVERBASE */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "ServerName", -1 /* WID_SERVERNAME */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "ServerPort", -1 /* WID_SERVERPORT */, ATTR_DEFAULT, &sal_uInt16_getCppuType },
+ { "Size", -1 /* WID_DOCUMENT_SIZE */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt64_getCppuType },
+ { "SizeLimit", -1 /* WID_SIZE_LIMIT */, ATTR_DEFAULT, &sal_uInt64_getCppuType },
+ { "SubscribedCount", -1 /* WID_SUBSCRNEWSGROUPCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY,
+ &sal_uInt32_getCppuType },
+ { "SynchronizePolicy", -1 /* WID_WHO_IS_MASTER */, ATTR_DEFAULT, &enum_getCppuType },
+ { "TargetFrames", -1 /* WID_TARGET_FRAMES */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "TargetURL", -1 /* WID_TARGET_URL */, ATTR_DEFAULT, &OUString_getCppuType },
+// { "ThreadingInfo", -1 /* WID_THREADING */, ATTR_DEFAULT, &Sequence_ThreadingInfo_getCppuType },
+ { "TimeLimitStore", -1 /* WID_STORE_MSGS_TIMELIMIT */, ATTR_DEFAULT, &sal_uInt16_getCppuType },
+ { "Title", -1 /* WID_TITLE */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "UpdateOnOpen", -1 /* WID_FLAG_UPDATE_ON_OPEN */, ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "UseOutBoxPrivateProtocolSettings",
+ -1 /* WID_SEND_PRIVATE_OUTBOXPROPS */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "UseOutBoxPublicProtocolSettings",
+ -1 /* WID_SEND_PUBLIC_OUTBOXPROPS */,
+ ATTR_DEFAULT, &sal_Bool_getCppuType },
+ { "UserName", -1 /* WID_USERNAME */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "UserSortCriterium", -1 /* WID_USER_SORT_CRITERIUM */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "VIMPostOfficePath", -1 /* WID_VIM_POPATH */, ATTR_DEFAULT, &OUString_getCppuType },
+ { "VerificationMode", -1 /* WID_HTTP_VERIFY_MODE */, ATTR_DEFAULT, &enum_getCppuType },
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // EOT.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ { 0, 0, 0, 0 }
+};
+
+//=========================================================================
+//=========================================================================
+//
+// UcbPropertiesManager Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+UcbPropertiesManager::UcbPropertiesManager(
+ const Reference< XMultiServiceFactory >& )
+: m_pProps( 0 )
+{
+}
+
+//=========================================================================
+// virtual
+UcbPropertiesManager::~UcbPropertiesManager()
+{
+ delete m_pProps;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3( UcbPropertiesManager,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetInfo );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3( UcbPropertiesManager,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetInfo );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( UcbPropertiesManager,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.UcbPropertiesManager" ),
+ OUString::createFromAscii(
+ PROPERTIES_MANAGER_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbPropertiesManager );
+
+//=========================================================================
+//
+// XPropertySetInfo methods.
+//
+//=========================================================================
+
+// virtual
+Sequence< Property > SAL_CALL UcbPropertiesManager::getProperties()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_pProps )
+ {
+ m_pProps = new Sequence< Property >( 128 );
+ Property* pProps = m_pProps->getArray();
+ sal_Int32 nPos = 0;
+ sal_Int32 nSize = m_pProps->getLength();
+
+ //////////////////////////////////////////////////////////////////
+ // Get info for well-known properties.
+ //////////////////////////////////////////////////////////////////
+
+ const PropertyTableEntry* pCurr = &__aPropertyTable[ 0 ];
+ while ( pCurr->pName )
+ {
+ if ( nSize <= nPos )
+ {
+ OSL_ENSURE( sal_False,
+ "UcbPropertiesManager::getProperties - "
+ "Initial size of property sequence too small!" );
+
+ m_pProps->realloc( 128 );
+ nSize += 128;
+ }
+
+ Property& rProp = pProps[ nPos ];
+
+ rProp.Name = OUString::createFromAscii( pCurr->pName );
+ rProp.Handle = pCurr->nHandle;
+ rProp.Type = pCurr->pGetCppuType();
+ rProp.Attributes = pCurr->nAttributes;
+
+ nPos++;
+ pCurr++;
+ }
+
+ if ( nPos > 0 )
+ {
+ m_pProps->realloc( nPos );
+ nSize = m_pProps->getLength();
+ }
+ }
+ return *m_pProps;
+}
+
+//=========================================================================
+// virtual
+Property SAL_CALL UcbPropertiesManager::getPropertyByName( const OUString& aName )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ Property aProp;
+ if ( queryProperty( aName, aProp ) )
+ return aProp;
+
+ throw UnknownPropertyException();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL UcbPropertiesManager::hasPropertyByName( const OUString& Name )
+ throw( RuntimeException )
+{
+ Property aProp;
+ return queryProperty( Name, aProp );
+}
+
+//=========================================================================
+//
+// Non-Interface methods.
+//
+//=========================================================================
+
+sal_Bool UcbPropertiesManager::queryProperty(
+ const OUString& rName, Property& rProp )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ getProperties();
+
+ const Property* pProps = m_pProps->getConstArray();
+ sal_Int32 nCount = m_pProps->getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const Property& rCurrProp = pProps[ n ];
+ if ( rCurrProp.Name == rName )
+ {
+ rProp = rCurrProp;
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
diff --git a/ucb/source/core/ucbprops.hxx b/ucb/source/core/ucbprops.hxx
new file mode 100644
index 000000000000..7908fa6af90c
--- /dev/null
+++ b/ucb/source/core/ucbprops.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCBPROPS_HXX
+#define _UCBPROPS_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+#include <ucbhelper/macros.hxx>
+
+//=========================================================================
+
+#define PROPERTIES_MANAGER_SERVICE_NAME "com.sun.star.ucb.PropertiesManager"
+
+//============================================================================
+//
+// class UcbPropertiesManager.
+//
+//============================================================================
+
+class UcbPropertiesManager :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::beans::XPropertySetInfo
+{
+ com::sun::star::uno::Sequence< com::sun::star::beans::Property >*
+ m_pProps;
+ osl::Mutex m_aMutex;
+
+private:
+ sal_Bool queryProperty( const rtl::OUString& rName,
+ com::sun::star::beans::Property& rProp );
+
+public:
+ UcbPropertiesManager( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >&
+ rxSMgr );
+ virtual ~UcbPropertiesManager();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XPropertySetInfo
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property > SAL_CALL
+ getProperties()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::beans::Property SAL_CALL
+ getPropertyByName( const rtl::OUString& aName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasPropertyByName( const rtl::OUString& Name )
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+#endif /* !_UCBPROPS_HXX */
+
diff --git a/ucb/source/core/ucbserv.cxx b/ucb/source/core/ucbserv.cxx
new file mode 100644
index 000000000000..340fa5db0c0f
--- /dev/null
+++ b/ucb/source/core/ucbserv.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "ucb.hxx"
+#include "ucbstore.hxx"
+#include "ucbprops.hxx"
+#include "provprox.hxx"
+#include "cmdenv.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const OUString & rImplementationName,
+ Sequence< OUString > const & rServiceNames )
+{
+ OUString aKeyName( OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Universal Content Broker.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ UniversalContentBroker::getImplementationName_Static(),
+ UniversalContentBroker::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // UCB Store.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ UcbStore::getImplementationName_Static(),
+ UcbStore::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // UCB PropertiesManager.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ UcbPropertiesManager::getImplementationName_Static(),
+ UcbPropertiesManager::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // UCP Proxy Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ UcbContentProviderProxyFactory::getImplementationName_Static(),
+ UcbContentProviderProxyFactory::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Command Environment.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ ucb_cmdenv::UcbCommandEnvironment::getImplementationName_Static(),
+ ucb_cmdenv::UcbCommandEnvironment::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Universal Content Broker.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( UniversalContentBroker::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = UniversalContentBroker::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // UCB Store.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( UcbStore::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = UcbStore::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // UCB PropertiesManager.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( UcbPropertiesManager::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = UcbPropertiesManager::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // UCP Proxy Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( UcbContentProviderProxyFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory
+ = UcbContentProviderProxyFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Command Environment.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( ucb_cmdenv::UcbCommandEnvironment::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory
+ = ucb_cmdenv::UcbCommandEnvironment::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/core/ucbstore.cxx b/ucb/source/core/ucbstore.cxx
new file mode 100644
index 000000000000..9500db4f45b6
--- /dev/null
+++ b/ucb/source/core/ucbstore.cxx
@@ -0,0 +1,2793 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <list>
+#include <hash_map>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include "ucbstore.hxx"
+
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+//=========================================================================
+rtl::OUString makeHierarchalNameSegment( const rtl::OUString & rIn )
+{
+ rtl::OUStringBuffer aBuffer;
+ aBuffer.appendAscii( "['" );
+
+ sal_Int32 nCount = rIn.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = rIn.getStr()[ n ];
+ switch ( c )
+ {
+ case '&':
+ aBuffer.appendAscii( "&amp;" );
+ break;
+
+ case '"':
+ aBuffer.appendAscii( "&quot;" );
+ break;
+
+ case '\'':
+ aBuffer.appendAscii( "&apos;" );
+ break;
+
+ case '<':
+ aBuffer.appendAscii( "&lt;" );
+ break;
+
+ case '>':
+ aBuffer.appendAscii( "&gt;" );
+ break;
+
+ default:
+ aBuffer.append( c );
+ break;
+ }
+ }
+
+ aBuffer.appendAscii( "']" );
+ return rtl::OUString( aBuffer.makeStringAndClear() );
+}
+
+//=========================================================================
+
+#define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
+
+// describe path of cfg entry
+#define CFGPROPERTY_NODEPATH "nodepath"
+// true->async. update; false->sync. update
+#define CFGPROPERTY_LAZYWRITE "lazywrite"
+
+//=========================================================================
+
+struct equalString_Impl
+{
+ bool operator()( const OUString& s1, const OUString& s2 ) const
+ {
+ return !!( s1 == s2 );
+ }
+};
+
+struct hashString_Impl
+{
+ size_t operator()( const OUString & rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+//=========================================================================
+//
+// PropertySetMap_Impl.
+//
+//=========================================================================
+
+typedef std::hash_map
+<
+ OUString,
+ PersistentPropertySet*,
+ hashString_Impl,
+ equalString_Impl
+>
+PropertySetMap_Impl;
+
+//=========================================================================
+//
+// class PropertySetInfo_Impl
+//
+//=========================================================================
+
+class PropertySetInfo_Impl :
+ public OWeakObject, public XTypeProvider, public XPropertySetInfo
+{
+ Reference< XMultiServiceFactory > m_xSMgr;
+ Sequence< Property >* m_pProps;
+ PersistentPropertySet* m_pOwner;
+
+public:
+ PropertySetInfo_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
+ PersistentPropertySet* pOwner );
+ virtual ~PropertySetInfo_Impl();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties()
+ throw( RuntimeException );
+ virtual Property SAL_CALL getPropertyByName( const OUString& aName )
+ throw( UnknownPropertyException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
+ throw( RuntimeException );
+
+ // Non-interface methods.
+ void reset() { delete m_pProps; m_pProps = 0; }
+};
+
+//=========================================================================
+//
+// UcbStore_Impl.
+//
+//=========================================================================
+
+struct UcbStore_Impl
+{
+ osl::Mutex m_aMutex;
+ Sequence< Any > m_aInitArgs;
+ Reference< XPropertySetRegistry > m_xTheRegistry;
+};
+
+//=========================================================================
+//=========================================================================
+//=========================================================================
+//
+// UcbStore Implementation.
+//
+//=========================================================================
+//=========================================================================
+//=========================================================================
+
+UcbStore::UcbStore( const Reference< XMultiServiceFactory >& rXSMgr )
+: m_xSMgr( rXSMgr ),
+ m_pImpl( new UcbStore_Impl() )
+{
+}
+
+//=========================================================================
+// virtual
+UcbStore::~UcbStore()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( UcbStore,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetRegistryFactory,
+ XInitialization );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( UcbStore,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetRegistryFactory,
+ XInitialization );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( UcbStore,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.UcbStore" ),
+ OUString::createFromAscii(
+ STORE_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore );
+
+//=========================================================================
+//
+// XPropertySetRegistryFactory methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XPropertySetRegistry > SAL_CALL
+UcbStore::createPropertySetRegistry( const OUString& )
+ throw( RuntimeException )
+{
+ // The URL parameter is ignored by this interface implementation. It always
+ // uses the configuration server as storage medium.
+
+ if ( !m_pImpl->m_xTheRegistry.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ if ( !m_pImpl->m_xTheRegistry.is() )
+ m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xSMgr, *this );
+ }
+ return m_pImpl->m_xTheRegistry;
+}
+
+//=========================================================================
+//
+// XInitialization methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments )
+ throw( Exception, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ m_pImpl->m_aInitArgs = aArguments;
+}
+
+//=========================================================================
+//
+// New methods.
+//
+//=========================================================================
+
+void UcbStore::removeRegistry()
+{
+ if ( m_pImpl->m_xTheRegistry.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ if ( m_pImpl->m_xTheRegistry.is() )
+ m_pImpl->m_xTheRegistry = 0;
+ }
+}
+
+//=========================================================================
+const Sequence< Any >& UcbStore::getInitArgs() const
+{
+ return m_pImpl->m_aInitArgs;
+}
+
+//=========================================================================
+//
+// PropertySetRegistry_Impl.
+//
+//=========================================================================
+
+struct PropertySetRegistry_Impl
+{
+ UcbStore* m_pCreator;
+ PropertySetMap_Impl m_aPropSets;
+ Reference< XMultiServiceFactory > m_xConfigProvider;
+ Reference< XInterface > m_xRootReadAccess;
+ Reference< XInterface > m_xRootWriteAccess;
+ osl::Mutex m_aMutex;
+ sal_Bool m_bTriedToGetRootReadAccess; // #82494#
+ sal_Bool m_bTriedToGetRootWriteAccess; // #82494#
+
+ PropertySetRegistry_Impl( UcbStore& rCreator )
+ : m_pCreator( &rCreator ),
+ m_bTriedToGetRootReadAccess( sal_False ),
+ m_bTriedToGetRootWriteAccess( sal_False )
+ {
+ m_pCreator->acquire();
+ }
+
+ ~PropertySetRegistry_Impl()
+ {
+ m_pCreator->removeRegistry();
+ m_pCreator->release();
+ }
+};
+
+//=========================================================================
+//=========================================================================
+//=========================================================================
+//
+// PropertySetRegistry Implementation.
+//
+//=========================================================================
+//=========================================================================
+//=========================================================================
+
+PropertySetRegistry::PropertySetRegistry(
+ const Reference< XMultiServiceFactory >& rXSMgr,
+ UcbStore& rCreator )
+: m_xSMgr( rXSMgr ),
+ m_pImpl( new PropertySetRegistry_Impl( rCreator ) )
+{
+}
+
+//=========================================================================
+// virtual
+PropertySetRegistry::~PropertySetRegistry()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_5( PropertySetRegistry,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetRegistry,
+ XElementAccess, /* base of XNameAccess */
+ XNameAccess );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( PropertySetRegistry,
+ XTypeProvider,
+ XServiceInfo,
+ XPropertySetRegistry,
+ XNameAccess );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.PropertySetRegistry" ),
+ OUString::createFromAscii(
+ PROPSET_REG_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// XPropertySetRegistry methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XPersistentPropertySet > SAL_CALL
+PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
+ throw( RuntimeException )
+{
+ if ( key.getLength() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
+
+ PropertySetMap_Impl::const_iterator it = rSets.find( key );
+ if ( it != rSets.end() )
+ {
+ // Already instanciated.
+ return Reference< XPersistentPropertySet >( (*it).second );
+ }
+ else
+ {
+ // Create new instance.
+ Reference< XNameAccess > xRootNameAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootNameAccess.is() )
+ {
+ // Propertyset in registry?
+ if ( xRootNameAccess->hasByName( key ) )
+ {
+ // Yep!
+ return Reference< XPersistentPropertySet >(
+ new PersistentPropertySet(
+ m_xSMgr, *this, key ) );
+ }
+ else if ( create )
+ {
+ // No. Create entry for propertyset.
+
+ Reference< XSingleServiceFactory > xFac(
+ getConfigWriteAccess( OUString() ), UNO_QUERY );
+ Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
+ Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
+
+ OSL_ENSURE( xFac.is(),
+ "PropertySetRegistry::openPropertySet - "
+ "No factory!" );
+
+ OSL_ENSURE( xBatch.is(),
+ "PropertySetRegistry::openPropertySet - "
+ "No batch!" );
+
+ OSL_ENSURE( xContainer.is(),
+ "PropertySetRegistry::openPropertySet - "
+ "No conteiner!" );
+
+ if ( xFac.is() && xBatch.is() && xContainer.is() )
+ {
+ try
+ {
+ // Create new "Properties" config item.
+ Reference< XNameReplace > xNameReplace(
+ xFac->createInstance(), UNO_QUERY );
+
+ if ( xNameReplace.is() )
+ {
+ // Fill new item...
+
+// // Set Values
+// xNameReplace->replaceByName(
+// OUString::createFromAscii( "Values" ),
+// makeAny( ... ) );
+
+ // Insert new item.
+ xContainer->insertByName(
+ key, makeAny( xNameReplace ) );
+ // Commit changes.
+ xBatch->commitChanges();
+
+ return Reference< XPersistentPropertySet >(
+ new PersistentPropertySet(
+ m_xSMgr, *this, key ) );
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - "
+ "caught IllegalArgumentException!" );
+ }
+ catch ( ElementExistException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - "
+ "caught ElementExistException!" );
+ }
+ catch ( WrappedTargetException& )
+ {
+ // insertByName, commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - "
+ "caught WrappedTargetException!" );
+ }
+ catch ( RuntimeException& )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - "
+ "caught RuntimeException!" );
+ }
+ catch ( Exception& )
+ {
+ // createInstance
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - "
+ "caught Exception!" );
+ }
+ }
+ }
+ else
+ {
+ // No entry. Fail, but no error.
+ return Reference< XPersistentPropertySet >();
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::openPropertySet - Error!" );
+ }
+ }
+
+ return Reference< XPersistentPropertySet >();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
+ throw( RuntimeException )
+{
+ if ( !key.getLength() )
+ return;
+
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XNameAccess > xRootNameAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootNameAccess.is() )
+ {
+ // Propertyset in registry?
+ if ( !xRootNameAccess->hasByName( key ) )
+ return;
+ Reference< XChangesBatch > xBatch(
+ getConfigWriteAccess( OUString() ), UNO_QUERY );
+ Reference< XNameContainer > xContainer( xBatch, UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "PropertySetRegistry::removePropertySet - "
+ "No batch!" );
+
+ OSL_ENSURE( xContainer.is(),
+ "PropertySetRegistry::removePropertySet - "
+ "No conteiner!" );
+
+ if ( xBatch.is() && xContainer.is() )
+ {
+ try
+ {
+ // Remove item.
+ xContainer->removeByName( key );
+ // Commit changes.
+ xBatch->commitChanges();
+
+ // Success.
+ return;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // removeByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::removePropertySet - "
+ "caught NoSuchElementException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::removePropertySet - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ }
+
+ return;
+ }
+
+ OSL_ENSURE( sal_False, "PropertySetRegistry::removePropertySet - Error!" );
+}
+
+//=========================================================================
+//
+// XElementAccess methods.
+//
+//=========================================================================
+
+// virtual
+com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType()
+ throw( RuntimeException )
+{
+ return getCppuType( ( Reference< XPersistentPropertySet > * ) 0 );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL PropertySetRegistry::hasElements()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XElementAccess > xElemAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xElemAccess.is() )
+ return xElemAccess->hasElements();
+
+ return sal_False;
+}
+
+//=========================================================================
+//
+// XNameAccess methods.
+//
+//=========================================================================
+
+// virtual
+Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName )
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XNameAccess > xNameAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+
+ try
+ {
+ return xNameAccess->getByName( aName );
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByName
+ }
+ catch ( WrappedTargetException& )
+ {
+ // getByName
+ }
+ }
+
+ return Any();
+}
+
+//=========================================================================
+// virtual
+Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XNameAccess > xNameAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ return xNameAccess->getElementNames();
+ }
+ return Sequence< OUString >( 0 );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XNameAccess > xNameAccess(
+ getRootConfigReadAccess(), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ return xNameAccess->hasByName( aName );
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+void PropertySetRegistry::add( PersistentPropertySet* pSet )
+{
+ OUString key( pSet->getKey() );
+
+ if ( key.getLength() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ m_pImpl->m_aPropSets[ key ] = pSet;
+ }
+}
+
+//=========================================================================
+void PropertySetRegistry::remove( PersistentPropertySet* pSet )
+{
+ OUString key( pSet->getKey() );
+
+ if ( key.getLength() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
+
+ PropertySetMap_Impl::iterator it = rSets.find( key );
+ if ( it != rSets.end() )
+ {
+ // Found.
+ rSets.erase( it );
+ }
+ }
+}
+
+//=========================================================================
+void PropertySetRegistry::renamePropertySet( const OUString& rOldKey,
+ const OUString& rNewKey )
+{
+ if ( rOldKey == rNewKey )
+ return;
+
+ Reference< XNameAccess > xRootNameAccess(
+ getConfigWriteAccess( OUString() ), UNO_QUERY );
+ if ( xRootNameAccess.is() )
+ {
+ // Old key present?
+ if ( xRootNameAccess->hasByName( rOldKey ) )
+ {
+ // New key not present?
+ if ( xRootNameAccess->hasByName( rNewKey ) )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "New key exists!" );
+ return;
+ }
+ Reference< XSingleServiceFactory > xFac(
+ xRootNameAccess, UNO_QUERY );
+ Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
+ Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
+
+ OSL_ENSURE( xFac.is(),
+ "PropertySetRegistry::renamePropertySet - "
+ "No factory!" );
+
+ OSL_ENSURE( xBatch.is(),
+ "PropertySetRegistry::renamePropertySet - "
+ "No batch!" );
+
+ OSL_ENSURE( xContainer.is(),
+ "PropertySetRegistry::renamePropertySet - "
+ "No container!" );
+
+ if ( xFac.is() && xBatch.is() && xContainer.is() )
+ {
+ //////////////////////////////////////////////////////
+ // Create new "Properties" config item.
+ //////////////////////////////////////////////////////
+
+ try
+ {
+ Reference< XNameReplace > xNameReplace(
+ xFac->createInstance(), UNO_QUERY );
+
+ if ( xNameReplace.is() )
+ {
+ // Insert new item.
+ xContainer->insertByName(
+ rNewKey, makeAny( xNameReplace ) );
+ // Commit changes.
+ xBatch->commitChanges();
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught IllegalArgumentException!" );
+ return;
+ }
+ catch ( ElementExistException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught ElementExistException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // insertByName, commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ catch ( RuntimeException& )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught RuntimeException!" );
+ return;
+ }
+ catch ( Exception& )
+ {
+ // createInstance
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught Exception!" );
+ return;
+ }
+
+ //////////////////////////////////////////////////////
+ // Copy data...
+ //////////////////////////////////////////////////////
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ xRootNameAccess, UNO_QUERY );
+ if ( !xRootHierNameAccess.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "No hierarchical name access!" );
+ return;
+ }
+
+ try
+ {
+ rtl::OUString aOldValuesKey
+ = makeHierarchalNameSegment( rOldKey );
+ aOldValuesKey += OUString::createFromAscii( "/Values" );
+
+ Reference< XNameAccess > xOldNameAccess;
+ xRootHierNameAccess->getByHierarchicalName(
+ aOldValuesKey )
+ >>= xOldNameAccess;
+ if ( !xOldNameAccess.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::renamePropertySet - "
+ "No old name access!" );
+ return;
+ }
+
+ // Obtain property names.
+ Sequence< OUString > aElems
+ = xOldNameAccess->getElementNames();
+ sal_Int32 nCount = aElems.getLength();
+ if ( nCount )
+ {
+ rtl::OUString aNewValuesKey
+ = makeHierarchalNameSegment( rNewKey );
+ aNewValuesKey += OUString::createFromAscii( "/Values" );
+
+ Reference< XSingleServiceFactory > xNewFac;
+ xRootHierNameAccess->getByHierarchicalName(
+ aNewValuesKey )
+ >>= xNewFac;
+ if ( !xNewFac.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::renamePropertySet - "
+ "No new factory!" );
+ return;
+ }
+
+ Reference< XNameContainer > xNewContainer(
+ xNewFac, UNO_QUERY );
+ if ( !xNewContainer.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::renamePropertySet - "
+ "No new container!" );
+ return;
+ }
+
+ aOldValuesKey += OUString::createFromAscii( "/" );
+
+ OUString aHandleKey
+ = OUString::createFromAscii( "/Handle" );
+ OUString aValueKey
+ = OUString::createFromAscii( "/Value" );
+ OUString aStateKey
+ = OUString::createFromAscii( "/State" );
+ OUString aAttrKey
+ = OUString::createFromAscii( "/Attributes" );
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const OUString& rPropName = aElems[ n ];
+
+ // Create new item.
+ Reference< XNameReplace > xNewPropNameReplace(
+ xNewFac->createInstance(), UNO_QUERY );
+
+ if ( !xNewPropNameReplace.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::renamePropertySet - "
+ "No new prop name replace!" );
+ return;
+ }
+
+ // Fill new item...
+
+ // Set Values
+ OUString aKey = aOldValuesKey;
+ aKey += makeHierarchalNameSegment( rPropName );
+
+ // ... handle
+ OUString aNewKey1 = aKey;
+ aNewKey1 += aHandleKey;
+ Any aAny =
+ xRootHierNameAccess->getByHierarchicalName(
+ aNewKey1 );
+ xNewPropNameReplace->replaceByName(
+ OUString::createFromAscii( "Handle" ),
+ aAny );
+
+ // ... value
+ aNewKey1 = aKey;
+ aNewKey1 += aValueKey;
+ aAny =
+ xRootHierNameAccess->getByHierarchicalName(
+ aNewKey1 );
+ xNewPropNameReplace->replaceByName(
+ OUString::createFromAscii( "Value" ),
+ aAny );
+
+ // ... state
+ aNewKey1 = aKey;
+ aNewKey1 += aStateKey;
+ aAny =
+ xRootHierNameAccess->getByHierarchicalName(
+ aNewKey1 );
+ xNewPropNameReplace->replaceByName(
+ OUString::createFromAscii( "State" ),
+ aAny );
+
+ // ... attributes
+ aNewKey1 = aKey;
+ aNewKey1 += aAttrKey;
+ aAny =
+ xRootHierNameAccess->getByHierarchicalName(
+ aNewKey1 );
+ xNewPropNameReplace->replaceByName(
+ OUString::createFromAscii( "Attributes" ),
+ aAny );
+
+ // Insert new item.
+ xNewContainer->insertByName(
+ rPropName, makeAny( xNewPropNameReplace ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+ }
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // insertByName, replaceByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught IllegalArgumentException!" );
+ return;
+ }
+ catch ( ElementExistException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught ElementExistException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // insertByName, replaceByName, commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName, replaceByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught NoSuchElementException!" );
+ return;
+ }
+ catch ( RuntimeException& )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught RuntimeException!" );
+ return;
+ }
+ catch ( Exception& )
+ {
+ // createInstance
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught Exception!" );
+ return;
+ }
+
+ //////////////////////////////////////////////////////
+ // Remove old entry...
+ //////////////////////////////////////////////////////
+
+ try
+ {
+ // Remove item.
+ xContainer->removeByName( rOldKey );
+ // Commit changes.
+ xBatch->commitChanges();
+
+ // Success.
+ return;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // removeByName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught NoSuchElementException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::renamePropertySet - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ }
+ }
+ }
+
+ OSL_ENSURE( sal_False, "PropertySetRegistry::renamePropertySet - Error!" );
+}
+
+//=========================================================================
+Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider()
+{
+ if ( !m_pImpl->m_xConfigProvider.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ if ( !m_pImpl->m_xConfigProvider.is() )
+ {
+ const Sequence< Any >& rInitArgs
+ = m_pImpl->m_pCreator->getInitArgs();
+
+ if ( rInitArgs.getLength() > 0 )
+ {
+ // Extract config provider from service init args.
+ rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider;
+
+ OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
+ "PropertySetRegistry::getConfigProvider - "
+ "No config provider!" );
+ }
+ else
+ {
+ try
+ {
+ m_pImpl->m_xConfigProvider
+ = Reference< XMultiServiceFactory >(
+ m_xSMgr->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.configuration."
+ "ConfigurationProvider" ) ),
+ UNO_QUERY );
+
+ OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
+ "PropertySetRegistry::getConfigProvider - "
+ "No config provider!" );
+
+ }
+ catch ( Exception& )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getConfigProvider - "
+ "caught exception!" );
+ }
+ }
+ }
+ }
+
+ return m_pImpl->m_xConfigProvider;
+}
+
+//=========================================================================
+Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess()
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( !m_pImpl->m_xRootReadAccess.is() )
+ {
+ if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getRootConfigReadAccess - "
+ "Unable to read any config data! -> #82494#" );
+ return Reference< XInterface >();
+ }
+
+ getConfigProvider();
+
+ if ( m_pImpl->m_xConfigProvider.is() )
+ {
+ Sequence< Any > aArguments( 1 );
+ PropertyValue aProperty;
+ aProperty.Name
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value
+ <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ STORE_CONTENTPROPERTIES_KEY ) );
+ aArguments[ 0 ] <<= aProperty;
+
+ m_pImpl->m_bTriedToGetRootReadAccess = sal_True;
+
+ m_pImpl->m_xRootReadAccess =
+ m_pImpl->m_xConfigProvider->createInstanceWithArguments(
+ OUString::createFromAscii(
+ "com.sun.star.configuration.ConfigurationAccess" ),
+ aArguments );
+
+ if ( m_pImpl->m_xRootReadAccess.is() )
+ return m_pImpl->m_xRootReadAccess;
+ }
+ }
+ else
+ return m_pImpl->m_xRootReadAccess;
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
+ return Reference< XInterface >();
+ }
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getRootConfigReadAccess - Error!" );
+ return Reference< XInterface >();
+}
+
+//=========================================================================
+Reference< XInterface > PropertySetRegistry::getConfigWriteAccess(
+ const OUString& rPath )
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( !m_pImpl->m_xRootWriteAccess.is() )
+ {
+ if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getConfigWriteAccess - "
+ "Unable to write any config data! -> #82494#" );
+ return Reference< XInterface >();
+ }
+
+ getConfigProvider();
+
+ if ( m_pImpl->m_xConfigProvider.is() )
+ {
+ Sequence< Any > aArguments( 2 );
+ PropertyValue aProperty;
+
+ aProperty.Name
+ = OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value
+ <<= OUString( RTL_CONSTASCII_USTRINGPARAM(
+ STORE_CONTENTPROPERTIES_KEY ) );
+ aArguments[ 0 ] <<= aProperty;
+
+ aProperty.Name
+ = OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_LAZYWRITE ) );
+ aProperty.Value <<= sal_True;
+ aArguments[ 1 ] <<= aProperty;
+
+ m_pImpl->m_bTriedToGetRootWriteAccess = sal_True;
+
+ m_pImpl->m_xRootWriteAccess =
+ m_pImpl->m_xConfigProvider->createInstanceWithArguments(
+ OUString::createFromAscii(
+ "com.sun.star.configuration.ConfigurationUpdateAccess" ),
+ aArguments );
+
+ OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(),
+ "PropertySetRegistry::getConfigWriteAccess - "
+ "No config update access!" );
+ }
+ }
+
+ if ( m_pImpl->m_xRootWriteAccess.is() )
+ {
+ if ( rPath.getLength() )
+ {
+ Reference< XHierarchicalNameAccess > xNA(
+ m_pImpl->m_xRootWriteAccess, UNO_QUERY );
+ if ( xNA.is() )
+ {
+ Reference< XInterface > xInterface;
+ xNA->getByHierarchicalName( rPath ) >>= xInterface;
+
+ if ( xInterface.is() )
+ return xInterface;
+ }
+ }
+ else
+ return m_pImpl->m_xRootWriteAccess;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getConfigWriteAccess - "
+ "caught NoSuchElementException!" );
+ return Reference< XInterface >();
+ }
+ catch ( Exception& )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getConfigWriteAccess - "
+ "caught Exception!" );
+ return Reference< XInterface >();
+ }
+
+ OSL_ENSURE( sal_False,
+ "PropertySetRegistry::getConfigWriteAccess - Error!" );
+ return Reference< XInterface >();
+}
+
+//=========================================================================
+//
+// PropertyListeners_Impl.
+//
+//=========================================================================
+
+typedef OMultiTypeInterfaceContainerHelperVar
+<
+ OUString,
+ hashString_Impl,
+ equalString_Impl
+> PropertyListeners_Impl;
+
+//=========================================================================
+//
+// PersistentPropertySet_Impl.
+//
+//=========================================================================
+
+struct PersistentPropertySet_Impl
+{
+ PropertySetRegistry* m_pCreator;
+ PropertySetInfo_Impl* m_pInfo;
+ OUString m_aKey;
+ OUString m_aFullKey;
+ osl::Mutex m_aMutex;
+ OInterfaceContainerHelper* m_pDisposeEventListeners;
+ OInterfaceContainerHelper* m_pPropSetChangeListeners;
+ PropertyListeners_Impl* m_pPropertyChangeListeners;
+
+ PersistentPropertySet_Impl( PropertySetRegistry& rCreator,
+ const OUString& rKey )
+ : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ),
+ m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ),
+ m_pPropertyChangeListeners( NULL )
+ {
+ m_pCreator->acquire();
+ }
+
+ ~PersistentPropertySet_Impl()
+ {
+ m_pCreator->release();
+
+ if ( m_pInfo )
+ m_pInfo->release();
+
+ delete m_pDisposeEventListeners;
+ delete m_pPropSetChangeListeners;
+ delete m_pPropertyChangeListeners;
+ }
+};
+
+//=========================================================================
+//=========================================================================
+//=========================================================================
+//
+// PersistentPropertySet Implementation.
+//
+//=========================================================================
+//=========================================================================
+//=========================================================================
+
+PersistentPropertySet::PersistentPropertySet(
+ const Reference< XMultiServiceFactory >& rXSMgr,
+ PropertySetRegistry& rCreator,
+ const OUString& rKey )
+: m_xSMgr( rXSMgr ),
+ m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) )
+{
+ // register at creator.
+ rCreator.add( this );
+}
+
+//=========================================================================
+// virtual
+PersistentPropertySet::~PersistentPropertySet()
+{
+ // deregister at creator.
+ m_pImpl->m_pCreator->remove( this );
+
+ delete m_pImpl;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_9( PersistentPropertySet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XPropertySet, /* base of XPersistentPropertySet */
+ XNamed,
+ XPersistentPropertySet,
+ XPropertyContainer,
+ XPropertySetInfoChangeNotifier,
+ XPropertyAccess );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_8( PersistentPropertySet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XPersistentPropertySet,
+ XNamed,
+ XPropertyContainer,
+ XPropertySetInfoChangeNotifier,
+ XPropertyAccess );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.PersistentPropertySet" ),
+ OUString::createFromAscii(
+ PERS_PROPSET_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL PersistentPropertySet::dispose()
+ throw( RuntimeException )
+{
+ if ( m_pImpl->m_pDisposeEventListeners &&
+ m_pImpl->m_pDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+ m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ if ( m_pImpl->m_pPropSetChangeListeners &&
+ m_pImpl->m_pPropSetChangeListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this );
+ m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
+ }
+
+ if ( m_pImpl->m_pPropertyChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ if ( !m_pImpl->m_pDisposeEventListeners )
+ m_pImpl->m_pDisposeEventListeners =
+ new OInterfaceContainerHelper( m_pImpl->m_aMutex );
+
+ m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ if ( m_pImpl->m_pDisposeEventListeners )
+ m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
+
+ // Note: Don't want to delete empty container here -> performance.
+}
+
+//=========================================================================
+//
+// XPropertySet methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XPropertySetInfo > SAL_CALL
+ PersistentPropertySet::getPropertySetInfo()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo;
+ if ( !rpInfo )
+ {
+ rpInfo = new PropertySetInfo_Impl( m_xSMgr, this );
+ rpInfo->acquire();
+ }
+ return Reference< XPropertySetInfo >( rpInfo );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::setPropertyValue(
+ const OUString& aPropertyName, const Any& aValue )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ if ( !aPropertyName.getLength() )
+ throw UnknownPropertyException();
+
+ osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ OUString aFullPropName( getFullKey() );
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( aPropertyName );
+
+ // Does property exist?
+ if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
+ {
+ Reference< XNameReplace > xNameReplace(
+ m_pImpl->m_pCreator->getConfigWriteAccess(
+ aFullPropName ), UNO_QUERY );
+ Reference< XChangesBatch > xBatch(
+ m_pImpl->m_pCreator->getConfigWriteAccess(
+ OUString() ), UNO_QUERY );
+
+ if ( xNameReplace.is() && xBatch.is() )
+ {
+ try
+ {
+ // Obtain old value
+ OUString aValueName = aFullPropName;
+ aValueName += OUString::createFromAscii( "/Value" );
+ Any aOldValue
+ = xRootHierNameAccess->getByHierarchicalName(
+ aValueName );
+ // Check value type.
+ if ( aOldValue.getValueType() != aValue.getValueType() )
+ {
+ aCGuard.clear();
+ throw IllegalArgumentException();
+ }
+
+ // Write value
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Value" ),
+ aValue );
+
+ // Write state ( Now it is a directly set value )
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "State" ),
+ makeAny(
+ sal_Int32(
+ PropertyState_DIRECT_VALUE ) ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+
+ PropertyChangeEvent aEvt;
+ if ( m_pImpl->m_pPropertyChangeListeners )
+ {
+ // Obtain handle
+ aValueName = aFullPropName;
+ aValueName += OUString::createFromAscii( "/Handle" );
+ sal_Int32 nHandle = -1;
+ xRootHierNameAccess->getByHierarchicalName( aValueName )
+ >>= nHandle;
+
+ aEvt.Source = (OWeakObject*)this;
+ aEvt.PropertyName = aPropertyName;
+ aEvt.PropertyHandle = nHandle;
+ aEvt.Further = sal_False;
+ aEvt.OldValue = aOldValue;
+ aEvt.NewValue = aValue;
+
+ // Callback follows!
+ aCGuard.clear();
+
+ notifyPropertyChangeEvent( aEvt );
+ }
+ return;
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // replaceByName
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName, replaceByName
+ }
+ catch ( WrappedTargetException& )
+ {
+ // replaceByName, commitChanges
+ }
+ }
+ }
+ }
+
+ throw UnknownPropertyException();
+}
+
+//=========================================================================
+// virtual
+Any SAL_CALL PersistentPropertySet::getPropertyValue(
+ const OUString& PropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ if ( !PropertyName.getLength() )
+ throw UnknownPropertyException();
+
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XHierarchicalNameAccess > xNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ OUString aFullPropName( getFullKey() );
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( PropertyName );
+ aFullPropName += OUString::createFromAscii( "/Value" );
+ try
+ {
+ return xNameAccess->getByHierarchicalName( aFullPropName );
+ }
+ catch ( NoSuchElementException& )
+ {
+ throw UnknownPropertyException();
+ }
+ }
+
+ throw UnknownPropertyException();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::addPropertyChangeListener(
+ const OUString& aPropertyName,
+ const Reference< XPropertyChangeListener >& xListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+// load();
+
+ if ( !m_pImpl->m_pPropertyChangeListeners )
+ m_pImpl->m_pPropertyChangeListeners =
+ new PropertyListeners_Impl( m_pImpl->m_aMutex );
+
+ m_pImpl->m_pPropertyChangeListeners->addInterface(
+ aPropertyName, xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::removePropertyChangeListener(
+ const OUString& aPropertyName,
+ const Reference< XPropertyChangeListener >& aListener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+// load();
+
+ if ( m_pImpl->m_pPropertyChangeListeners )
+ m_pImpl->m_pPropertyChangeListeners->removeInterface(
+ aPropertyName, aListener );
+
+ // Note: Don't want to delete empty container here -> performance.
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::addVetoableChangeListener(
+ const OUString&,
+ const Reference< XVetoableChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+// load();
+// OSL_ENSURE( sal_False,
+// "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::removeVetoableChangeListener(
+ const OUString&,
+ const Reference< XVetoableChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+// load();
+// OSL_ENSURE( sal_False,
+// "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
+}
+
+//=========================================================================
+//
+// XPersistentPropertySet methods.
+//
+//=========================================================================
+
+// virtual
+Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry()
+ throw( RuntimeException )
+{
+ return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator );
+}
+
+//=========================================================================
+// virtual
+OUString SAL_CALL PersistentPropertySet::getKey()
+ throw( RuntimeException )
+{
+ return m_pImpl->m_aKey;
+}
+
+//=========================================================================
+//
+// XNamed methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL PersistentPropertySet::getName()
+ throw( RuntimeException )
+{
+ // same as getKey()
+ return m_pImpl->m_aKey;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::setName( const OUString& aName )
+ throw( RuntimeException )
+{
+ if ( aName != m_pImpl->m_aKey )
+ m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName );
+}
+
+//=========================================================================
+//
+// XPropertyContainer methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL PersistentPropertySet::addProperty(
+ const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue )
+ throw( PropertyExistException,
+ IllegalTypeException,
+ IllegalArgumentException,
+ RuntimeException )
+{
+ if ( !Name.getLength() )
+ throw IllegalArgumentException();
+
+ // @@@ What other types can't be written to config server?
+
+ // Check type class ( Not all types can be written to storage )
+ TypeClass eTypeClass = DefaultValue.getValueTypeClass();
+ if ( eTypeClass == TypeClass_INTERFACE )
+ throw IllegalTypeException();
+
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ // Property already in set?
+
+ OUString aFullValuesName;
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ aFullValuesName = getFullKey();
+ OUString aFullPropName = aFullValuesName;
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( Name );
+
+ if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
+ {
+ // Already in set.
+ throw PropertyExistException();
+ }
+ }
+
+ // Property is always removeable.
+ Attributes |= PropertyAttribute::REMOVEABLE;
+
+ // Add property.
+
+ Reference< XSingleServiceFactory > xFac(
+ m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
+ UNO_QUERY );
+ Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
+ Reference< XChangesBatch > xBatch(
+ m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
+ UNO_QUERY );
+
+ OSL_ENSURE( xFac.is(),
+ "PersistentPropertySet::addProperty - No factory!" );
+
+ OSL_ENSURE( xBatch.is(),
+ "PersistentPropertySet::addProperty - No batch!" );
+
+ OSL_ENSURE( xContainer.is(),
+ "PersistentPropertySet::addProperty - No container!" );
+
+ if ( xFac.is() && xBatch.is() && xContainer.is() )
+ {
+ try
+ {
+ // Create new "PropertyValue" config item.
+ Reference< XNameReplace > xNameReplace(
+ xFac->createInstance(), UNO_QUERY );
+
+ if ( xNameReplace.is() )
+ {
+ // Fill new item...
+
+ // Set handle
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Handle" ),
+ makeAny( sal_Int32( -1 ) ) );
+
+ // Set default value
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Value" ),
+ DefaultValue );
+
+ // Set state ( always "default" )
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "State" ),
+ makeAny(
+ sal_Int32(
+ PropertyState_DEFAULT_VALUE ) ) );
+
+ // Set attributes
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Attributes" ),
+ makeAny( sal_Int32( Attributes ) ) );
+
+ // Insert new item.
+ xContainer->insertByName( Name, makeAny( xNameReplace ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+
+ // Property set info is invalid.
+ if ( m_pImpl->m_pInfo )
+ m_pImpl->m_pInfo->reset();
+
+ // Notify propertyset info change listeners.
+ if ( m_pImpl->m_pPropSetChangeListeners &&
+ m_pImpl->m_pPropSetChangeListeners->getLength() )
+ {
+ PropertySetInfoChangeEvent evt(
+ static_cast< OWeakObject * >( this ),
+ Name,
+ -1,
+ PropertySetInfoChange::PROPERTY_INSERTED );
+ notifyPropertySetInfoChange( evt );
+ }
+
+ // Success.
+ return;
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::addProperty - "
+ "caught IllegalArgumentException!" );
+ return;
+ }
+ catch ( ElementExistException& )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::addProperty - "
+ "caught ElementExistException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // replaceByName, insertByName, commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::addProperty - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ // createInstance
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::addProperty - "
+ "caught Exception!" );
+ return;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::addProperty - Error!" );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name )
+ throw( UnknownPropertyException,
+ NotRemoveableException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ OUString aFullValuesName;
+ OUString aFullPropName;
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ aFullValuesName = getFullKey();
+ aFullPropName = aFullValuesName;
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( Name );
+
+ // Property in set?
+ if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
+ throw UnknownPropertyException();
+
+ // Property removeable?
+ try
+ {
+ OUString aFullAttrName = aFullPropName;
+ aFullAttrName += OUString::createFromAscii( "/Attributes" );
+
+ sal_Int32 nAttribs = 0;
+ if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
+ >>= nAttribs )
+ {
+ if ( !( nAttribs & PropertyAttribute::REMOVEABLE ) )
+ {
+ // Not removeable!
+ throw NotRemoveableException();
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - "
+ "No attributes!" );
+ return;
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - "
+ "caught NoSuchElementException!" );
+ }
+
+ // Remove property...
+
+ Reference< XNameContainer > xContainer(
+ m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
+ UNO_QUERY );
+ Reference< XChangesBatch > xBatch(
+ m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
+ UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "PersistentPropertySet::removeProperty - No batch!" );
+
+ OSL_ENSURE( xContainer.is(),
+ "PersistentPropertySet::removeProperty - No container!" );
+
+ if ( xBatch.is() && xContainer.is() )
+ {
+ try
+ {
+ sal_Int32 nHandle = -1;
+
+ if ( m_pImpl->m_pPropSetChangeListeners &&
+ m_pImpl->m_pPropSetChangeListeners->getLength() )
+ {
+ // Obtain property handle ( needed for propertysetinfo
+ // change event )...
+
+ try
+ {
+ OUString aFullHandleName = aFullPropName;
+ aFullHandleName
+ += OUString::createFromAscii( "/Handle" );
+
+ if ( ! ( xRootHierNameAccess->getByHierarchicalName(
+ aFullHandleName ) >>= nHandle ) )
+ nHandle = -1;
+
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - "
+ "caught NoSuchElementException!" );
+ nHandle = -1;
+ }
+ }
+
+ xContainer->removeByName( Name );
+ xBatch->commitChanges();
+
+ // Property set info is invalid.
+ if ( m_pImpl->m_pInfo )
+ m_pImpl->m_pInfo->reset();
+
+ // Notify propertyset info change listeners.
+ if ( m_pImpl->m_pPropSetChangeListeners &&
+ m_pImpl->m_pPropSetChangeListeners->getLength() )
+ {
+ PropertySetInfoChangeEvent evt(
+ static_cast< OWeakObject * >( this ),
+ Name,
+ nHandle,
+ PropertySetInfoChange::PROPERTY_REMOVED );
+ notifyPropertySetInfoChange( evt );
+ }
+
+ // Success.
+ return;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // removeByName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - "
+ "caught NoSuchElementException!" );
+ return;
+ }
+ catch ( WrappedTargetException& )
+ {
+ // commitChanges
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - "
+ "caught WrappedTargetException!" );
+ return;
+ }
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::removeProperty - Error!" );
+}
+
+//=========================================================================
+//
+// XPropertySetInfoChangeNotifier methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener(
+ const Reference< XPropertySetInfoChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ if ( !m_pImpl->m_pPropSetChangeListeners )
+ m_pImpl->m_pPropSetChangeListeners =
+ new OInterfaceContainerHelper( m_pImpl->m_aMutex );
+
+ m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener(
+ const Reference< XPropertySetInfoChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ if ( m_pImpl->m_pPropSetChangeListeners )
+ m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
+}
+
+//=========================================================================
+//
+// XPropertyAccess methods.
+//
+//=========================================================================
+
+// virtual
+Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess;
+ xRootHierNameAccess->getByHierarchicalName(getFullKey())
+ >>= xNameAccess;
+ if ( xNameAccess.is() )
+ {
+ // Obtain property names.
+
+ Sequence< OUString > aElems = xNameAccess->getElementNames();
+
+ sal_Int32 nCount = aElems.getLength();
+ if ( nCount )
+ {
+ Reference< XHierarchicalNameAccess > xHierNameAccess(
+ xNameAccess, UNO_QUERY );
+
+ OSL_ENSURE( xHierNameAccess.is(),
+ "PersistentPropertySet::getPropertyValues - "
+ "No hierarchical name access!" );
+
+ if ( xHierNameAccess.is() )
+ {
+ Sequence< PropertyValue > aValues( nCount );
+
+ const OUString aHandleName
+ = OUString::createFromAscii( "/Handle" );
+ const OUString aValueName
+ = OUString::createFromAscii( "/Value" );
+ const OUString aStateName
+ = OUString::createFromAscii( "/State" );
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ PropertyValue& rValue = aValues[ n ];
+ OUString rName = aElems[ n ];
+ OUString aXMLName
+ = makeHierarchalNameSegment( rName );
+
+ // Set property name.
+
+ rValue.Name = rName;
+
+ try
+ {
+ // Obtain and set property handle
+ OUString aHierName = aXMLName;
+ aHierName += aHandleName;
+ Any aKeyValue
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ if ( !( aKeyValue >>= rValue.Handle ) )
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::getPropertyValues - "
+ "Error getting property handle!" );
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::getPropertyValues - "
+ "NoSuchElementException!" );
+ }
+
+ try
+ {
+ // Obtain and set property value
+ OUString aHierName = aXMLName;
+ aHierName += aValueName;
+ rValue.Value
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ // Note: The value may be void if addProperty
+ // was called with a default value
+ // of type void.
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::getPropertyValues - "
+ "NoSuchElementException!" );
+ }
+
+ try
+ {
+ // Obtain and set property state
+ OUString aHierName = aXMLName;
+ aHierName += aStateName;
+ Any aKeyValue
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ sal_Int32 nState = 0;
+ if ( !( aKeyValue >>= nState ) )
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::getPropertyValues - "
+ "Error getting property state!" );
+ else
+ rValue.State = PropertyState( nState );
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::getPropertyValues - "
+ "NoSuchElementException!" );
+ }
+ }
+
+ return aValues;
+ }
+ }
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+ }
+ }
+
+ return Sequence< PropertyValue >( 0 );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL PersistentPropertySet::setPropertyValues(
+ const Sequence< PropertyValue >& aProps )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ sal_Int32 nCount = aProps.getLength();
+ if ( !nCount )
+ return;
+
+ osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
+
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ const PropertyValue* pNewValues = aProps.getConstArray();
+
+ typedef std::list< PropertyChangeEvent > Events;
+ Events aEvents;
+
+ OUString aFullPropNamePrefix( getFullKey() );
+ aFullPropNamePrefix += OUString::createFromAscii( "/" );
+
+ // Iterate over given property value sequence.
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const PropertyValue& rNewValue = pNewValues[ n ];
+ const OUString& rName = rNewValue.Name;
+
+ OUString aFullPropName = aFullPropNamePrefix;
+ aFullPropName += makeHierarchalNameSegment( rName );
+
+ // Does property exist?
+ if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
+ {
+ Reference< XNameReplace > xNameReplace(
+ m_pImpl->m_pCreator->getConfigWriteAccess(
+ aFullPropName ), UNO_QUERY );
+ Reference< XChangesBatch > xBatch(
+ m_pImpl->m_pCreator->getConfigWriteAccess(
+ OUString() ), UNO_QUERY );
+
+ if ( xNameReplace.is() && xBatch.is() )
+ {
+ try
+ {
+ // Write handle
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Handle" ),
+ makeAny( rNewValue.Handle ) );
+
+ // Save old value
+ OUString aValueName = aFullPropName;
+ aValueName += OUString::createFromAscii( "/Value" );
+ Any aOldValue
+ = xRootHierNameAccess->getByHierarchicalName(
+ aValueName );
+ // Write value
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "Value" ),
+ rNewValue.Value );
+
+ // Write state ( Now it is a directly set value )
+ xNameReplace->replaceByName(
+ OUString::createFromAscii( "State" ),
+ makeAny(
+ sal_Int32(
+ PropertyState_DIRECT_VALUE ) ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+
+ if ( m_pImpl->m_pPropertyChangeListeners )
+ {
+ PropertyChangeEvent aEvt;
+ aEvt.Source = (OWeakObject*)this;
+ aEvt.PropertyName = rNewValue.Name;
+ aEvt.PropertyHandle = rNewValue.Handle;
+ aEvt.Further = sal_False;
+ aEvt.OldValue = aOldValue;
+ aEvt.NewValue = rNewValue.Value;
+
+ aEvents.push_back( aEvt );
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ // replaceByName
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName, replaceByName
+ }
+ catch ( WrappedTargetException& )
+ {
+ // replaceByName, commitChanges
+ }
+ }
+ }
+ }
+
+ // Callback follows!
+ aCGuard.clear();
+
+ if ( m_pImpl->m_pPropertyChangeListeners )
+ {
+ // Notify property changes.
+ Events::const_iterator it = aEvents.begin();
+ Events::const_iterator end = aEvents.end();
+
+ while ( it != end )
+ {
+ notifyPropertyChangeEvent( (*it) );
+ it++;
+ }
+ }
+
+ return;
+ }
+
+ OSL_ENSURE( sal_False,
+ "PersistentPropertySet::setPropertyValues - Nothing set!" );
+}
+
+//=========================================================================
+//
+// Non-interface methods
+//
+//=========================================================================
+
+void PersistentPropertySet::notifyPropertyChangeEvent(
+ const PropertyChangeEvent& rEvent ) const
+{
+ // Get "normal" listeners for the property.
+ OInterfaceContainerHelper* pContainer =
+ m_pImpl->m_pPropertyChangeListeners->getContainer(
+ rEvent.PropertyName );
+ if ( pContainer && pContainer->getLength() )
+ {
+ OInterfaceIteratorHelper aIter( *pContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ // Propagate event.
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvent );
+ }
+ }
+
+ // Get "normal" listeners for all properties.
+ OInterfaceContainerHelper* pNoNameContainer =
+ m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
+ if ( pNoNameContainer && pNoNameContainer->getLength() )
+ {
+ OInterfaceIteratorHelper aIter( *pNoNameContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ // Propagate event.
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvent );
+ }
+ }
+}
+
+//=========================================================================
+void PersistentPropertySet::notifyPropertySetInfoChange(
+ const PropertySetInfoChangeEvent& evt ) const
+{
+ if ( !m_pImpl->m_pPropSetChangeListeners )
+ return;
+
+ // Notify event listeners.
+ OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) );
+ while ( aIter.hasMoreElements() )
+ {
+ // Propagate event.
+ Reference< XPropertySetInfoChangeListener >
+ xListener( aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertySetInfoChange( evt );
+ }
+}
+
+//=========================================================================
+const OUString& PersistentPropertySet::getFullKey()
+{
+ if ( !m_pImpl->m_aFullKey.getLength() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ if ( !m_pImpl->m_aFullKey.getLength() )
+ {
+ m_pImpl->m_aFullKey
+ = makeHierarchalNameSegment( m_pImpl->m_aKey );
+ m_pImpl->m_aFullKey
+ += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Values" ) );
+ }
+ }
+
+ return m_pImpl->m_aFullKey;
+}
+
+//=========================================================================
+PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry()
+{
+ return *m_pImpl->m_pCreator;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// PropertySetInfo_Impl Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+PropertySetInfo_Impl::PropertySetInfo_Impl(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ PersistentPropertySet* pOwner )
+: m_xSMgr( rxSMgr ),
+ m_pProps( NULL ),
+ m_pOwner( pOwner )
+{
+}
+
+//=========================================================================
+// virtual
+PropertySetInfo_Impl::~PropertySetInfo_Impl()
+{
+ delete m_pProps;
+
+ // !!! Do not delete m_pOwner !!!
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_2( PropertySetInfo_Impl,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//=========================================================================
+//
+// XPropertySetInfo methods.
+//
+//=========================================================================
+
+// virtual
+Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties()
+ throw( RuntimeException )
+{
+ if ( !m_pProps )
+ {
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
+ UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess;
+ xRootHierNameAccess->getByHierarchicalName(
+ m_pOwner->getFullKey() )
+ >>= xNameAccess;
+ if ( xNameAccess.is() )
+ {
+ // Obtain property names.
+
+ Sequence< OUString > aElems
+ = xNameAccess->getElementNames();
+
+ sal_uInt32 nCount = aElems.getLength();
+ Sequence< Property >* pPropSeq
+ = new Sequence< Property >( nCount );
+
+ if ( nCount )
+ {
+ Reference< XHierarchicalNameAccess > xHierNameAccess(
+ xNameAccess, UNO_QUERY );
+
+ OSL_ENSURE( xHierNameAccess.is(),
+ "PropertySetInfo_Impl::getProperties - "
+ "No hierarchical name access!" );
+
+ if ( xHierNameAccess.is() )
+ {
+ const OUString aHandleName
+ = OUString::createFromAscii( "/Handle" );
+ const OUString aValueName
+ = OUString::createFromAscii( "/Value" );
+ const OUString aAttrName
+ = OUString::createFromAscii( "/Attributes" );
+
+ Property* pProps = pPropSeq->getArray();
+
+ for ( sal_uInt32 n = 0; n < nCount; ++n )
+ {
+ Property& rProp = pProps[ n ];
+ OUString rName = aElems[ n ];
+ OUString aXMLName
+ = makeHierarchalNameSegment( rName );
+
+ // Set property name.
+
+ rProp.Name = rName;
+
+ try
+ {
+ // Obtain and set property handle
+ rtl::OUString aHierName = aXMLName;
+ aHierName += aHandleName;
+ Any aKeyValue
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ if ( !( aKeyValue >>= rProp.Handle ) )
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getProperties - "
+ "Error getting property handle!" );
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getProperties - "
+ "NoSuchElementException!" );
+ }
+
+ try
+ {
+ // Obtain and set property type
+ rtl::OUString aHierName = aXMLName;
+ aHierName += aValueName;
+ Any aKeyValue
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ // Note: The type may be void if addProperty
+ // was called with a default value
+ // of type void.
+
+ rProp.Type = aKeyValue.getValueType();
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getProperties - "
+ "NoSuchElementException!" );
+ }
+
+ try
+ {
+ // Obtain and set property attributes
+ rtl::OUString aHierName = aXMLName;
+ aHierName += aAttrName;
+ Any aKeyValue
+ = xHierNameAccess->getByHierarchicalName(
+ aHierName );
+
+ sal_Int32 nAttribs = 0;
+ if ( aKeyValue >>= nAttribs )
+ rProp.Attributes
+ = sal_Int16( nAttribs );
+ else
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getProperties - "
+ "Error getting property attributes!" );
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getProperties - "
+ "NoSuchElementException!" );
+ }
+ }
+ }
+ }
+
+ // Success.
+ m_pProps = pPropSeq;
+ return *m_pProps;
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+ }
+ }
+
+ OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getProperties - Error!" );
+ m_pProps = new Sequence< Property >( 0 );
+ }
+
+ return *m_pProps;
+}
+
+//=========================================================================
+// virtual
+Property SAL_CALL PropertySetInfo_Impl::getPropertyByName(
+ const OUString& aName )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
+ UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ OUString aFullPropName( m_pOwner->getFullKey() );
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( aName );
+
+ // Does property exist?
+ if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
+ throw UnknownPropertyException();
+
+ try
+ {
+ Property aProp;
+
+ // Obtain handle.
+ OUString aKey = aFullPropName;
+ aKey += OUString::createFromAscii( "/Handle" );
+
+ if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
+ >>= aProp.Handle ) )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getPropertyByName - "
+ "No handle!" );
+ return Property();
+ }
+
+ // Obtain Value and extract type.
+ aKey = aFullPropName;
+ aKey += OUString::createFromAscii( "/Value" );
+
+ Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
+ if ( !aValue.hasValue() )
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getPropertyByName - "
+ "No Value!" );
+ return Property();
+ }
+
+ aProp.Type = aValue.getValueType();
+
+ // Obtain Attributes.
+ aKey = aFullPropName;
+ aKey += OUString::createFromAscii( "/Attributes" );
+
+ sal_Int32 nAttribs = 0;
+ if ( xRootHierNameAccess->getByHierarchicalName( aKey )
+ >>= nAttribs )
+ aProp.Attributes = sal_Int16( nAttribs );
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getPropertyByName - "
+ "No attributes!" );
+ return Property();
+ }
+
+ // set name.
+ aProp.Name = aName;
+
+ // Success.
+ return aProp;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "PropertySetInfo_Impl::getPropertyByName - "
+ "caught NoSuchElementException!" );
+ }
+
+ }
+
+ OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getPropertyByName - Error!" );
+ return Property();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName(
+ const OUString& Name )
+ throw( RuntimeException )
+{
+ Reference< XHierarchicalNameAccess > xRootHierNameAccess(
+ m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
+ UNO_QUERY );
+ if ( xRootHierNameAccess.is() )
+ {
+ OUString aFullPropName( m_pOwner->getFullKey() );
+ aFullPropName += OUString::createFromAscii( "/" );
+ aFullPropName += makeHierarchalNameSegment( Name );
+
+ return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
+ }
+
+ return sal_False;
+}
+
diff --git a/ucb/source/core/ucbstore.hxx b/ucb/source/core/ucbstore.hxx
new file mode 100644
index 000000000000..8c339337f890
--- /dev/null
+++ b/ucb/source/core/ucbstore.hxx
@@ -0,0 +1,347 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCBSTORE_HXX
+#define _UCBSTORE_HXX
+
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
+#include <com/sun/star/ucb/XPropertySetRegistry.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertySetInfoChangeNotifier.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+
+//=========================================================================
+
+#define STORE_SERVICE_NAME "com.sun.star.ucb.Store"
+#define PROPSET_REG_SERVICE_NAME "com.sun.star.ucb.PropertySetRegistry"
+#define PERS_PROPSET_SERVICE_NAME "com.sun.star.ucb.PersistentPropertySet"
+
+//=========================================================================
+
+struct UcbStore_Impl;
+
+class UcbStore :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XPropertySetRegistryFactory,
+ public com::sun::star::lang::XInitialization
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ UcbStore_Impl* m_pImpl;
+
+public:
+ UcbStore(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~UcbStore();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XPropertySetRegistryFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XPropertySetRegistry > SAL_CALL
+ createPropertySetRegistry( const rtl::OUString& URL )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Any >& aArguments )
+ throw( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ // New
+ void removeRegistry();
+
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >&
+ getInitArgs() const;
+};
+
+//=========================================================================
+
+struct PropertySetRegistry_Impl;
+class PersistentPropertySet;
+
+class PropertySetRegistry :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XPropertySetRegistry,
+ public com::sun::star::container::XNameAccess
+{
+ friend class PersistentPropertySet;
+
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ PropertySetRegistry_Impl* m_pImpl;
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ getConfigProvider();
+
+ void add ( PersistentPropertySet* pSet );
+ void remove( PersistentPropertySet* pSet );
+
+ void renamePropertySet( const rtl::OUString& rOldKey,
+ const rtl::OUString& rNewKey );
+
+public:
+ PropertySetRegistry(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr,
+ UcbStore& rCreator );
+ virtual ~PropertySetRegistry();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ // XPropertySetRegistry
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XPersistentPropertySet > SAL_CALL
+ openPropertySet( const rtl::OUString& key, sal_Bool create )
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removePropertySet( const rtl::OUString& key )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XElementAccess ( XNameAccess is derived from it )
+ virtual com::sun::star::uno::Type SAL_CALL
+ getElementType()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasElements()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XNameAccess
+ virtual com::sun::star::uno::Any SAL_CALL
+ getByName( const rtl::OUString& aName )
+ throw( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString& aName )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // Non-interface methods
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
+ getRootConfigReadAccess();
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
+ getConfigWriteAccess( const rtl::OUString& rPath );
+};
+
+//=========================================================================
+
+struct PersistentPropertySet_Impl;
+
+class PersistentPropertySet :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::ucb::XPersistentPropertySet,
+ public com::sun::star::container::XNamed,
+ public com::sun::star::beans::XPropertyContainer,
+ public com::sun::star::beans::XPropertySetInfoChangeNotifier,
+ public com::sun::star::beans::XPropertyAccess
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ PersistentPropertySet_Impl* m_pImpl;
+
+private:
+ void notifyPropertyChangeEvent(
+ const com::sun::star::beans::PropertyChangeEvent& rEvent ) const;
+ void notifyPropertySetInfoChange(
+ const com::sun::star::beans::PropertySetInfoChangeEvent& evt ) const;
+
+public:
+ PersistentPropertySet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr,
+ PropertySetRegistry& rCreator,
+ const rtl::OUString& rKey );
+ virtual ~PersistentPropertySet();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XPropertySet
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addPropertyChangeListener( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removePropertyChangeListener( const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addVetoableChangeListener( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeVetoableChangeListener( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ // XPersistentPropertySet
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XPropertySetRegistry > SAL_CALL
+ getRegistry()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual rtl::OUString SAL_CALL
+ getKey()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XNamed
+ virtual rtl::OUString SAL_CALL
+ getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ setName( const ::rtl::OUString& aName )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XPropertyContainer
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const com::sun::star::uno::Any& DefaultValue )
+ throw( com::sun::star::beans::PropertyExistException,
+ com::sun::star::beans::IllegalTypeException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeProperty( const rtl::OUString& Name )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::NotRemoveableException,
+ com::sun::star::uno::RuntimeException );
+
+ // XPropertySetInfoChangeNotifier
+ virtual void SAL_CALL
+ addPropertySetInfoChangeListener( const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removePropertySetInfoChangeListener( const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XPropertyAccess
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyValue > SAL_CALL
+ getPropertyValues()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ setPropertyValues( const com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyValue >& aProps )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ // Non-interface methods.
+ PropertySetRegistry& getPropertySetRegistry();
+ const rtl::OUString& getFullKey();
+};
+
+#endif /* !_UCBSTORE_HXX */
diff --git a/ucb/source/inc/regexp.hxx b/ucb/source/inc/regexp.hxx
new file mode 100644
index 000000000000..ddfed2994108
--- /dev/null
+++ b/ucb/source/inc/regexp.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCB_REGEXP_HXX_
+#define _UCB_REGEXP_HXX_
+
+#include <rtl/ustring.hxx>
+
+//============================================================================
+namespace ucb_impl {
+
+class Regexp
+{
+public:
+ enum Kind
+ {
+ KIND_PREFIX,
+ KIND_AUTHORITY,
+ KIND_DOMAIN
+ };
+
+ inline bool operator ==(Regexp const & rOther) const;
+
+ inline bool isDefault() const
+ { return m_eKind == KIND_PREFIX && m_aPrefix.getLength() == 0; }
+
+ inline Kind getKind() const { return m_eKind; }
+
+ bool matches(rtl::OUString const & rString, rtl::OUString * pTranslation,
+ bool * pTranslated) const;
+
+ rtl::OUString getRegexp(bool bReverse) const;
+
+ static Regexp parse(rtl::OUString const & rRegexp);
+
+private:
+ Kind m_eKind;
+ rtl::OUString m_aPrefix;
+ rtl::OUString m_aInfix;
+ rtl::OUString m_aReversePrefix;
+ bool m_bEmptyDomain;
+ bool m_bTranslation;
+
+ inline Regexp(Kind eTheKind, rtl::OUString const & rThePrefix,
+ bool bTheEmptyDomain, rtl::OUString const & rTheInfix,
+ bool bTheTranslation,
+ rtl::OUString const & rTheReversePrefix);
+};
+
+inline bool Regexp::operator ==(Regexp const & rOther) const
+{
+ return m_eKind == rOther.m_eKind
+ && m_aPrefix == rOther.m_aPrefix
+ && m_aInfix == rOther.m_aInfix;
+}
+
+}
+
+#endif // _UCB_REGEXP_HXX_
+
diff --git a/ucb/source/inc/regexpmap.hxx b/ucb/source/inc/regexpmap.hxx
new file mode 100644
index 000000000000..3bff4e619073
--- /dev/null
+++ b/ucb/source/inc/regexpmap.hxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCB_REGEXPMAP_HXX_
+#define _UCB_REGEXPMAP_HXX_
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace ucb_impl {
+
+template< typename Val > class RegexpMap;
+template< typename Val > class RegexpMapIter;
+
+//============================================================================
+template< typename Val >
+class RegexpMapEntry
+{
+public:
+ inline RegexpMapEntry(rtl::OUString const & rTheRegexp,
+ Val * pTheValue):
+ m_aRegexp(rTheRegexp), m_pValue(pTheValue) {}
+
+ rtl::OUString getRegexp() const { return m_aRegexp; }
+
+ Val const & getValue() const { return *m_pValue; }
+
+ Val & getValue() { return *m_pValue; }
+
+private:
+ rtl::OUString m_aRegexp;
+ Val * m_pValue;
+};
+
+//============================================================================
+template< typename Val > class RegexpMapIterImpl;
+ // MSC doesn't like this to be a private RegexpMapConstIter member
+ // class...
+
+template< typename Val >
+class RegexpMapConstIter
+{
+ friend class RegexpMap< Val >; // to access m_pImpl, ctor
+ friend class RegexpMapIter< Val >; // to access m_pImpl, ctor
+
+public:
+ RegexpMapConstIter();
+
+ RegexpMapConstIter(RegexpMapConstIter const & rOther);
+
+ ~RegexpMapConstIter();
+
+ RegexpMapConstIter & operator =(RegexpMapConstIter const & rOther);
+
+ RegexpMapConstIter & operator ++();
+
+ RegexpMapConstIter operator ++(int);
+
+ RegexpMapEntry< Val > const & operator *() const;
+
+ RegexpMapEntry< Val > const * operator ->() const;
+
+ bool equals(RegexpMapConstIter const & rOther) const;
+ // for free operator ==(), operator !=()
+
+private:
+ RegexpMapIterImpl< Val > * m_pImpl;
+
+ RegexpMapConstIter(RegexpMapIterImpl< Val > * pTheImpl);
+};
+
+//============================================================================
+template< typename Val >
+class RegexpMapIter: public RegexpMapConstIter< Val >
+{
+ friend class RegexpMap< Val >; // to access ctor
+
+public:
+ RegexpMapIter() {}
+
+ RegexpMapIter & operator ++();
+
+ RegexpMapIter operator ++(int);
+
+ RegexpMapEntry< Val > & operator *();
+
+ RegexpMapEntry< Val > const & operator *() const;
+
+ RegexpMapEntry< Val > * operator ->();
+
+ RegexpMapEntry< Val > const * operator ->() const;
+
+private:
+ RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl);
+};
+
+//============================================================================
+template< typename Val > struct RegexpMapImpl;
+ // MSC doesn't like this to be a RegexpMap member class...
+
+template< typename Val >
+class RegexpMap
+{
+public:
+ typedef sal_uInt32 size_type;
+ typedef RegexpMapIter< Val > iterator;
+ typedef RegexpMapConstIter< Val > const_iterator;
+
+ RegexpMap();
+
+ RegexpMap(RegexpMap const & rOther);
+
+ ~RegexpMap();
+
+ RegexpMap & operator =(RegexpMap const & rOther);
+
+ bool add(rtl::OUString const & rKey, Val const & rValue, bool bOverwrite,
+ rtl::OUString * pReverse = 0);
+ // throws com::sun::star::lang::IllegalArgumentException
+
+ iterator find(rtl::OUString const & rKey, rtl::OUString * pReverse = 0);
+ // throws com::sun::star::lang::IllegalArgumentException
+
+ void erase(iterator const & rPos);
+
+ iterator begin();
+
+ const_iterator begin() const;
+
+ iterator end();
+
+ const_iterator end() const;
+
+ bool empty() const;
+
+ size_type size() const;
+
+ Val const * map(rtl::OUString const & rString,
+ rtl::OUString * pTranslation = 0, bool * pTranslated = 0)
+ const;
+
+private:
+ RegexpMapImpl< Val > * m_pImpl;
+};
+
+}
+
+//============================================================================
+template< typename Val >
+inline bool operator ==(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
+ ucb_impl::RegexpMapConstIter< Val > const & rIter2)
+{
+ return rIter1.equals(rIter2);
+}
+
+template< typename Val >
+inline bool operator !=(ucb_impl::RegexpMapConstIter< Val > const & rIter1,
+ ucb_impl::RegexpMapConstIter< Val > const & rIter2)
+{
+ return !rIter1.equals(rIter2);
+}
+
+#endif // _UCB_REGEXPMAP_HXX_
+
diff --git a/ucb/source/inc/regexpmap.tpt b/ucb/source/inc/regexpmap.tpt
new file mode 100644
index 000000000000..9d4a7fb69c82
--- /dev/null
+++ b/ucb/source/inc/regexpmap.tpt
@@ -0,0 +1,564 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCB_REGEXPMAP_TPT_
+#define _UCB_REGEXPMAP_TPT_
+
+#ifndef _UCB_REGEXPMAP_HXX_
+#include <regexpmap.hxx>
+#endif
+
+#include <list>
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _UCB_REGEXP_HXX_
+#include "regexp.hxx"
+#endif
+
+using namespace ucb_impl;
+
+namespace ucb_impl {
+
+//============================================================================
+
+template< typename Val >
+struct Entry
+{
+ Regexp m_aRegexp;
+ Val m_aValue;
+
+ inline Entry(Regexp const & rTheRegexp, Val const & rTheValue):
+ m_aRegexp(rTheRegexp), m_aValue(rTheValue) {}
+};
+
+//============================================================================
+template< typename Val > class List: public std::list< Entry< Val > > {};
+
+//============================================================================
+//
+// RegexpMapIterImpl
+//
+//============================================================================
+
+template< typename Val >
+class RegexpMapIterImpl
+{
+public:
+ typedef RegexpMapImpl< Val > MapImpl;
+ typedef typename List< Val >::iterator ListIterator;
+
+ // Solaris needs these for the ctor...
+
+ inline RegexpMapIterImpl();
+
+ inline RegexpMapIterImpl(MapImpl * pTheMap, int nTheList,
+ ListIterator aTheIndex);
+
+ RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap, bool bBegin);
+
+ bool operator ==(RegexpMapIterImpl const & rOther) const;
+
+ RegexpMapImpl< Val > const * getMap() const { return m_pMap; }
+
+ int getList() const { return m_nList; }
+
+ typename List< Val >::iterator const & getIndex() const { return m_aIndex; }
+
+ void next();
+
+ RegexpMapEntry< Val > & get();
+
+private:
+ mutable RegexpMapEntry< Val > m_aEntry;
+ typename List< Val >::iterator m_aIndex;
+ RegexpMapImpl< Val > * m_pMap;
+ int m_nList;
+ mutable bool m_bEntrySet;
+
+ void setEntry() const;
+};
+
+}
+
+template< typename Val >
+inline RegexpMapIterImpl< Val >::RegexpMapIterImpl():
+ m_aEntry(rtl::OUString(), 0),
+ m_pMap(0),
+ m_nList(-1),
+ m_bEntrySet(false)
+{}
+
+template< typename Val >
+inline RegexpMapIterImpl< Val >::RegexpMapIterImpl(MapImpl * pTheMap,
+ int nTheList,
+ ListIterator aTheIndex):
+ m_aEntry(rtl::OUString(), 0),
+ m_aIndex(aTheIndex),
+ m_pMap(pTheMap),
+ m_nList(nTheList),
+ m_bEntrySet(false)
+{}
+
+//============================================================================
+template< typename Val >
+void RegexpMapIterImpl< Val >::setEntry() const
+{
+ if (!m_bEntrySet)
+ {
+ Entry< Val > const & rTheEntry
+ = m_nList == -1 ? *m_pMap->m_pDefault : *m_aIndex;
+ m_aEntry
+ = RegexpMapEntry< Val >(rTheEntry.m_aRegexp.getRegexp(false),
+ const_cast< Val * >(&rTheEntry.m_aValue));
+ m_bEntrySet = true;
+ }
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapIterImpl< Val >::RegexpMapIterImpl(RegexpMapImpl< Val > * pTheMap,
+ bool bBegin):
+ m_aEntry(rtl::OUString(), 0),
+ m_pMap(pTheMap),
+ m_bEntrySet(false)
+{
+ if (bBegin)
+ {
+ m_nList = -1;
+ m_aIndex = typename List< Val >::iterator();
+ if (!m_pMap->m_pDefault)
+ next();
+ }
+ else
+ {
+ m_nList = Regexp::KIND_DOMAIN;
+ m_aIndex = m_pMap->m_aList[Regexp::KIND_DOMAIN].end();
+ }
+}
+
+//============================================================================
+template< typename Val >
+bool RegexpMapIterImpl< Val >::operator ==(RegexpMapIterImpl const & rOther)
+ const
+{
+ return m_pMap == rOther.m_pMap
+ && m_nList == rOther.m_nList
+ && m_aIndex == rOther.m_aIndex;
+}
+
+//============================================================================
+template< typename Val >
+void RegexpMapIterImpl< Val >::next()
+{
+ switch (m_nList)
+ {
+ case Regexp::KIND_DOMAIN:
+ if (m_aIndex == m_pMap->m_aList[m_nList].end())
+ return;
+ default:
+ ++m_aIndex;
+ if (m_nList == Regexp::KIND_DOMAIN
+ || m_aIndex != m_pMap->m_aList[m_nList].end())
+ break;
+ case -1:
+ do
+ {
+ ++m_nList;
+ m_aIndex = m_pMap->m_aList[m_nList].begin();
+ }
+ while (m_nList < Regexp::KIND_DOMAIN
+ && m_aIndex == m_pMap->m_aList[m_nList].end());
+ break;
+ }
+ m_bEntrySet = false;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > & RegexpMapIterImpl< Val >::get()
+{
+ setEntry();
+ return m_aEntry;
+}
+
+//============================================================================
+//
+// RegexpMapConstIter
+//
+//============================================================================
+
+template< typename Val >
+RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapIterImpl< Val > *
+ pTheImpl):
+ m_pImpl(pTheImpl)
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val >::RegexpMapConstIter():
+ m_pImpl(new RegexpMapIterImpl< Val >)
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val >::RegexpMapConstIter(RegexpMapConstIter const &
+ rOther):
+ m_pImpl(new RegexpMapIterImpl< Val >(*rOther.m_pImpl))
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val >::~RegexpMapConstIter()
+{
+ delete m_pImpl;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val > &
+RegexpMapConstIter< Val >::operator =(RegexpMapConstIter const & rOther)
+{
+ *m_pImpl = *rOther.m_pImpl;
+ return *this;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val > & RegexpMapConstIter< Val >::operator ++()
+{
+ m_pImpl->next();
+ return *this;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapConstIter< Val > RegexpMapConstIter< Val >::operator ++(int)
+{
+ RegexpMapConstIter aTemp(*this);
+ m_pImpl->next();
+ return aTemp;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > const & RegexpMapConstIter< Val >::operator *() const
+{
+ return m_pImpl->get();
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > const * RegexpMapConstIter< Val >::operator ->() const
+{
+ return &m_pImpl->get();
+}
+
+//============================================================================
+template< typename Val >
+bool RegexpMapConstIter< Val >::equals(RegexpMapConstIter const & rOther)
+ const
+{
+ return *m_pImpl == *rOther.m_pImpl;
+}
+
+//============================================================================
+//
+// RegexpMapIter
+//
+//============================================================================
+
+template< typename Val >
+RegexpMapIter< Val >::RegexpMapIter(RegexpMapIterImpl< Val > * pTheImpl):
+ RegexpMapConstIter< Val >(pTheImpl)
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMapIter< Val > & RegexpMapIter< Val >::operator ++()
+{
+ this->m_pImpl->next();
+ return *this;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapIter< Val > RegexpMapIter< Val >::operator ++(int)
+{
+ RegexpMapIter aTemp(*this);
+ this->m_pImpl->next();
+ return aTemp;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > & RegexpMapIter< Val >::operator *()
+{
+ return this->m_pImpl->get();
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > const & RegexpMapIter< Val >::operator *() const
+{
+ return this->m_pImpl->get();
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > * RegexpMapIter< Val >::operator ->()
+{
+ return &this->m_pImpl->get();
+}
+
+//============================================================================
+template< typename Val >
+RegexpMapEntry< Val > const * RegexpMapIter< Val >::operator ->() const
+{
+ return &this->m_pImpl->get();
+}
+
+//============================================================================
+//
+// RegexpMap
+//
+//============================================================================
+
+namespace ucb_impl {
+
+template< typename Val >
+struct RegexpMapImpl
+{
+ List< Val > m_aList[Regexp::KIND_DOMAIN + 1];
+ Entry< Val > * m_pDefault;
+
+ RegexpMapImpl(): m_pDefault(0) {}
+
+ ~RegexpMapImpl() { delete m_pDefault; }
+};
+
+}
+
+//============================================================================
+template< typename Val >
+RegexpMap< Val >::RegexpMap():
+ m_pImpl(new RegexpMapImpl< Val >)
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMap< Val >::RegexpMap(RegexpMap const & rOther):
+ m_pImpl(new RegexpMapImpl< Val >(*rOther.m_pImpl))
+{}
+
+//============================================================================
+template< typename Val >
+RegexpMap< Val >::~RegexpMap()
+{
+ delete m_pImpl;
+}
+
+//============================================================================
+template< typename Val >
+RegexpMap< Val > & RegexpMap< Val >::operator =(RegexpMap const & rOther)
+{
+ *m_pImpl = *rOther.m_pImpl;
+ return *this;
+}
+
+//============================================================================
+template< typename Val >
+bool RegexpMap< Val >::add(rtl::OUString const & rKey, Val const & rValue,
+ bool bOverwrite, rtl::OUString * pReverse)
+{
+ Regexp aRegexp(Regexp::parse(rKey));
+
+ if (aRegexp.isDefault())
+ {
+ if (m_pImpl->m_pDefault)
+ {
+ if (!bOverwrite)
+ return false;
+ delete m_pImpl->m_pDefault;
+ }
+ m_pImpl->m_pDefault = new Entry< Val >(aRegexp, rValue);
+ }
+ else
+ {
+ List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
+
+ typename List< Val >::iterator aEnd(rTheList.end());
+ for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
+ {
+ if (aIt->m_aRegexp == aRegexp)
+ {
+ if (bOverwrite)
+ {
+ rTheList.erase(aIt);
+ break;
+ }
+ else
+ return false;
+ }
+ }
+
+ rTheList.push_back(Entry< Val >(aRegexp, rValue));
+ }
+
+ if (pReverse)
+ *pReverse = aRegexp.getRegexp(true);
+
+ return true;
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::iterator RegexpMap< Val >::find(rtl::OUString const & rKey,
+ rtl::OUString * pReverse)
+{
+ Regexp aRegexp(Regexp::parse(rKey));
+
+ if (pReverse)
+ *pReverse = aRegexp.getRegexp(true);
+
+ if (aRegexp.isDefault())
+ {
+ if (m_pImpl->m_pDefault)
+ return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
+ true));
+ }
+ else
+ {
+ List< Val > & rTheList = m_pImpl->m_aList[aRegexp.getKind()];
+
+ typename List< Val > ::iterator aEnd(rTheList.end());
+ for (typename List< Val >::iterator aIt(rTheList.begin()); aIt != aEnd; ++aIt)
+ if (aIt->m_aRegexp == aRegexp)
+ return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(
+ m_pImpl,
+ aRegexp.getKind(), aIt));
+ }
+
+ return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
+}
+
+//============================================================================
+template< typename Val >
+void RegexpMap< Val >::erase(iterator const & rPos)
+{
+ if (rPos.m_pImpl->getMap() == m_pImpl)
+ {
+ if (rPos.m_pImpl->getList() == -1)
+ {
+ if (m_pImpl->m_pDefault)
+ {
+ delete m_pImpl->m_pDefault;
+ m_pImpl->m_pDefault = 0;
+ }
+ }
+ else
+ m_pImpl->m_aList[rPos.m_pImpl->getList()].
+ erase(rPos.m_pImpl->getIndex());
+ }
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::iterator RegexpMap< Val >::begin()
+{
+ return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, true));
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::const_iterator RegexpMap< Val >::begin() const
+{
+ return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
+ true));
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::iterator RegexpMap< Val >::end()
+{
+ return RegexpMapIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl, false));
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::const_iterator RegexpMap< Val >::end() const
+{
+ return RegexpMapConstIter< Val >(new RegexpMapIterImpl< Val >(m_pImpl,
+ false));
+}
+
+//============================================================================
+template< typename Val >
+bool RegexpMap< Val >::empty() const
+{
+ return !m_pImpl->m_pDefault
+ && m_pImpl->m_aList[Regexp::KIND_PREFIX].empty()
+ && m_pImpl->m_aList[Regexp::KIND_AUTHORITY].empty()
+ && m_pImpl->m_aList[Regexp::KIND_DOMAIN].empty();
+}
+
+//============================================================================
+template< typename Val >
+typename RegexpMap< Val >::size_type RegexpMap< Val >::size() const
+{
+ return (m_pImpl->m_pDefault ? 1 : 0)
+ + m_pImpl->m_aList[Regexp::KIND_PREFIX].size()
+ + m_pImpl->m_aList[Regexp::KIND_AUTHORITY].size()
+ + m_pImpl->m_aList[Regexp::KIND_DOMAIN].size();
+}
+
+//============================================================================
+template< typename Val >
+Val const * RegexpMap< Val >::map(rtl::OUString const & rString,
+ rtl::OUString * pTranslation,
+ bool * pTranslated) const
+{
+ for (int n = Regexp::KIND_DOMAIN; n >= Regexp::KIND_PREFIX; --n)
+ {
+ List< Val > const & rTheList = m_pImpl->m_aList[n];
+
+ typename List< Val >::const_iterator aEnd(rTheList.end());
+ for (typename List< Val >::const_iterator aIt(rTheList.begin()); aIt != aEnd;
+ ++aIt)
+ if (aIt->m_aRegexp.matches(rString, pTranslation, pTranslated))
+ return &aIt->m_aValue;
+ }
+ if (m_pImpl->m_pDefault
+ && m_pImpl->m_pDefault->m_aRegexp.matches(rString, pTranslation,
+ pTranslated))
+ return &m_pImpl->m_pDefault->m_aValue;
+ return 0;
+}
+
+#endif // _UCB_REGEXPMAP_TPT_
diff --git a/ucb/source/regexp/makefile.mk b/ucb/source/regexp/makefile.mk
new file mode 100644
index 000000000000..e748f054ea13
--- /dev/null
+++ b/ucb/source/regexp/makefile.mk
@@ -0,0 +1,41 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=ucb
+TARGET=regexp
+AUTOSEG=true
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/regexp.obj
+.ENDIF # L10N_framework
+
+.INCLUDE : target.mk
diff --git a/ucb/source/regexp/regexp.cxx b/ucb/source/regexp/regexp.cxx
new file mode 100644
index 000000000000..f784532d31b3
--- /dev/null
+++ b/ucb/source/regexp/regexp.cxx
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <regexp.hxx>
+
+#include <cstddef>
+
+#include "osl/diagnose.h"
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+namespace unnamed_ucb_regexp {} using namespace unnamed_ucb_regexp;
+ // unnamed namespaces don't work well yet...
+
+using namespace com::sun::star;
+using namespace ucb_impl;
+
+//============================================================================
+//
+// Regexp
+//
+//============================================================================
+
+inline Regexp::Regexp(Kind eTheKind, rtl::OUString const & rThePrefix,
+ bool bTheEmptyDomain, rtl::OUString const & rTheInfix,
+ bool bTheTranslation,
+ rtl::OUString const & rTheReversePrefix):
+ m_eKind(eTheKind),
+ m_aPrefix(rThePrefix),
+ m_aInfix(rTheInfix),
+ m_aReversePrefix(rTheReversePrefix),
+ m_bEmptyDomain(bTheEmptyDomain),
+ m_bTranslation(bTheTranslation)
+{
+ OSL_ASSERT(m_eKind == KIND_DOMAIN
+ || !m_bEmptyDomain && m_aInfix.getLength() == 0);
+ OSL_ASSERT(m_bTranslation || m_aReversePrefix.getLength() == 0);
+}
+
+//============================================================================
+namespace unnamed_ucb_regexp {
+
+bool matchStringIgnoreCase(sal_Unicode const ** pBegin,
+ sal_Unicode const * pEnd,
+ rtl::OUString const & rString)
+{
+ sal_Unicode const * p = *pBegin;
+
+ sal_Unicode const * q = rString.getStr();
+ sal_Unicode const * qEnd = q + rString.getLength();
+
+ if (pEnd - p < qEnd - q)
+ return false;
+
+ while (q != qEnd)
+ {
+ sal_Unicode c1 = *p++;
+ sal_Unicode c2 = *q++;
+ if (c1 >= 'a' && c1 <= 'z')
+ c1 -= 'a' - 'A';
+ if (c2 >= 'a' && c2 <= 'z')
+ c2 -= 'a' - 'A';
+ if (c1 != c2)
+ return false;
+ }
+
+ *pBegin = p;
+ return true;
+}
+
+}
+
+bool Regexp::matches(rtl::OUString const & rString,
+ rtl::OUString * pTranslation, bool * pTranslated) const
+{
+ sal_Unicode const * pBegin = rString.getStr();
+ sal_Unicode const * pEnd = pBegin + rString.getLength();
+
+ bool bMatches = false;
+
+ sal_Unicode const * p = pBegin;
+ if (matchStringIgnoreCase(&p, pEnd, m_aPrefix))
+ {
+ sal_Unicode const * pBlock1Begin = p;
+ sal_Unicode const * pBlock1End = pEnd;
+
+ sal_Unicode const * pBlock2Begin = 0;
+ sal_Unicode const * pBlock2End = 0;
+
+ switch (m_eKind)
+ {
+ case KIND_PREFIX:
+ bMatches = true;
+ break;
+
+ case KIND_AUTHORITY:
+ bMatches = p == pEnd || *p == '/' || *p == '?' || *p == '#';
+ break;
+
+ case KIND_DOMAIN:
+ if (!m_bEmptyDomain)
+ {
+ if (p == pEnd || *p == '/' || *p == '?' || *p == '#')
+ break;
+ ++p;
+ }
+ for (;;)
+ {
+ sal_Unicode const * q = p;
+ if (matchStringIgnoreCase(&q, pEnd, m_aInfix)
+ && (q == pEnd || *q == '/' || *q == '?' || *q == '#'))
+ {
+ bMatches = true;
+ pBlock1End = p;
+ pBlock2Begin = q;
+ pBlock2End = pEnd;
+ break;
+ }
+
+ if (p == pEnd)
+ break;
+
+ sal_Unicode c = *p++;
+ if (c == '/' || c == '?' || c == '#')
+ break;
+ }
+ break;
+ }
+
+ if (bMatches)
+ {
+ if (m_bTranslation)
+ {
+ if (pTranslation)
+ {
+ rtl::OUStringBuffer aBuffer(m_aReversePrefix);
+ aBuffer.append(pBlock1Begin, pBlock1End - pBlock1Begin);
+ aBuffer.append(m_aInfix);
+ aBuffer.append(pBlock2Begin, pBlock2End - pBlock2Begin);
+ *pTranslation = aBuffer.makeStringAndClear();
+ }
+ if (pTranslated)
+ *pTranslated = true;
+ }
+ else
+ {
+ if (pTranslation)
+ *pTranslation = rString;
+ if (pTranslated)
+ *pTranslated = false;
+ }
+ }
+ }
+
+ return bMatches;
+}
+
+//============================================================================
+namespace unnamed_ucb_regexp {
+
+inline bool isAlpha(sal_Unicode c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
+}
+
+inline bool isDigit(sal_Unicode c)
+{
+ return c >= '0' && c <= '9';
+}
+
+bool isScheme(rtl::OUString const & rString, bool bColon)
+{
+ // Return true if rString matches <scheme> (plus a trailing ":" if bColon
+ // is true) from RFC 2396:
+ sal_Unicode const * p = rString.getStr();
+ sal_Unicode const * pEnd = p + rString.getLength();
+ if (p != pEnd && isAlpha(*p))
+ for (++p;;)
+ {
+ if (p == pEnd)
+ return !bColon;
+ sal_Unicode c = *p++;
+ if (!(isAlpha(c) || isDigit(c)
+ || c == '+' || c == '-' || c == '.'))
+ return bColon && c == ':' && p == pEnd;
+ }
+ return false;
+}
+
+void appendStringLiteral(rtl::OUStringBuffer * pBuffer,
+ rtl::OUString const & rString)
+{
+ OSL_ASSERT(pBuffer);
+
+ pBuffer->append(sal_Unicode('"'));
+ sal_Unicode const * p = rString.getStr();
+ sal_Unicode const * pEnd = p + rString.getLength();
+ while (p != pEnd)
+ {
+ sal_Unicode c = *p++;
+ if (c == '"' || c == '\\')
+ pBuffer->append(sal_Unicode('\\'));
+ pBuffer->append(c);
+ }
+ pBuffer->append(sal_Unicode('"'));
+}
+
+}
+
+rtl::OUString Regexp::getRegexp(bool bReverse) const
+{
+ if (m_bTranslation)
+ {
+ rtl::OUStringBuffer aBuffer;
+ if (bReverse)
+ {
+ if (m_aReversePrefix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aReversePrefix);
+ }
+ else
+ {
+ if (m_aPrefix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aPrefix);
+ }
+ switch (m_eKind)
+ {
+ case KIND_PREFIX:
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("(.*)"));
+ break;
+
+ case KIND_AUTHORITY:
+ aBuffer.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("(([/?#].*)?)"));
+ break;
+
+ case KIND_DOMAIN:
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("([^/?#]"));
+ aBuffer.append(sal_Unicode(m_bEmptyDomain ? '*' : '+'));
+ if (m_aInfix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aInfix);
+ aBuffer.
+ appendAscii(RTL_CONSTASCII_STRINGPARAM("([/?#].*)?)"));
+ break;
+ }
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("->"));
+ if (bReverse)
+ {
+ if (m_aPrefix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aPrefix);
+ }
+ else
+ {
+ if (m_aReversePrefix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aReversePrefix);
+ }
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\\1"));
+ return aBuffer.makeStringAndClear();
+ }
+ else if (m_eKind == KIND_PREFIX && isScheme(m_aPrefix, true))
+ return m_aPrefix.copy(0, m_aPrefix.getLength() - 1);
+ else
+ {
+ rtl::OUStringBuffer aBuffer;
+ if (m_aPrefix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aPrefix);
+ switch (m_eKind)
+ {
+ case KIND_PREFIX:
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM(".*"));
+ break;
+
+ case KIND_AUTHORITY:
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("([/?#].*)?"));
+ break;
+
+ case KIND_DOMAIN:
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("[^/?#]"));
+ aBuffer.append(sal_Unicode(m_bEmptyDomain ? '*' : '+'));
+ if (m_aInfix.getLength() != 0)
+ appendStringLiteral(&aBuffer, m_aInfix);
+ aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("([/?#].*)?"));
+ break;
+ }
+ return aBuffer.makeStringAndClear();
+ }
+}
+
+//============================================================================
+namespace unnamed_ucb_regexp {
+
+bool matchString(sal_Unicode const ** pBegin, sal_Unicode const * pEnd,
+ sal_Char const * pString, size_t nStringLength)
+{
+ sal_Unicode const * p = *pBegin;
+
+ sal_uChar const * q = reinterpret_cast< sal_uChar const * >(pString);
+ sal_uChar const * qEnd = q + nStringLength;
+
+ if (pEnd - p < qEnd - q)
+ return false;
+
+ while (q != qEnd)
+ {
+ sal_Unicode c1 = *p++;
+ sal_Unicode c2 = *q++;
+ if (c1 != c2)
+ return false;
+ }
+
+ *pBegin = p;
+ return true;
+}
+
+bool scanStringLiteral(sal_Unicode const ** pBegin, sal_Unicode const * pEnd,
+ rtl::OUString * pString)
+{
+ sal_Unicode const * p = *pBegin;
+
+ if (p == pEnd || *p++ != '"')
+ return false;
+
+ rtl::OUStringBuffer aBuffer;
+ for (;;)
+ {
+ if (p == pEnd)
+ return false;
+ sal_Unicode c = *p++;
+ if (c == '"')
+ break;
+ if (c == '\\')
+ {
+ if (p == pEnd)
+ return false;
+ c = *p++;
+ if (c != '"' && c != '\\')
+ return false;
+ }
+ aBuffer.append(c);
+ }
+
+ *pBegin = p;
+ *pString = aBuffer.makeStringAndClear();
+ return true;
+}
+
+}
+
+Regexp Regexp::parse(rtl::OUString const & rRegexp)
+{
+ // Detect an input of '<scheme>' as an abbreviation of '"<scheme>:".*'
+ // where <scheme> is as defined in RFC 2396:
+ if (isScheme(rRegexp, false))
+ return Regexp(Regexp::KIND_PREFIX,
+ rRegexp
+ + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":")),
+ false,
+ rtl::OUString(),
+ false,
+ rtl::OUString());
+
+ sal_Unicode const * p = rRegexp.getStr();
+ sal_Unicode const * pEnd = p + rRegexp.getLength();
+
+ rtl::OUString aPrefix;
+ scanStringLiteral(&p, pEnd, &aPrefix);
+
+ if (p == pEnd)
+ throw lang::IllegalArgumentException();
+
+ if (matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM(".*")))
+ {
+ if (p != pEnd)
+ throw lang::IllegalArgumentException();
+
+ return Regexp(Regexp::KIND_PREFIX, aPrefix, false, rtl::OUString(),
+ false, rtl::OUString());
+ }
+ else if (matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("(.*)->")))
+ {
+ rtl::OUString aReversePrefix;
+ scanStringLiteral(&p, pEnd, &aReversePrefix);
+
+ if (!matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("\\1"))
+ || p != pEnd)
+ throw lang::IllegalArgumentException();
+
+ return Regexp(Regexp::KIND_PREFIX, aPrefix, false, rtl::OUString(),
+ true, aReversePrefix);
+ }
+ else if (matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("([/?#].*)?")))
+ {
+ if (p != pEnd)
+ throw lang::IllegalArgumentException();
+
+ return Regexp(Regexp::KIND_AUTHORITY, aPrefix, false, rtl::OUString(),
+ false, rtl::OUString());
+ }
+ else if (matchString(&p, pEnd,
+ RTL_CONSTASCII_STRINGPARAM("(([/?#].*)?)->")))
+ {
+ rtl::OUString aReversePrefix;
+ if (!(scanStringLiteral(&p, pEnd, &aReversePrefix)
+ && matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("\\1"))
+ && p == pEnd))
+ throw lang::IllegalArgumentException();
+
+ return Regexp(Regexp::KIND_AUTHORITY, aPrefix, false, rtl::OUString(),
+ true, aReversePrefix);
+ }
+ else
+ {
+ bool bOpen = false;
+ if (p != pEnd && *p == '(')
+ {
+ ++p;
+ bOpen = true;
+ }
+
+ if (!matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("[^/?#]")))
+ throw lang::IllegalArgumentException();
+
+ if (p == pEnd || (*p != '*' && *p != '+'))
+ throw lang::IllegalArgumentException();
+ bool bEmptyDomain = *p++ == '*';
+
+ rtl::OUString aInfix;
+ scanStringLiteral(&p, pEnd, &aInfix);
+
+ if (!matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("([/?#].*)?")))
+ throw lang::IllegalArgumentException();
+
+ rtl::OUString aReversePrefix;
+ if (bOpen
+ && !(matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM(")->"))
+ && scanStringLiteral(&p, pEnd, &aReversePrefix)
+ && matchString(&p, pEnd, RTL_CONSTASCII_STRINGPARAM("\\1"))))
+ throw lang::IllegalArgumentException();
+
+ if (p != pEnd)
+ throw lang::IllegalArgumentException();
+
+ return Regexp(Regexp::KIND_DOMAIN, aPrefix, bEmptyDomain, aInfix,
+ bOpen, aReversePrefix);
+ }
+}
+
diff --git a/ucb/source/sorter/makefile.mk b/ucb/source/sorter/makefile.mk
new file mode 100644
index 000000000000..68a9959589d2
--- /dev/null
+++ b/ucb/source/sorter/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=ucb
+TARGET=srtrs
+ENABLE_EXCEPTIONS=TRUE
+
+# Version
+UCB_MAJOR=1
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/sortdynres.obj \
+ $(SLO)$/sortresult.obj \
+ $(SLO)$/sortmain.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(UCB_MAJOR)
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+DEF1NAME=$(SHL1TARGET)
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/sorter/sortdynres.cxx b/ucb/source/sorter/sortdynres.cxx
new file mode 100644
index 000000000000..2fc38ee46a42
--- /dev/null
+++ b/ucb/source/sorter/sortdynres.cxx
@@ -0,0 +1,628 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <vector>
+#include <sortdynres.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/ucb/ContentResultSetCapability.hpp>
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
+#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
+#include <com/sun/star/ucb/XSourceInitialization.hpp>
+
+//-----------------------------------------------------------------------------
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace rtl;
+
+//=========================================================================
+
+// The mutex to synchronize access to containers.
+static osl::Mutex& getContainerMutex()
+{
+ static osl::Mutex* pMutex = NULL;
+ if( !pMutex )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pMutex )
+ {
+ static osl::Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+
+ return *pMutex;
+}
+
+//=========================================================================
+//
+// SortedDynamicResultSet
+//
+//=========================================================================
+
+SortedDynamicResultSet::SortedDynamicResultSet(
+ const Reference < XDynamicResultSet > &xOriginal,
+ const Sequence < NumberedSortingInfo > &aOptions,
+ const Reference < XAnyCompareFactory > &xCompFac,
+ const Reference < XMultiServiceFactory > &xSMgr )
+{
+ mpDisposeEventListeners = NULL;
+ mpOwnListener = new SortedDynamicResultSetListener( this );
+
+ mxOwnListener = Reference< XDynamicResultSetListener >( mpOwnListener );
+
+ mxOriginal = xOriginal;
+ maOptions = aOptions;
+ mxCompFac = xCompFac;
+ mxSMgr = xSMgr;
+
+ mpOne = NULL;
+ mpTwo = NULL;
+
+ mbGotWelcome = sal_False;
+ mbUseOne = sal_True;
+ mbStatic = sal_False;
+}
+
+//--------------------------------------------------------------------------
+SortedDynamicResultSet::~SortedDynamicResultSet()
+{
+ mpOwnListener->impl_OwnerDies();
+ mxOwnListener.clear();
+
+ delete mpDisposeEventListeners;
+
+ mxOne.clear();
+ mxTwo.clear();
+ mxOriginal.clear();
+
+ mpOne = NULL;
+ mpTwo = NULL;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_4( SortedDynamicResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent, /* base class of XDynamicResultSet */
+ XDynamicResultSet );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( SortedDynamicResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XDynamicResultSet );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( SortedDynamicResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedDynamicResultSet" ),
+ OUString::createFromAscii(
+ DYNAMIC_RESULTSET_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::dispose()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+ mpDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ mxOne.clear();
+ mxTwo.clear();
+ mxOriginal.clear();
+
+ mpOne = NULL;
+ mpTwo = NULL;
+ mbUseOne = sal_True;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpDisposeEventListeners )
+ mpDisposeEventListeners =
+ new OInterfaceContainerHelper( getContainerMutex() );
+
+ mpDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners )
+ mpDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// XDynamicResultSet methods.
+// ------------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL
+SortedDynamicResultSet::getStaticResultSet()
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ mbStatic = sal_True;
+
+ if ( mxOriginal.is() )
+ {
+ mpOne = new SortedResultSet( mxOriginal->getStaticResultSet() );
+ mxOne = mpOne;
+ mpOne->Initialize( maOptions, mxCompFac );
+ }
+
+ return mxOne;
+}
+
+// ------------------------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::setListener( const Reference< XDynamicResultSetListener >& Listener )
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ addEventListener( Reference< XEventListener >::query( Listener ) );
+
+ mxListener = Listener;
+
+ if ( mxOriginal.is() )
+ mxOriginal->setListener( mxOwnListener );
+}
+
+// ------------------------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::connectToCache(
+ const Reference< XDynamicResultSet > & xCache )
+ throw( ListenerAlreadySetException,
+ AlreadyInitializedException,
+ ServiceNotFoundException,
+ RuntimeException )
+{
+ if( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ if( mbStatic )
+ throw ListenerAlreadySetException();
+
+ Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
+ if( xTarget.is() && mxSMgr.is() )
+ {
+ Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
+ try
+ {
+ xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
+ mxSMgr->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
+ UNO_QUERY );
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ if( xStubFactory.is() )
+ {
+ xStubFactory->connectToCache(
+ this, xCache, Sequence< NumberedSortingInfo > (), NULL );
+ return;
+ }
+ }
+ throw ServiceNotFoundException();
+}
+
+// ------------------------------------------------------------------------------
+sal_Int16 SAL_CALL
+SortedDynamicResultSet::getCapabilities()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Int16 nCaps = 0;
+
+ if ( mxOriginal.is() )
+ nCaps = mxOriginal->getCapabilities();
+
+ nCaps |= ContentResultSetCapability::SORTED;
+
+ return nCaps;
+}
+
+//--------------------------------------------------------------------------
+// XDynamicResultSetListener methods.
+// ------------------------------------------------------------------------------
+
+/** In the first notify-call the listener gets the two
+ <type>XResultSet</type>s and has to hold them. The <type>XResultSet</type>s
+ are implementations of the service <type>ContentResultSet</type>.
+
+ <p>The notified new <type>XResultSet</type> will stay valid after returning
+ notification. The old one will become invalid after returning notification.
+
+ <p>While in notify-call the listener is allowed to read old and new version,
+ except in the first call, where only the new Resultset is valid.
+
+ <p>The Listener is allowed to blockade this call, until he really want to go
+ to the new version. The only situation, where the listener has to return the
+ update call at once is, while he disposes his broadcaster or while he is
+ removing himsef as listener (otherwise you deadlock)!!!
+*/
+void SAL_CALL
+SortedDynamicResultSet::impl_notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Bool bHasNew = sal_False;
+ sal_Bool bHasModified = sal_False;
+
+ SortedResultSet *pCurSet = NULL;
+
+ // mxNew und mxOld vertauschen und anschliessend die Tabellen von Old
+ // nach New kopieren
+ if ( mbGotWelcome )
+ {
+ if ( mbUseOne )
+ {
+ mbUseOne = sal_False;
+ mpTwo->CopyData( mpOne );
+ pCurSet = mpTwo;
+ }
+ else
+ {
+ mbUseOne = sal_True;
+ mpOne->CopyData( mpTwo );
+ pCurSet = mpOne;
+ }
+ }
+
+ Any aRet;
+
+ try {
+ aRet = pCurSet->getPropertyValue( OUString::createFromAscii( "IsRowCountFinal" ) );
+ }
+ catch ( UnknownPropertyException ) {}
+ catch ( WrappedTargetException ) {}
+
+ long nOldCount = pCurSet->GetCount();
+ sal_Bool bWasFinal = false;
+
+ aRet >>= bWasFinal;
+
+ // handle the actions in the list
+ for ( long i=0; i<Changes.Changes.getLength(); i++ )
+ {
+ const ListAction aAction = Changes.Changes[i];
+ switch ( aAction.ListActionType )
+ {
+ case ListActionType::WELCOME:
+ {
+ WelcomeDynamicResultSetStruct aWelcome;
+ if ( aAction.ActionInfo >>= aWelcome )
+ {
+ mpTwo = new SortedResultSet( aWelcome.Old );
+ mxTwo = mpTwo;
+ mpOne = new SortedResultSet( aWelcome.New );
+ mxOne = mpOne;
+ mpOne->Initialize( maOptions, mxCompFac );
+ mbGotWelcome = sal_True;
+ mbUseOne = sal_True;
+ pCurSet = mpOne;
+
+ aWelcome.Old = mxTwo;
+ aWelcome.New = mxOne;
+
+ ListAction *pWelcomeAction = new ListAction;
+ pWelcomeAction->ActionInfo <<= aWelcome;
+ pWelcomeAction->Position = 0;
+ pWelcomeAction->Count = 0;
+ pWelcomeAction->ListActionType = ListActionType::WELCOME;
+
+ maActions.Insert( pWelcomeAction );
+ }
+ else
+ {
+ // throw RuntimeException();
+ }
+ break;
+ }
+ case ListActionType::INSERTED:
+ {
+ pCurSet->InsertNew( aAction.Position, aAction.Count );
+ bHasNew = sal_True;
+ break;
+ }
+ case ListActionType::REMOVED:
+ {
+ pCurSet->Remove( aAction.Position,
+ aAction.Count,
+ &maActions );
+ break;
+ }
+ case ListActionType::MOVED:
+ {
+ long nOffset = 0;
+ if ( aAction.ActionInfo >>= nOffset )
+ {
+ pCurSet->Move( aAction.Position,
+ aAction.Count,
+ nOffset );
+ }
+ break;
+ }
+ case ListActionType::PROPERTIES_CHANGED:
+ {
+ pCurSet->SetChanged( aAction.Position, aAction.Count );
+ bHasModified = sal_True;
+ break;
+ }
+ default: break;
+ }
+ }
+
+ if ( bHasModified )
+ pCurSet->ResortModified( &maActions );
+
+ if ( bHasNew )
+ pCurSet->ResortNew( &maActions );
+
+ // send the new actions with a notify to the listeners
+ SendNotify();
+
+ // check for propertyChangeEvents
+ pCurSet->CheckProperties( nOldCount, bWasFinal );
+}
+
+//-----------------------------------------------------------------
+// XEventListener
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::impl_disposing( const EventObject& )
+ throw( RuntimeException )
+{
+ mxListener.clear();
+ mxOriginal.clear();
+}
+
+// ------------------------------------------------------------------------------
+// private methods
+// ------------------------------------------------------------------------------
+void SortedDynamicResultSet::SendNotify()
+{
+ long nCount = maActions.Count();
+
+ if ( nCount && mxListener.is() )
+ {
+ Sequence< ListAction > aActionList( maActions.Count() );
+ ListAction *pActionList = aActionList.getArray();
+
+ for ( long i=0; i<nCount; i++ )
+ {
+ pActionList[ i ] = *(maActions.GetAction( i ));
+ }
+
+ ListEvent aNewEvent;
+ aNewEvent.Changes = aActionList;
+
+ mxListener->notify( aNewEvent );
+ }
+
+ // clean up
+ maActions.Clear();
+}
+
+//=========================================================================
+//
+// SortedDynamicResultSetFactory
+//
+//=========================================================================
+SortedDynamicResultSetFactory::SortedDynamicResultSetFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ mxSMgr = rSMgr;
+}
+
+//--------------------------------------------------------------------------
+SortedDynamicResultSetFactory::~SortedDynamicResultSetFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( SortedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XSortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( SortedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XSortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( SortedDynamicResultSetFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedDynamicResultSetFactory" ),
+ OUString::createFromAscii(
+ DYNAMIC_RESULTSET_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( SortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// SortedDynamicResultSetFactory methods.
+//--------------------------------------------------------------------------
+Reference< XDynamicResultSet > SAL_CALL
+SortedDynamicResultSetFactory::createSortedDynamicResultSet(
+ const Reference< XDynamicResultSet > & Source,
+ const Sequence< NumberedSortingInfo > & Info,
+ const Reference< XAnyCompareFactory > & CompareFactory )
+ throw( RuntimeException )
+{
+ Reference< XDynamicResultSet > xRet;
+ xRet = new SortedDynamicResultSet( Source, Info, CompareFactory, mxSMgr );
+ return xRet;
+}
+
+//=========================================================================
+//
+// EventList
+//
+//=========================================================================
+
+void EventList::Clear()
+{
+ for ( std::deque< LISTACTION* >::size_type i = 0;
+ i < maData.size(); ++i )
+ {
+ delete maData[i];
+ }
+
+ maData.clear();
+}
+
+//--------------------------------------------------------------------------
+void EventList::AddEvent( long nType, long nPos, long nCount )
+{
+ ListAction *pAction = new ListAction;
+ pAction->Position = nPos;
+ pAction->Count = nCount;
+ pAction->ListActionType = nType;
+
+ Insert( pAction );
+}
+
+//=================================================================
+//
+// SortedDynamicResultSetListener
+//
+//=================================================================
+
+SortedDynamicResultSetListener::SortedDynamicResultSetListener(
+ SortedDynamicResultSet *mOwner )
+{
+ mpOwner = mOwner;
+}
+
+//-----------------------------------------------------------------
+SortedDynamicResultSetListener::~SortedDynamicResultSetListener()
+{
+}
+
+//-----------------------------------------------------------------
+// XInterface methods.
+//-----------------------------------------------------------------
+
+XINTERFACE_IMPL_2( SortedDynamicResultSetListener,
+ XEventListener, /* base class of XDynamicResultSetListener */
+ XDynamicResultSetListener );
+
+//-----------------------------------------------------------------
+// XEventListener ( base of XDynamicResultSetListener )
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::disposing( const EventObject& Source )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpOwner )
+ mpOwner->impl_disposing( Source );
+}
+
+//-----------------------------------------------------------------
+// XDynamicResultSetListener
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpOwner )
+ mpOwner->impl_notify( Changes );
+}
+
+//-----------------------------------------------------------------
+// own methods:
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::impl_OwnerDies()
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mpOwner = NULL;
+}
+
diff --git a/ucb/source/sorter/sortdynres.hxx b/ucb/source/sorter/sortdynres.hxx
new file mode 100644
index 000000000000..fe026d40a3f7
--- /dev/null
+++ b/ucb/source/sorter/sortdynres.hxx
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SORTDYNRES_HXX
+#define _SORTDYNRES_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XDynamicResultSetListener.hpp>
+#include <com/sun/star/ucb/ListenerAlreadySetException.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+#include <ucbhelper/macros.hxx>
+#include "sortresult.hxx"
+
+namespace cppu {
+ class OInterfaceContainerHelper;
+}
+
+//-----------------------------------------------------------------------------
+
+#define NUMBERED_SORTINGINFO com::sun::star::ucb::NumberedSortingInfo
+#define RUNTIMEEXCEPTION com::sun::star::uno::RuntimeException
+#define REFERENCE com::sun::star::uno::Reference
+#define SEQUENCE com::sun::star::uno::Sequence
+#define EVENTOBJECT com::sun::star::lang::EventObject
+#define XEVENTLISTENER com::sun::star::lang::XEventListener
+#define XMULTISERVICEFACTORY com::sun::star::lang::XMultiServiceFactory
+#define XRESULTSET com::sun::star::sdbc::XResultSet
+#define SQLEXCEPTION com::sun::star::sdbc::SQLException
+#define XANYCOMPAREFACTORY com::sun::star::ucb::XAnyCompareFactory
+#define XDYNAMICRESULTSET com::sun::star::ucb::XDynamicResultSet
+#define XDYNAMICRESULTSETLISTENER com::sun::star::ucb::XDynamicResultSetListener
+#define LISTENERALREADYSETEXCEPTION com::sun::star::ucb::ListenerAlreadySetException
+
+#define DYNAMIC_RESULTSET_SERVICE_NAME "com.sun.star.ucb.SortedDynamicResultSet"
+#define DYNAMIC_RESULTSET_FACTORY_NAME "com.sun.star.ucb.SortedDynamicResultSetFactory"
+
+//-----------------------------------------------------------------------------
+class SortedDynamicResultSetListener;
+
+class SortedDynamicResultSet:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XDynamicResultSet
+{
+ cppu::OInterfaceContainerHelper *mpDisposeEventListeners;
+
+ REFERENCE < XDYNAMICRESULTSETLISTENER > mxListener;
+ REFERENCE < XDYNAMICRESULTSETLISTENER > mxOwnListener;
+
+ REFERENCE < XRESULTSET > mxOne;
+ REFERENCE < XRESULTSET > mxTwo;
+ REFERENCE < XDYNAMICRESULTSET > mxOriginal;
+ SEQUENCE < NUMBERED_SORTINGINFO > maOptions;
+ REFERENCE < XANYCOMPAREFACTORY > mxCompFac;
+ REFERENCE < XMULTISERVICEFACTORY > mxSMgr;
+
+ SortedResultSet* mpOne;
+ SortedResultSet* mpTwo;
+ SortedDynamicResultSetListener* mpOwnListener;
+
+ EventList maActions;
+ osl::Mutex maMutex;
+ sal_Bool mbGotWelcome :1;
+ sal_Bool mbUseOne :1;
+ sal_Bool mbStatic :1;
+
+private:
+
+ void SendNotify();
+
+public:
+ SortedDynamicResultSet( const REFERENCE < XDYNAMICRESULTSET > &xOriginal,
+ const SEQUENCE < NUMBERED_SORTINGINFO > &aOptions,
+ const REFERENCE < XANYCOMPAREFACTORY > &xCompFac,
+ const REFERENCE < XMULTISERVICEFACTORY > &xSMgr );
+
+ ~SortedDynamicResultSet();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ //-----------------------------------------------------------------
+ // XComponent
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ dispose() throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ //-----------------------------------------------------------------
+ // XDynamicResultSet
+ //-----------------------------------------------------------------
+ virtual REFERENCE< XRESULTSET > SAL_CALL
+ getStaticResultSet( )
+ throw( LISTENERALREADYSETEXCEPTION, RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ setListener( const REFERENCE< XDYNAMICRESULTSETLISTENER >& Listener )
+ throw( LISTENERALREADYSETEXCEPTION, RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ connectToCache( const REFERENCE< XDYNAMICRESULTSET > & xCache )
+ throw( LISTENERALREADYSETEXCEPTION,
+ com::sun::star::ucb::AlreadyInitializedException,
+ com::sun::star::ucb::ServiceNotFoundException,
+ RUNTIMEEXCEPTION );
+
+ virtual sal_Int16 SAL_CALL
+ getCapabilities()
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_disposing( const EVENTOBJECT& Source )
+ throw( RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ impl_notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( RUNTIMEEXCEPTION );
+};
+
+//-----------------------------------------------------------------------------
+
+class SortedDynamicResultSetListener:
+ public cppu::OWeakObject,
+ public com::sun::star::ucb::XDynamicResultSetListener
+{
+ SortedDynamicResultSet *mpOwner;
+ osl::Mutex maMutex;
+
+public:
+ SortedDynamicResultSetListener( SortedDynamicResultSet *mOwner );
+ ~SortedDynamicResultSetListener();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XEventListener ( base of XDynamicResultSetListener )
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ disposing( const EVENTOBJECT& Source )
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // XDynamicResultSetListener
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ //-----------------------------------------------------------------
+ void SAL_CALL impl_OwnerDies();
+};
+
+//-----------------------------------------------------------------------------
+
+class SortedDynamicResultSetFactory:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XSortedDynamicResultSetFactory
+{
+
+ REFERENCE< XMULTISERVICEFACTORY > mxSMgr;
+
+public:
+
+ SortedDynamicResultSetFactory(
+ const REFERENCE< XMULTISERVICEFACTORY > & rSMgr);
+
+ ~SortedDynamicResultSetFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XSortedDynamicResultSetFactory
+
+ virtual REFERENCE< XDYNAMICRESULTSET > SAL_CALL
+ createSortedDynamicResultSet(
+ const REFERENCE< XDYNAMICRESULTSET > & Source,
+ const SEQUENCE< NUMBERED_SORTINGINFO > & Info,
+ const REFERENCE< XANYCOMPAREFACTORY > & CompareFactory )
+ throw( RUNTIMEEXCEPTION );
+};
+
+#endif
diff --git a/ucb/source/sorter/sortmain.cxx b/ucb/source/sorter/sortmain.cxx
new file mode 100644
index 000000000000..d96b4bcff796
--- /dev/null
+++ b/ucb/source/sorter/sortmain.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <sortdynres.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const OUString & rImplementationName,
+ Sequence< OUString > const & rServiceNames )
+{
+ OUString aKeyName( OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // SortedDynamicResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ SortedDynamicResultSetFactory::getImplementationName_Static(),
+ SortedDynamicResultSetFactory::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // SortedDynamicResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( SortedDynamicResultSetFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = SortedDynamicResultSetFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/sorter/sortresult.cxx b/ucb/source/sorter/sortresult.cxx
new file mode 100644
index 000000000000..6e546950a23a
--- /dev/null
+++ b/ucb/source/sorter/sortresult.cxx
@@ -0,0 +1,2070 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <vector>
+#include <sortresult.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/XAnyCompare.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <osl/diagnose.h>
+
+//-----------------------------------------------------------------------------
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::io;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+//=========================================================================
+
+// The mutex to synchronize access to containers.
+static osl::Mutex& getContainerMutex()
+{
+ static osl::Mutex* pMutex = NULL;
+ if( !pMutex )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pMutex )
+ {
+ static osl::Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+
+ return *pMutex;
+}
+
+//==========================================================================
+
+struct SortInfo
+{
+ sal_Bool mbUseOwnCompare;
+ sal_Bool mbAscending;
+ sal_Bool mbCaseSensitive;
+ sal_Int32 mnColumn;
+ sal_Int32 mnType;
+ SortInfo* mpNext;
+ Reference < XAnyCompare > mxCompareFunction;
+};
+
+//-----------------------------------------------------------------------------
+
+struct SortListData
+{
+ sal_Bool mbModified;
+ long mnCurPos;
+ long mnOldPos;
+
+ SortListData( long nPos, sal_Bool bModified = sal_False );
+};
+
+//============================================================================
+//
+// class SRSPropertySetInfo.
+//
+//============================================================================
+
+class SRSPropertySetInfo :
+ public OWeakObject,
+ public XTypeProvider,
+ public XPropertySetInfo
+{
+ Property maProps[2];
+
+private:
+
+public:
+ SRSPropertySetInfo();
+ virtual ~SRSPropertySetInfo();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties()
+ throw( RuntimeException );
+ virtual Property SAL_CALL getPropertyByName( const OUString& aName )
+ throw( UnknownPropertyException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
+ throw( RuntimeException );
+};
+
+//=========================================================================
+//
+// PropertyChangeListenerContainer_Impl.
+//
+//=========================================================================
+
+struct equalStr_Impl
+{
+ bool operator()( const OUString& s1, const OUString& s2 ) const
+ {
+ return !!( s1 == s2 );
+ }
+};
+
+struct hashStr_Impl
+{
+ size_t operator()( const OUString& rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+typedef OMultiTypeInterfaceContainerHelperVar
+<
+ OUString,
+ hashStr_Impl,
+ equalStr_Impl
+> PropertyChangeListenerContainer_Impl;
+
+//=========================================================================
+//
+// class PropertyChangeListeners_Impl
+//
+//=========================================================================
+
+class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
+{
+public:
+ PropertyChangeListeners_Impl()
+ : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
+};
+
+//==========================================================================
+SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
+{
+ mpDisposeEventListeners = NULL;
+ mpPropChangeListeners = NULL;
+ mpVetoChangeListeners = NULL;
+ mpPropSetInfo = NULL;
+
+ mxOriginal = aResult;
+ mpSortInfo = NULL;
+ mnLastSort = 0;
+ mnCurEntry = 0;
+ mnCount = 0;
+ mbIsCopy = sal_False;
+}
+
+//--------------------------------------------------------------------------
+SortedResultSet::~SortedResultSet()
+{
+ mxOriginal.clear();
+ mxOther.clear();
+
+ if ( !mbIsCopy )
+ {
+ SortInfo *pInfo = mpSortInfo;
+ while ( pInfo )
+ {
+ mpSortInfo = pInfo->mpNext;
+ delete pInfo;
+ pInfo = mpSortInfo;
+ }
+ }
+
+ mpSortInfo = NULL;
+
+ if ( mpPropSetInfo )
+ mpPropSetInfo->release();
+
+ delete mpPropChangeListeners;
+ delete mpVetoChangeListeners;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_9( SortedResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XContentAccess,
+ XResultSet,
+ XRow,
+ XCloseable,
+ XResultSetMetaDataSupplier,
+ XPropertySet );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_9( SortedResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XContentAccess,
+ XResultSet,
+ XRow,
+ XCloseable,
+ XResultSetMetaDataSupplier,
+ XPropertySet );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedResultSet" ),
+ OUString::createFromAscii(
+ RESULTSET_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::dispose()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+ mpDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ if ( mpPropChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ mpPropChangeListeners->disposeAndClear( aEvt );
+ }
+
+ if ( mpVetoChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ mpVetoChangeListeners->disposeAndClear( aEvt );
+ }
+
+ mxOriginal.clear();
+ mxOther.clear();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpDisposeEventListeners )
+ mpDisposeEventListeners =
+ new OInterfaceContainerHelper( getContainerMutex() );
+
+ mpDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners )
+ mpDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// XContentAccess methods.
+//--------------------------------------------------------------------------
+
+OUString SAL_CALL
+SortedResultSet::queryContentIdentifierString()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
+}
+
+//--------------------------------------------------------------------------
+Reference< XContentIdentifier > SAL_CALL
+SortedResultSet::queryContentIdentifier()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
+}
+
+//--------------------------------------------------------------------------
+Reference< XContent > SAL_CALL
+SortedResultSet::queryContent()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContent();
+}
+
+
+//--------------------------------------------------------------------------
+// XResultSet methods.
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::next()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ mnCurEntry++;
+
+ if ( mnCurEntry > 0 )
+ {
+ if ( mnCurEntry <= mnCount )
+ {
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = mnCount + 1;
+ }
+ }
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry )
+ return sal_False;
+ else
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isAfterLast()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry > mnCount )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isFirst()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry == 1 )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isLast()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry == mnCount )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::beforeFirst()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mnCurEntry = 0;
+ mxOriginal->beforeFirst();
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::afterLast()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mnCurEntry = mnCount+1;
+ mxOriginal->afterLast();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::first()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mnCount )
+ {
+ mnCurEntry = 1;
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::last()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mnCount )
+ {
+ mnCurEntry = mnCount;
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+}
+
+//-------------------------------------------------------------------------
+sal_Int32 SAL_CALL SortedResultSet::getRow()
+ throw ( SQLException, RuntimeException )
+{
+ return mnCurEntry;
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor to the given row number in the result set.
+ <p>If the row number is positive, the cursor moves to the given row
+ number with respect to the beginning of the result set. The first
+ row is row 1, the second is row 2, and so on.
+ <p>If the given row number is negative, the cursor moves to an
+ absolute row position with respect to the end of the result set.
+ For example, calling <code>moveToPosition(-1)</code> positions the
+ cursor on the last row, <code>moveToPosition(-2)</code> indicates the
+ next-to-last row, and so on.
+ <p>An attempt to position the cursor beyond the first/last row in the
+ result set leaves the cursor before/after the first/last row,
+ respectively.
+ <p>Note: Calling <code>moveToPosition(1)</code> is the same
+ as calling <code>moveToFirst()</code>. Calling
+ <code>moveToPosition(-1)</code> is the same as calling
+ <code>moveToLast()</code>.
+ @param row
+ is the number of rows to move. Could be negative.
+ @returns
+ <sal_True/> if the cursor is on a row; <sal_False/> otherwise
+ @throws SQLException
+ if a database access error occurs or if row is 0, or the result set
+ type is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Int32 nIndex;
+
+ if ( row > 0 )
+ {
+ if ( row <= mnCount )
+ {
+ mnCurEntry = row;
+ nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = mnCount + 1;
+ return sal_False;
+ }
+ }
+ else if ( row == 0 )
+ {
+ throw SQLException();
+ }
+ else
+ {
+ if ( mnCount + row + 1 > 0 )
+ {
+ mnCurEntry = mnCount + row + 1;
+ nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor a relative number of rows, either positive or negative.
+ <p>
+ Attempting to move beyond the first/last row in the result set positions
+ the cursor before/after the first/last row. Calling
+ <code>moveRelative(0)</code> is valid, but does not change the cursor
+ position.
+ <p>Note: Calling <code>moveRelative(1)</code> is different from calling
+ <code>moveNext()</code> because is makes sense to call
+ <code>moveNext()</code> when there is no current row, for example,
+ when the cursor is positioned before the first row or after the last
+ row of the result set.
+ @param rows
+ is the number of rows to move. Could be negative.
+ @returns
+ <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
+ the result set.
+ @throws SQLException
+ if a database access error occurs or if there is no
+ current row, or the result set type is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ if ( rows == 0 )
+ return sal_True;
+
+ sal_Int32 nTmp = mnCurEntry + rows;
+
+ if ( nTmp <= 0 )
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+ else if ( nTmp > mnCount )
+ {
+ mnCurEntry = mnCount + 1;
+ return sal_False;
+ }
+ else
+ {
+ mnCurEntry = nTmp;
+ nTmp = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nTmp );
+ }
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor to the previous row in the result set.
+ <p>Note: <code>previous()</code> is not the same as
+ <code>relative(-1)</code> because it makes sense to call
+ <code>previous()</code> when there is no current row.
+ @returns <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
+ the result set.
+ @throws SQLException
+ if a database access error occurs or the result set type
+ is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::previous()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ mnCurEntry -= 1;
+
+ if ( mnCurEntry > 0 )
+ {
+ if ( mnCurEntry <= mnCount )
+ {
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ }
+ else
+ mnCurEntry = 0;
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::refreshRow()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ mxOriginal->refreshRow();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowUpdated()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowUpdated();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowInserted()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowInserted();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowDeleted()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowDeleted();
+}
+
+//-------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->getStatement();
+}
+
+//--------------------------------------------------------------------------
+// XRow methods.
+//--------------------------------------------------------------------------
+
+sal_Bool SAL_CALL SortedResultSet::wasNull()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->wasNull();
+}
+
+//-------------------------------------------------------------------------
+OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
+}
+//-------------------------------------------------------------------------
+sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XInputStream > SAL_CALL
+SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XInputStream > SAL_CALL
+SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
+ const Reference< XNameAccess >& typeMap )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
+ typeMap);
+}
+
+//-------------------------------------------------------------------------
+Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
+}
+
+
+//--------------------------------------------------------------------------
+// XCloseable methods.
+//--------------------------------------------------------------------------
+
+void SAL_CALL SortedResultSet::close()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ Reference< XCloseable >::query(mxOriginal)->close();
+}
+
+//--------------------------------------------------------------------------
+// XResultSetMetaDataSupplier methods.
+//--------------------------------------------------------------------------
+
+Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
+}
+
+
+//--------------------------------------------------------------------------
+// XPropertySet methods.
+//--------------------------------------------------------------------------
+
+Reference< XPropertySetInfo > SAL_CALL
+SortedResultSet::getPropertySetInfo() throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropSetInfo )
+ {
+ mpPropSetInfo = new SRSPropertySetInfo();
+ mpPropSetInfo->acquire();
+ }
+
+ return Reference< XPropertySetInfo >( mpPropSetInfo );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::setPropertyValue(
+ const OUString& PropertyName,
+ const Any& )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
+ ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
+ throw IllegalArgumentException();
+ else
+ throw UnknownPropertyException();
+}
+
+//--------------------------------------------------------------------------
+Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ Any aRet;
+
+ if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
+ {
+ aRet <<= maS2O.Count();
+ }
+ else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
+ {
+ sal_uInt32 nOrgCount = 0;
+ sal_Bool bOrgFinal = false;
+ Any aOrgRet;
+
+ aRet <<= (sal_Bool) sal_False;
+
+ aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
+ getPropertyValue( PropertyName );
+ aOrgRet >>= bOrgFinal;
+
+ if ( bOrgFinal )
+ {
+ aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
+ getPropertyValue( OUString::createFromAscii( "RowCount" ) );
+ aOrgRet >>= nOrgCount;
+ if ( nOrgCount == maS2O.Count() )
+ aRet <<= (sal_Bool) sal_True;
+ }
+ }
+ else
+ throw UnknownPropertyException();
+
+ return aRet;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addPropertyChangeListener(
+ const OUString& PropertyName,
+ const Reference< XPropertyChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ mpPropChangeListeners =
+ new PropertyChangeListeners_Impl();
+
+ mpPropChangeListeners->addInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removePropertyChangeListener(
+ const OUString& PropertyName,
+ const Reference< XPropertyChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpPropChangeListeners )
+ mpPropChangeListeners->removeInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addVetoableChangeListener(
+ const OUString& PropertyName,
+ const Reference< XVetoableChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpVetoChangeListeners )
+ mpVetoChangeListeners =
+ new PropertyChangeListeners_Impl();
+
+ mpVetoChangeListeners->addInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removeVetoableChangeListener(
+ const OUString& PropertyName,
+ const Reference< XVetoableChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpVetoChangeListeners )
+ mpVetoChangeListeners->removeInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+// private methods
+//--------------------------------------------------------------------------
+long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
+ Reference < XResultSet > xResultTwo,
+ long nIndexOne, long nIndexTwo,
+ SortInfo* pSortInfo )
+
+ throw( SQLException, RuntimeException )
+{
+ Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
+ Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
+
+ long nCompare = 0;
+ long nColumn = pSortInfo->mnColumn;
+
+ switch ( pSortInfo->mnType )
+ {
+ case DataType::BIT :
+ case DataType::TINYINT :
+ case DataType::SMALLINT :
+ case DataType::INTEGER :
+ {
+ sal_Int32 aOne = 0;
+ sal_Int32 aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getInt( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getInt( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::BIGINT :
+ {
+ sal_Int64 aOne = 0;
+ sal_Int64 aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getLong( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getLong( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::CHAR :
+ case DataType::VARCHAR :
+ case DataType::LONGVARCHAR :
+ {
+ OUString aOne, aTwo;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getString( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getString( nColumn );
+
+ if ( ! pSortInfo->mbCaseSensitive )
+ {
+ aOne = aOne.toAsciiLowerCase();
+ aTwo = aTwo.toAsciiLowerCase();
+ }
+
+ nCompare = aOne.compareTo( aTwo );
+ break;
+ }
+ case DataType::DATE :
+ {
+ Date aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getDate( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getDate( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
+ }
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::TIME :
+ {
+ Time aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getTime( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getTime( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.HundredthSeconds
+ - (sal_Int32) aOne.HundredthSeconds;
+ }}
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::TIMESTAMP :
+ {
+ DateTime aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getTimestamp( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getTimestamp( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.HundredthSeconds
+ - (sal_Int32) aOne.HundredthSeconds;
+ }}}}}
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::REAL :
+ {
+ float aOne = 0;
+ float aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getFloat( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getFloat( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::FLOAT :
+ case DataType::DOUBLE :
+ {
+ double aOne = 0;
+ double aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getDouble( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getDouble( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ default:
+ {
+ OSL_ENSURE( sal_False, "DataType not supported for compare!" );
+ }
+ }
+
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
+ Reference < XResultSet > xResultTwo,
+ long nIndexOne, long nIndexTwo )
+ throw( SQLException, RuntimeException )
+{
+ long nCompare = 0;
+ SortInfo* pInfo = mpSortInfo;
+
+ while ( !nCompare && pInfo )
+ {
+ if ( pInfo->mbUseOwnCompare )
+ {
+ nCompare = CompareImpl( xResultOne, xResultTwo,
+ nIndexOne, nIndexTwo, pInfo );
+ }
+ else
+ {
+ Any aOne, aTwo;
+
+ Reference < XRow > xRowOne =
+ Reference< XRow >::query( xResultOne );
+ Reference < XRow > xRowTwo =
+ Reference< XRow >::query( xResultTwo );
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
+
+ nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
+ }
+
+ if ( ! pInfo->mbAscending )
+ nCompare = - nCompare;
+
+ pInfo = pInfo->mpNext;
+ }
+
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::Compare( SortListData *pOne,
+ SortListData *pTwo )
+ throw( SQLException, RuntimeException )
+{
+ long nIndexOne;
+ long nIndexTwo;
+
+ Reference < XResultSet > xResultOne;
+ Reference < XResultSet > xResultTwo;
+
+ if ( pOne->mbModified )
+ {
+ xResultOne = mxOther;
+ nIndexOne = pOne->mnOldPos;
+ }
+ else
+ {
+ xResultOne = mxOriginal;
+ nIndexOne = pOne->mnCurPos;
+ }
+
+ if ( pTwo->mbModified )
+ {
+ xResultTwo = mxOther;
+ nIndexTwo = pTwo->mnOldPos;
+ }
+ else
+ {
+ xResultTwo = mxOriginal;
+ nIndexTwo = pTwo->mnCurPos;
+ }
+
+ long nCompare;
+ nCompare = CompareImpl( xResultOne, xResultTwo,
+ nIndexOne, nIndexTwo );
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::FindPos( SortListData *pEntry,
+ long _nStart, long _nEnd )
+ throw( SQLException, RuntimeException )
+{
+ if ( _nStart > _nEnd )
+ return _nStart + 1;
+
+ long nStart = _nStart;
+ long nEnd = _nEnd;
+ long nMid = 0, nCompare = 0;
+
+ SortListData *pMid;
+
+ while ( nStart <= nEnd )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maS2O.GetData( nMid );
+ nCompare = Compare( pEntry, pMid );
+
+ if ( !nCompare )
+ nCompare = ((long) pEntry ) - ( (long) pMid );
+
+ if ( nCompare < 0 ) // pEntry < pMid
+ nEnd = nMid - 1;
+ else
+ nStart = nMid + 1;
+ }
+
+ if ( nCompare < 0 ) // pEntry < pMid
+ return nMid;
+ else
+ return nMid+1;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ return;
+
+ // Notify listeners interested especially in the changed property.
+ OInterfaceContainerHelper* pPropsContainer =
+ mpPropChangeListeners->getContainer( rEvt.PropertyName );
+ if ( pPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+
+ // Notify listeners interested in all properties.
+ pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
+ if ( pPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// public methods
+//--------------------------------------------------------------------------
+
+void SortedResultSet::CopyData( SortedResultSet *pSource )
+{
+ const SortedEntryList *pSrcS2O = pSource->GetS2OList();
+ const SimpleList *pSrcO2S = pSource->GetO2SList();
+
+ long i, nCount;
+
+ maS2O.Clear();
+ maO2S.Clear();
+ maModList.Clear();
+
+ maS2O.Insert( NULL, 0 );
+ maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
+
+ nCount = pSrcS2O->Count();
+
+ for ( i=1; i<nCount; i++ )
+ {
+ maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
+ maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
+ }
+
+ mnLastSort = maS2O.Count();
+ mxOther = pSource->GetResultSet();
+
+ if ( !mpSortInfo )
+ {
+ mpSortInfo = pSource->GetSortInfo();
+ mbIsCopy = sal_True;
+ }
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::Initialize(
+ const Sequence < NumberedSortingInfo > &xSortInfo,
+ const Reference< XAnyCompareFactory > &xCompFactory )
+{
+ BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
+ // Insert dummy at pos 0
+ SortListData *pData = new SortListData( 0 );
+ maS2O.Insert( pData, 0 );
+
+ long nIndex = 1;
+
+ // now fetch all the elements from the original result set,
+ // get there new position in the sorted result set and insert
+ // an entry in the sorted to original mapping list
+ try {
+ while ( mxOriginal->absolute( nIndex ) )
+ {
+ pData = new SortListData( nIndex );
+ long nPos = FindPos( pData, 1, nIndex-1 );
+
+ maS2O.Insert( pData, nPos );
+
+ nIndex++;
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); }
+
+ // when we have fetched all the elements, we can create the
+ // original to sorted mapping list from the s2o list
+ maO2S.Clear();
+ maO2S.Insert( NULL, (sal_uInt32) 0 );
+
+ // insert some dummy entries first and replace then
+ // the entries with the right ones
+ sal_uInt32 i;
+
+ for ( i=1; i<maS2O.Count(); i++ )
+ maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
+ for ( i=1; i<maS2O.Count(); i++ )
+ maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
+
+ mnCount = maS2O.Count() - 1;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ return;
+
+ try {
+ // check for propertyChangeEvents
+ if ( nOldCount != GetCount() )
+ {
+ sal_Bool bIsFinal = sal_False;
+ PropertyChangeEvent aEvt;
+
+ aEvt.PropertyName = OUString::createFromAscii( "RowCount" );
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = -1;
+ aEvt.OldValue <<= nOldCount;
+ aEvt.NewValue <<= GetCount();
+
+ PropertyChanged( aEvt );
+
+ OUString aName = OUString::createFromAscii( "IsRowCountFinal" );
+ Any aRet = getPropertyValue( aName );
+ if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
+ {
+ aEvt.PropertyName = aName;
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = -1;
+ aEvt.OldValue <<= (sal_Bool) bWasFinal;
+ aEvt.NewValue <<= (sal_Bool) bIsFinal;
+ PropertyChanged( aEvt );
+ }
+ }
+ }
+ catch ( UnknownPropertyException ) {}
+ catch ( WrappedTargetException ) {}
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::InsertNew( long nPos, long nCount )
+{
+ // in der maS2O Liste alle Einträge, die >= nPos sind, um nCount
+ // erhöhen
+ SortListData *pData;
+ long i, nEnd;
+
+ nEnd = maS2O.Count();
+ for ( i=1; i<=nEnd; i++ )
+ {
+ pData = maS2O.GetData( i );
+ if ( pData->mnCurPos >= nPos )
+ {
+ pData->mnCurPos += nCount;
+ }
+ }
+
+ // und die neuen einträge hinten an die maS2O Liste anhängen bzw
+ // an der Position nPos in der maO2S Liste einfügen
+ for ( i=0; i<nCount; i++ )
+ {
+ nEnd += 1;
+ pData = new SortListData( nEnd );
+
+ maS2O.Insert( pData, nEnd ); // Insert( Wert, Position )
+ maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Wert, Position )
+ }
+
+ mnCount += nCount;
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
+{
+ sal_uInt32 i, j;
+ long nOldLastSort;
+
+ // correct mnLastSort first
+ nOldLastSort = mnLastSort;
+ if ( nPos <= mnLastSort )
+ {
+ if ( nPos + nCount - 1 <= mnLastSort )
+ mnLastSort -= nCount;
+ else
+ mnLastSort = nPos - 1;
+ }
+
+ // remove the entries from the lists and correct the positions
+ // in the original2sorted list
+ for ( i=0; i < (sal_uInt32) nCount; i++ )
+ {
+ long nSortPos = (long) maO2S.GetObject( nPos );
+ maO2S.Remove( (sal_uInt32) nPos );
+
+ for ( j=1; j<=maO2S.Count(); j++ )
+ {
+ long nVal = (long) maO2S.GetObject( j );
+ if ( nVal > nSortPos )
+ {
+ --nVal;
+ maO2S.Replace( (void*) nVal, j );
+ }
+ }
+
+ SortListData *pData = maS2O.Remove( nSortPos );
+ if ( pData->mbModified )
+ maModList.Remove( (void*) pData );
+ delete pData;
+
+ // generate remove Event, but not for new entries
+ if ( nSortPos <= nOldLastSort )
+ pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
+ }
+
+ // correct the positions in the sorted list
+ for ( i=1; i<= maS2O.Count(); i++ )
+ {
+ SortListData *pData = maS2O.GetData( i );
+ if ( pData->mnCurPos > nPos )
+ pData->mnCurPos -= nCount;
+ }
+
+ mnCount -= nCount;
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::Move( long nPos, long nCount, long nOffset )
+{
+ if ( !nOffset )
+ return;
+
+ long i, nSortPos, nTo;
+ SortListData *pData;
+
+ for ( i=0; i<nCount; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( nPos+i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos += nOffset;
+ }
+
+ if ( nOffset < 0 )
+ {
+ for ( i=nPos+nOffset; i<nPos; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos += nCount;
+ }
+ }
+ else
+ {
+ long nStart = nPos + nCount;
+ long nEnd = nStart + nOffset;
+ for ( i=nStart; i<nEnd; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos -= nCount;
+ }
+ }
+
+ // remember the to be moved entries
+ long *pTmpArr = new long[ nCount ];
+ for ( i=0; i<nCount; i++ )
+ pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
+
+ // now move the entries, which are in the way
+ if ( nOffset < 0 )
+ {
+ // be carefully here, because nOffset is negative here, so an
+ // addition is a subtraction
+ long nFrom = nPos - 1;
+ nTo = nPos + nCount - 1;
+
+ // same for i here
+ for ( i=0; i>nOffset; i-- )
+ {
+ long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
+ maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
+ }
+
+ }
+ else
+ {
+ long nStart = nPos + nCount;
+ for ( i=0; i<nOffset; i++ )
+ {
+ long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
+ maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
+ }
+ }
+
+ // finally put the remembered entries at there new location
+ nTo = nPos + nOffset;
+ for ( i=0; i<nCount; i++ )
+ {
+ maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
+ }
+
+ delete [] pTmpArr;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::BuildSortInfo(
+ Reference< XResultSet > aResult,
+ const Sequence < NumberedSortingInfo > &xSortInfo,
+ const Reference< XAnyCompareFactory > &xCompFactory )
+{
+ Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
+
+ if ( ! xMeta.is() )
+ {
+ OSL_ENSURE( sal_False, "No MetaData, No Sorting!" );
+ return;
+ }
+
+ Reference < XResultSetMetaData > xData = xMeta->getMetaData();
+ const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
+
+ sal_Int32 nColumn;
+ OUString aPropName;
+ SortInfo *pInfo;
+
+ for ( long i=xSortInfo.getLength(); i > 0; )
+ {
+ --i;
+ nColumn = pSortInfo[ i ].ColumnIndex;
+ aPropName = xData->getColumnName( nColumn );
+ pInfo = new SortInfo;
+
+ if ( xCompFactory.is() )
+ pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
+ aPropName );
+
+ if ( pInfo->mxCompareFunction.is() )
+ {
+ pInfo->mbUseOwnCompare = sal_False;
+ pInfo->mnType = 0;
+ }
+ else
+ {
+ pInfo->mbUseOwnCompare = sal_True;
+ pInfo->mnType = xData->getColumnType( nColumn );
+ }
+
+ pInfo->mnColumn = nColumn;
+ pInfo->mbAscending = pSortInfo[ i ].Ascending;
+ pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
+ pInfo->mpNext = mpSortInfo;
+ mpSortInfo = pInfo;
+ }
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::SetChanged( long nPos, long nCount )
+{
+ for ( long i=0; i<nCount; i++ )
+ {
+ long nSortPos = (long) maO2S.GetObject( nPos );
+ if ( nSortPos < mnLastSort )
+ {
+ SortListData *pData = maS2O.GetData( nSortPos );
+ if ( ! pData->mbModified )
+ {
+ pData->mbModified = sal_True;
+ maModList.Append( pData );
+ }
+ }
+ nPos += 1;
+ }
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::ResortModified( EventList* pList )
+{
+ sal_uInt32 i, j;
+ long nCompare, nCurPos, nNewPos;
+ long nStart, nEnd, nOffset, nVal;
+ SortListData *pData;
+ ListAction *pAction;
+
+ try {
+ for ( i=0; i<maModList.Count(); i++ )
+ {
+ pData = (SortListData*) maModList.GetObject( i );
+ nCompare = CompareImpl( mxOther, mxOriginal,
+ pData->mnOldPos, pData->mnCurPos );
+ pData->mbModified = sal_False;
+ if ( nCompare != 0 )
+ {
+ nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
+ if ( nCompare < 0 )
+ {
+ nNewPos = FindPos( pData, 1, nCurPos-1 );
+ nStart = nNewPos;
+ nEnd = nCurPos;
+ nOffset = 1;
+ }
+ else
+ {
+ nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
+ nStart = nCurPos;
+ nEnd = mnLastSort;
+ nOffset = -1;
+ }
+
+ if ( nNewPos != nCurPos )
+ {
+ // correct the lists!
+ maS2O.Remove( (sal_uInt32) nCurPos );
+ maS2O.Insert( pData, nNewPos );
+ for ( j=1; j<maO2S.Count(); j++ )
+ {
+ nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
+ if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
+ {
+ nVal += nOffset;
+ maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
+ }
+ }
+
+ maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
+
+ pAction = new ListAction;
+ pAction->Position = nCurPos;
+ pAction->Count = 1;
+ pAction->ListActionType = ListActionType::MOVED;
+ pAction->ActionInfo <<= nNewPos-nCurPos;
+ pList->Insert( pAction );
+ }
+ pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
+ nNewPos, 1 );
+ }
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); }
+
+ maModList.Clear();
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::ResortNew( EventList* pList )
+{
+ long i, j, nNewPos, nVal;
+ SortListData *pData;
+
+ try {
+ for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
+ {
+ pData = (SortListData*) maModList.GetObject( i );
+ nNewPos = FindPos( pData, 1, mnLastSort );
+ if ( nNewPos != i )
+ {
+ maS2O.Remove( (sal_uInt32) i );
+ maS2O.Insert( pData, nNewPos );
+ // maO2S liste korigieren
+ for ( j=1; j<(long)maO2S.Count(); j++ )
+ {
+ nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
+ if ( nVal >= nNewPos )
+ maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
+ }
+ maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
+ }
+ mnLastSort++;
+ pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); }
+}
+
+//-------------------------------------------------------------------------
+//
+// SortListData
+//
+//-------------------------------------------------------------------------
+SortListData::SortListData( long nPos, sal_Bool bModified )
+{
+ mbModified = bModified;
+ mnCurPos = nPos;
+ mnOldPos = nPos;
+};
+
+
+//=========================================================================
+void SortedEntryList::Clear()
+{
+ for ( std::deque< LISTACTION* >::size_type i = 0;
+ i < maData.size(); ++i )
+ {
+ delete maData[i];
+ }
+
+ maData.clear();
+}
+
+//-------------------------------------------------------------------------
+void SortedEntryList::Insert( SortListData *pEntry, long nPos )
+{
+ if ( nPos < (long) maData.size() )
+ maData.insert( maData.begin() + nPos, pEntry );
+ else
+ maData.push_back( pEntry );
+}
+
+//-------------------------------------------------------------------------
+SortListData* SortedEntryList::Remove( long nPos )
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ {
+ pData = maData[ nPos ];
+ maData.erase( maData.begin() + nPos );
+ }
+ else
+ pData = NULL;
+
+ return pData;
+}
+
+//-------------------------------------------------------------------------
+SortListData* SortedEntryList::GetData( long nPos )
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ pData = maData[ nPos ];
+ else
+ pData = NULL;
+
+ return pData;
+}
+
+//-------------------------------------------------------------------------
+long SortedEntryList::operator [] ( long nPos ) const
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ pData = maData[ nPos ];
+ else
+ pData = NULL;
+
+ if ( pData )
+ if ( ! pData->mbModified )
+ return pData->mnCurPos;
+ else
+ {
+ OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!");
+ return 0;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!");
+ return 0;
+ }
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+void SimpleList::Remove( sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ {
+ maData.erase( maData.begin() + nPos );
+ }
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Remove( void* pData )
+{
+ sal_Bool bFound = sal_False;
+ sal_uInt32 i;
+
+ for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
+ {
+ if ( maData[ i ] == pData )
+ {
+ bFound = sal_True;
+ break;
+ }
+ }
+
+ if ( bFound )
+ maData.erase( maData.begin() + i );
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Insert( void* pData, sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ maData.insert( maData.begin() + nPos, pData );
+ else
+ maData.push_back( pData );
+}
+
+//-------------------------------------------------------------------------
+void* SimpleList::GetObject( sal_uInt32 nPos ) const
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ return maData[ nPos ];
+ else
+ return NULL;
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Replace( void* pData, sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ maData[ nPos ] = pData;
+}
+
+//-------------------------------------------------------------------------
+//
+// class SRSPropertySetInfo.
+//
+//-------------------------------------------------------------------------
+
+SRSPropertySetInfo::SRSPropertySetInfo()
+{
+ maProps[0].Name = OUString::createFromAscii( "RowCount" );
+ maProps[0].Handle = -1;
+ maProps[0].Type = ::getCppuType( (const OUString*) NULL );
+ maProps[0].Attributes = -1;
+
+ maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" );
+ maProps[1].Handle = -1;
+ maProps[1].Type = ::getBooleanCppuType();
+ maProps[1].Attributes = -1;
+}
+
+//-------------------------------------------------------------------------
+SRSPropertySetInfo::~SRSPropertySetInfo()
+{}
+
+//-------------------------------------------------------------------------
+// XInterface methods.
+//-------------------------------------------------------------------------
+
+XINTERFACE_IMPL_2( SRSPropertySetInfo,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//-------------------------------------------------------------------------
+// XTypeProvider methods.
+//-------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//-------------------------------------------------------------------------
+// XPropertySetInfo methods.
+//-------------------------------------------------------------------------
+Sequence< Property > SAL_CALL
+SRSPropertySetInfo::getProperties() throw( RuntimeException )
+{
+ return Sequence < Property > ( maProps, 2 );
+}
+
+//-------------------------------------------------------------------------
+Property SAL_CALL
+SRSPropertySetInfo::getPropertyByName( const OUString& Name )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ if ( Name.compareToAscii( "RowCount" ) == 0 )
+ return maProps[0];
+ else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
+ return maProps[1];
+ else
+ throw UnknownPropertyException();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL
+SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
+ throw( RuntimeException )
+{
+ if ( Name.compareToAscii( "RowCount" ) == 0 )
+ return sal_True;
+ else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
+ return sal_True;
+ else
+ return sal_False;
+}
+
diff --git a/ucb/source/sorter/sortresult.hxx b/ucb/source/sorter/sortresult.hxx
new file mode 100644
index 000000000000..3817152f3d6c
--- /dev/null
+++ b/ucb/source/sorter/sortresult.hxx
@@ -0,0 +1,455 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SORTRESULT_HXX
+#define _SORTRESULT_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/ListAction.hpp>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+
+#include <deque>
+#include <ucbhelper/macros.hxx>
+
+namespace cppu {
+ class OInterfaceContainerHelper;
+}
+
+//-----------------------------------------------------------------------------
+struct SortInfo;
+struct SortListData;
+class SRSPropertySetInfo;
+class PropertyChangeListeners_Impl;
+
+//-----------------------------------------------------------------------------
+class SortedEntryList
+{
+ std::deque < SortListData* > maData;
+
+public:
+ SortedEntryList(){}
+ ~SortedEntryList(){ Clear(); }
+
+ sal_uInt32 Count() const { return (sal_uInt32) maData.size(); }
+
+ void Clear();
+ void Insert( SortListData *pEntry, long nPos );
+ SortListData* Remove( long nPos );
+ SortListData* GetData( long nPos );
+
+ long operator [] ( long nPos ) const;
+};
+
+//-----------------------------------------------------------------------------
+#define LISTACTION com::sun::star::ucb::ListAction
+
+class EventList
+{
+ std::deque < LISTACTION* > maData;
+
+public:
+ EventList(){}
+ ~EventList(){ Clear(); }
+
+ sal_uInt32 Count() { return (sal_uInt32) maData.size(); }
+
+ void AddEvent( long nType, long nPos, long nCount );
+ void Insert( LISTACTION *pAction ) { maData.push_back( pAction ); }
+ void Clear();
+ LISTACTION* GetAction( long nIndex ) { return maData[ nIndex ]; }
+};
+
+//-----------------------------------------------------------------------------
+
+class SimpleList
+{
+ std::deque < void* > maData;
+
+public:
+ SimpleList(){}
+ ~SimpleList(){ Clear(); }
+
+ sal_uInt32 Count() { return (sal_uInt32) maData.size(); }
+ void Clear() { maData.clear(); }
+
+ void Remove( sal_uInt32 nPos );
+ void Remove( void* pData );
+
+ void Append( void* pData )
+ { maData.push_back( pData ); }
+ void Insert( void* pData, sal_uInt32 nPos );
+ void* GetObject( sal_uInt32 nPos ) const;
+ void Replace( void* pData, sal_uInt32 nPos );
+};
+
+//-----------------------------------------------------------------------------
+
+#define PROPERTYCHANGEEVENT com::sun::star::beans::PropertyChangeEvent
+#define RUNTIME_EXCEPTION com::sun::star::uno::RuntimeException
+#define REFERENCE com::sun::star::uno::Reference
+#define SEQUENCE com::sun::star::uno::Sequence
+#define XEVENTLISTENER com::sun::star::lang::XEventListener
+#define XRESULTSET com::sun::star::sdbc::XResultSet
+#define SQLEXCEPTION com::sun::star::sdbc::SQLException
+#define XRESULTSETMETADATA com::sun::star::sdbc::XResultSetMetaData
+#define NUMBERED_SORTINGINFO com::sun::star::ucb::NumberedSortingInfo
+#define XANYCOMPAREFACTORY com::sun::star::ucb::XAnyCompareFactory
+
+#define RESULTSET_SERVICE_NAME "com.sun.star.ucb.SortedResultSet"
+
+//-----------------------------------------------------------------------------
+
+class SortedResultSet:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::ucb::XContentAccess,
+ public XRESULTSET,
+ public com::sun::star::sdbc::XRow,
+ public com::sun::star::sdbc::XCloseable,
+ public com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ public com::sun::star::beans::XPropertySet
+{
+ cppu::OInterfaceContainerHelper *mpDisposeEventListeners;
+ PropertyChangeListeners_Impl *mpPropChangeListeners;
+ PropertyChangeListeners_Impl *mpVetoChangeListeners;
+
+ REFERENCE < XRESULTSET > mxOriginal;
+ REFERENCE < XRESULTSET > mxOther;
+
+ SRSPropertySetInfo* mpPropSetInfo;
+ SortInfo* mpSortInfo;
+ osl::Mutex maMutex;
+ SortedEntryList maS2O; // maps the sorted entries to the original ones
+ SimpleList maO2S; // maps the original Entries to the sorted ones
+ SimpleList maModList; // keeps track of modified entries
+ long mnLastSort; // index of the last sorted entry;
+ long mnCurEntry; // index of the current entry
+ long mnCount; // total count of the elements
+ sal_Bool mbIsCopy;
+
+
+private:
+
+ long FindPos( SortListData *pEntry, long nStart, long nEnd )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ long Compare( SortListData *pOne,
+ SortListData *pTwo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ void BuildSortInfo( REFERENCE< XRESULTSET > aResult,
+ const SEQUENCE < NUMBERED_SORTINGINFO > &xSortInfo,
+ const REFERENCE< XANYCOMPAREFACTORY > &xCompFac );
+ long CompareImpl( REFERENCE < XRESULTSET > xResultOne,
+ REFERENCE < XRESULTSET > xResultTwo,
+ long nIndexOne, long nIndexTwo,
+ SortInfo* pSortInfo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ long CompareImpl( REFERENCE < XRESULTSET > xResultOne,
+ REFERENCE < XRESULTSET > xResultTwo,
+ long nIndexOne, long nIndexTwo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ void PropertyChanged( const PROPERTYCHANGEEVENT& rEvt );
+
+public:
+ SortedResultSet( REFERENCE< XRESULTSET > aResult );
+ ~SortedResultSet();
+
+ const SortedEntryList* GetS2OList() const { return &maS2O; }
+ const SimpleList* GetO2SList() const { return &maO2S; }
+ REFERENCE < XRESULTSET > GetResultSet() const { return mxOriginal; }
+ SortInfo* GetSortInfo() const { return mpSortInfo; }
+ long GetCount() const { return mnCount; }
+
+ void CopyData( SortedResultSet* pSource );
+ void Initialize( const SEQUENCE < NUMBERED_SORTINGINFO > &xSortInfo,
+ const REFERENCE< XANYCOMPAREFACTORY > &xCompFac );
+ void CheckProperties( long nOldCount, sal_Bool bWasFinal );
+
+ void InsertNew( long nPos, long nCount );
+ void SetChanged( long nPos, long nCount );
+ void Remove( long nPos, long nCount, EventList *pList );
+ void Move( long nPos, long nCount, long nOffset );
+
+ void ResortModified( EventList* pList );
+ void ResortNew( EventList* pList );
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose() throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ // XContentAccess
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString()
+ throw( RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier()
+ throw( RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent()
+ throw( RUNTIME_EXCEPTION );
+
+ // XResultSet
+ virtual sal_Bool SAL_CALL
+ next()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isAfterLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ beforeFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ afterLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ first()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ last()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Int32 SAL_CALL
+ getRow()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ absolute( sal_Int32 row )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ relative( sal_Int32 rows )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ previous()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ refreshRow()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowUpdated()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowInserted()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowDeleted()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::uno::XInterface > SAL_CALL
+ getStatement()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XRow
+ virtual sal_Bool SAL_CALL
+ wasNull() throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual rtl::OUString SAL_CALL
+ getString( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Bool SAL_CALL
+ getBoolean( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int8 SAL_CALL
+ getByte( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int16 SAL_CALL
+ getShort( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int32 SAL_CALL
+ getInt( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int64 SAL_CALL
+ getLong( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual float SAL_CALL
+ getFloat( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual double SAL_CALL
+ getDouble( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual REFERENCE<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual REFERENCE<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject( sal_Int32 columnIndex,
+ const REFERENCE<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XRef > SAL_CALL
+ getRef( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XClob > SAL_CALL
+ getClob( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XArray > SAL_CALL
+ getArray( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XCloseable
+ virtual void SAL_CALL
+ close()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XResultSetMetaDataSupplier
+ virtual REFERENCE< XRESULTSETMETADATA > SAL_CALL
+ getMetaData()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+
+ // XPropertySet
+ virtual REFERENCE<
+ com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Any& Value )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addPropertyChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XPropertyChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removePropertyChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XPropertyChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addVetoableChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XVetoableChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeVetoableChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+};
+
+#endif
+
diff --git a/ucb/source/sorter/srtrs.xml b/ucb/source/sorter/srtrs.xml
new file mode 100644
index 000000000000..51626a1e6acc
--- /dev/null
+++ b/ucb/source/sorter/srtrs.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ srtrs
+ </module-name>
+
+ <component-description>
+ <author>
+ Dirk Voelzke
+ </author>
+ <name>
+ com.sun.star.comp.ucb.SortedDynamicResultSetFactory
+ </name>
+ <description>
+ This component implements a factory for sorted Content Resultsets.
+ It can be used to sort resultsets obtained from UCB folder contents.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.SortedDynamicResultSetFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.CachedDynamicResultSetStubFactory
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.DataType </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSet </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentResultSetCapability </type>
+ <type> com.sun.star.ucb.ListActionType </type>
+ <type> com.sun.star.ucb.NumberedSortingInfo </type>
+ <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XSortedDynamicResultSetFactory </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.uno.XWeak </type>
+</module-description>
diff --git a/ucb/source/ucp/expand/makefile.mk b/ucb/source/ucp/expand/makefile.mk
new file mode 100644
index 000000000000..32de160318f2
--- /dev/null
+++ b/ucb/source/ucp/expand/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+PRJNAME = ucb
+UCPEXPAND_MAJOR = 1
+TARGET = ucpexpand$(UCPEXPAND_MAJOR).uno
+ENABLE_EXCEPTIONS = TRUE
+NO_BSYMBOLIC = TRUE
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+.IF "$(L10N_framework)"==""
+
+SLOFILES= \
+ $(SLO)$/ucpexpand.obj
+
+SHL1STDLIBS = \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1TARGET = $(TARGET)
+
+SHL1DEPN =
+SHL1IMPLIB = i$(TARGET)
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME = $(SHL1TARGET)
+
+.ENDIF # L10N_framework
+
+.INCLUDE : target.mk
diff --git a/ucb/source/ucp/expand/ucpexpand.cxx b/ucb/source/ucp/expand/ucpexpand.cxx
new file mode 100644
index 000000000000..710cf137ba06
--- /dev/null
+++ b/ucb/source/ucp/expand/ucpexpand.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "rtl/uri.hxx"
+#include "osl/mutex.hxx"
+#include "cppuhelper/compbase2.hxx"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/ucb/XContentProvider.hpp"
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand"
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define ARLEN(x) sizeof (x) / sizeof *(x)
+
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace
+{
+
+struct MutexHolder
+{
+ mutable ::osl::Mutex m_mutex;
+};
+
+typedef ::cppu::WeakComponentImplHelper2<
+ lang::XServiceInfo, ucb::XContentProvider > t_impl_helper;
+
+//==============================================================================
+class ExpandContentProviderImpl : protected MutexHolder, public t_impl_helper
+{
+ uno::Reference< util::XMacroExpander > m_xMacroExpander;
+ OUString expandUri(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const;
+
+protected:
+ inline void check() const;
+ virtual void SAL_CALL disposing();
+
+public:
+ inline ExpandContentProviderImpl(
+ uno::Reference< uno::XComponentContext > const & xComponentContext )
+ : t_impl_helper( m_mutex ),
+ m_xMacroExpander(
+ xComponentContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
+ uno::UNO_QUERY_THROW )
+ {}
+ virtual ~ExpandContentProviderImpl() throw ();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
+ throw (uno::RuntimeException);
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (uno::RuntimeException);
+
+ // XContentProvider
+ virtual uno::Reference< ucb::XContent > SAL_CALL queryContent(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
+ throw (ucb::IllegalIdentifierException, uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL compareContentIds(
+ uno::Reference< ucb::XContentIdentifier > const & xId1,
+ uno::Reference< ucb::XContentIdentifier > const & xId2 )
+ throw (uno::RuntimeException);
+};
+
+//______________________________________________________________________________
+inline void ExpandContentProviderImpl::check() const
+{
+ // xxx todo guard?
+// MutexGuard guard( m_mutex );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("expand content provider instance has "
+ "already been disposed!"),
+ static_cast< OWeakObject * >(
+ const_cast< ExpandContentProviderImpl * >(this) ) );
+ }
+}
+
+//______________________________________________________________________________
+ExpandContentProviderImpl::~ExpandContentProviderImpl() throw ()
+{
+}
+
+//______________________________________________________________________________
+void ExpandContentProviderImpl::disposing()
+{
+}
+
+//==============================================================================
+static uno::Reference< uno::XInterface > SAL_CALL create(
+ uno::Reference< uno::XComponentContext > const & xComponentContext )
+ SAL_THROW( (uno::Exception) )
+{
+ return static_cast< ::cppu::OWeakObject * >(
+ new ExpandContentProviderImpl( xComponentContext ) );
+}
+
+//==============================================================================
+static OUString SAL_CALL implName()
+{
+ return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider");
+}
+
+//==============================================================================
+static uno::Sequence< OUString > SAL_CALL supportedServices()
+{
+ OUString names [] = {
+ OUSTR("com.sun.star.ucb.ExpandContentProvider"),
+ OUSTR("com.sun.star.ucb.ContentProvider")
+ };
+ return uno::Sequence< OUString >( names, ARLEN(names) );
+}
+
+// XServiceInfo
+//______________________________________________________________________________
+OUString ExpandContentProviderImpl::getImplementationName()
+ throw (uno::RuntimeException)
+{
+ check();
+ return implName();
+}
+
+//______________________________________________________________________________
+uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
+ throw (uno::RuntimeException)
+{
+ check();
+ return supportedServices();
+}
+
+//______________________________________________________________________________
+sal_Bool ExpandContentProviderImpl::supportsService(
+ OUString const & serviceName )
+ throw (uno::RuntimeException)
+{
+// check();
+ uno::Sequence< OUString > supported_services( getSupportedServiceNames() );
+ OUString const * ar = supported_services.getConstArray();
+ for ( sal_Int32 pos = supported_services.getLength(); pos--; )
+ {
+ if (ar[ pos ].equals( serviceName ))
+ return true;
+ }
+ return false;
+}
+
+//______________________________________________________________________________
+OUString ExpandContentProviderImpl::expandUri(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const
+{
+ OUString uri( xIdentifier->getContentIdentifier() );
+ if (uri.compareToAscii(
+ RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ) != 0)
+ {
+ throw ucb::IllegalIdentifierException(
+ OUSTR("expected protocol " EXPAND_PROTOCOL "!"),
+ static_cast< OWeakObject * >(
+ const_cast< ExpandContentProviderImpl * >(this) ) );
+ }
+ // cut protocol
+ OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
+ // decode uric class chars
+ str = ::rtl::Uri::decode(
+ str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ return m_xMacroExpander->expandMacros( str );
+}
+
+// XContentProvider
+//______________________________________________________________________________
+uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
+ throw (ucb::IllegalIdentifierException, uno::RuntimeException)
+{
+ check();
+ OUString uri( expandUri( xIdentifier ) );
+
+ ::ucbhelper::Content ucb_content;
+ if (::ucbhelper::Content::create(
+ uri, uno::Reference< ucb::XCommandEnvironment >(), ucb_content ))
+ {
+ return ucb_content.get();
+ }
+ else
+ {
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//______________________________________________________________________________
+sal_Int32 ExpandContentProviderImpl::compareContentIds(
+ uno::Reference< ucb::XContentIdentifier > const & xId1,
+ uno::Reference< ucb::XContentIdentifier > const & xId2 )
+ throw (uno::RuntimeException)
+{
+ check();
+ try
+ {
+ OUString uri1( expandUri( xId1 ) );
+ OUString uri2( expandUri( xId2 ) );
+ return uri1.compareTo( uri2 );
+ }
+ catch (ucb::IllegalIdentifierException & exc)
+ {
+ (void) exc; // unused
+ OSL_ENSURE(
+ 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return -1;
+ }
+}
+
+static const ::cppu::ImplementationEntry s_entries [] =
+{
+ {
+ create,
+ implName,
+ supportedServices,
+ ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C"
+{
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return ::cppu::component_writeInfoHelper(
+ pServiceManager, pRegistryKey, s_entries );
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName,
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, s_entries );
+}
+
+}
diff --git a/ucb/source/ucp/file/bc.cxx b/ucb/source/ucp/file/bc.cxx
new file mode 100644
index 000000000000..b78e5d6e4890
--- /dev/null
+++ b/ucb/source/ucp/file/bc.cxx
@@ -0,0 +1,1409 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+
+#include "osl/diagnose.h"
+#include <com/sun/star/ucb/OpenMode.hpp>
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include <com/sun/star/ucb/ContentAction.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include "filglob.hxx"
+#include "filid.hxx"
+#include "filrow.hxx"
+#include "bc.hxx"
+#include "prov.hxx"
+#ifndef _FILERROR_HXX_
+#include "filerror.hxx"
+#endif
+#include "filinsreq.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+
+// PropertyListeners
+
+
+typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString >
+PropertyListeners_impl;
+
+class fileaccess::PropertyListeners
+ : public PropertyListeners_impl
+{
+public:
+ PropertyListeners( ::osl::Mutex& aMutex )
+ : PropertyListeners_impl( aMutex )
+ {
+ }
+};
+
+
+/****************************************************************************************/
+/* */
+/* BaseContent */
+/* */
+/****************************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////
+// Private Constructor for just inserted Contents
+
+BaseContent::BaseContent( shell* pMyShell,
+ const rtl::OUString& parentName,
+ sal_Bool bFolder )
+ : m_pMyShell( pMyShell ),
+ m_xContentIdentifier( 0 ),
+ m_aUncPath( parentName ),
+ m_bFolder( bFolder ),
+ m_nState( JustInserted ),
+ m_pDisposeEventListeners( 0 ),
+ m_pContentEventListeners( 0 ),
+ m_pPropertySetInfoChangeListeners( 0 ),
+ m_pPropertyListener( 0 )
+{
+ m_pMyShell->m_pProvider->acquire();
+ // No registering, since we have no name
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Constructor for full featured Contents
+
+BaseContent::BaseContent( shell* pMyShell,
+ const Reference< XContentIdentifier >& xContentIdentifier,
+ const rtl::OUString& aUncPath )
+ : m_pMyShell( pMyShell ),
+ m_xContentIdentifier( xContentIdentifier ),
+ m_aUncPath( aUncPath ),
+ m_bFolder( false ),
+ m_nState( FullFeatured ),
+ m_pDisposeEventListeners( 0 ),
+ m_pContentEventListeners( 0 ),
+ m_pPropertySetInfoChangeListeners( 0 ),
+ m_pPropertyListener( 0 )
+{
+ m_pMyShell->m_pProvider->acquire();
+ m_pMyShell->registerNotifier( m_aUncPath,this );
+ m_pMyShell->insertDefaultProperties( m_aUncPath );
+}
+
+
+BaseContent::~BaseContent( )
+{
+ if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) )
+ {
+ m_pMyShell->deregisterNotifier( m_aUncPath,this );
+ }
+ m_pMyShell->m_pProvider->release();
+
+ delete m_pDisposeEventListeners;
+ delete m_pContentEventListeners;
+ delete m_pPropertyListener;
+ delete m_pPropertySetInfoChangeListeners;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// XInterface
+//////////////////////////////////////////////////////////////////////////
+
+void SAL_CALL
+BaseContent::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+BaseContent::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+Any SAL_CALL
+BaseContent::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XComponent*, this ),
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( lang::XServiceInfo*, this ),
+ SAL_STATIC_CAST( XCommandProcessor*, this ),
+ SAL_STATIC_CAST( container::XChild*, this ),
+ SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ),
+ SAL_STATIC_CAST( beans::XPropertyContainer*, this ),
+ SAL_STATIC_CAST( XContentCreator*,this ),
+ SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ),
+ SAL_STATIC_CAST( XContent*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XComponent
+////////////////////////////////////////////////////////////////////////////////////////
+
+void SAL_CALL
+BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ! m_pDisposeEventListeners )
+ m_pDisposeEventListeners =
+ new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+
+void SAL_CALL
+BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+
+void SAL_CALL
+BaseContent::dispose()
+ throw( RuntimeException )
+{
+ lang::EventObject aEvt;
+ cppu::OInterfaceContainerHelper* pDisposeEventListeners;
+ cppu::OInterfaceContainerHelper* pContentEventListeners;
+ cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners;
+ PropertyListeners* pPropertyListener;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ aEvt.Source = static_cast< XContent* >( this );
+
+
+ pDisposeEventListeners =
+ m_pDisposeEventListeners, m_pDisposeEventListeners = 0;
+
+ pContentEventListeners =
+ m_pContentEventListeners, m_pContentEventListeners = 0;
+
+ pPropertySetInfoChangeListeners =
+ m_pPropertySetInfoChangeListeners,
+ m_pPropertySetInfoChangeListeners = 0;
+
+ pPropertyListener =
+ m_pPropertyListener, m_pPropertyListener = 0;
+ }
+
+ if ( pDisposeEventListeners && pDisposeEventListeners->getLength() )
+ pDisposeEventListeners->disposeAndClear( aEvt );
+
+ if ( pContentEventListeners && pContentEventListeners->getLength() )
+ pContentEventListeners->disposeAndClear( aEvt );
+
+ if( pPropertyListener )
+ pPropertyListener->disposeAndClear( aEvt );
+
+ if( pPropertySetInfoChangeListeners )
+ pPropertySetInfoChangeListeners->disposeAndClear( aEvt );
+
+ delete pDisposeEventListeners;
+ delete pContentEventListeners;
+ delete pPropertyListener;
+ delete pPropertySetInfoChangeListeners;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XServiceInfo
+//////////////////////////////////////////////////////////////////////////////////////////
+
+rtl::OUString SAL_CALL
+BaseContent::getImplementationName()
+ throw( RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" );
+}
+
+
+
+sal_Bool SAL_CALL
+BaseContent::supportsService( const rtl::OUString& ServiceName )
+ throw( RuntimeException)
+{
+ if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 )
+ return true;
+ else
+ return false;
+}
+
+
+
+Sequence< rtl::OUString > SAL_CALL
+BaseContent::getSupportedServiceNames()
+ throw( RuntimeException )
+{
+ Sequence< rtl::OUString > ret( 1 );
+ ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" );
+ return ret;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_10( BaseContent,
+ lang::XComponent,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ XCommandProcessor,
+ XContentCreator,
+ XContent,
+ container::XChild,
+ beans::XPropertiesChangeNotifier,
+ beans::XPropertyContainer,
+ beans::XPropertySetInfoChangeNotifier )
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XCommandProcessor
+//////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Int32 SAL_CALL
+BaseContent::createCommandIdentifier( void )
+ throw( RuntimeException )
+{
+ return m_pMyShell->getCommandId();
+}
+
+
+void SAL_CALL
+BaseContent::abort( sal_Int32 CommandId )
+ throw( RuntimeException )
+{
+ m_pMyShell->abort( CommandId );
+}
+
+
+Any SAL_CALL
+BaseContent::execute( const Command& aCommand,
+ sal_Int32 CommandId,
+ const Reference< XCommandEnvironment >& Environment )
+ throw( Exception,
+ CommandAbortedException,
+ RuntimeException )
+{
+ if( ! CommandId )
+ // A Command with commandid zero cannot be aborted
+ CommandId = createCommandIdentifier();
+
+ m_pMyShell->startTask( CommandId,
+ Environment );
+
+ Any aAny;
+
+ if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) ) // No exceptions
+ {
+ aAny <<= getPropertySetInfo( CommandId );
+ }
+ else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) ) // no exceptions
+ {
+ aAny <<= getCommandInfo();
+ }
+ else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) )
+ {
+ Sequence< beans::PropertyValue > sPropertyValues;
+
+ if( ! ( aCommand.Argument >>= sPropertyValues ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT );
+ else
+ aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself
+ }
+ else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) )
+ {
+ Sequence< beans::Property > ListOfRequestedProperties;
+
+ if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT );
+ else
+ aAny <<= getPropertyValues( CommandId,
+ ListOfRequestedProperties );
+ }
+ else if( ! aCommand.Name.compareToAscii( "open" ) )
+ {
+ OpenCommandArgument2 aOpenArgument;
+ if( ! ( aCommand.Argument >>= aOpenArgument ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_OPEN_ARGUMENT );
+ else
+ {
+ Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument );
+ if( result.is() )
+ aAny <<= result;
+ }
+ }
+ else if( ! aCommand.Name.compareToAscii( "delete" ) )
+ {
+ if( ! aCommand.Argument.has< sal_Bool >() )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_DELETE_ARGUMENT );
+ else
+ deleteContent( CommandId );
+ }
+ else if( ! aCommand.Name.compareToAscii( "transfer" ) )
+ {
+ TransferInfo aTransferInfo;
+ if( ! ( aCommand.Argument >>= aTransferInfo ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_TRANSFER_ARGUMENT );
+ else
+ transfer( CommandId, aTransferInfo );
+ }
+ else if( ! aCommand.Name.compareToAscii( "insert" ) )
+ {
+ InsertCommandArgument aInsertArgument;
+ if( ! ( aCommand.Argument >>= aInsertArgument ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_INSERT_ARGUMENT );
+ else
+ insert( CommandId,aInsertArgument );
+ }
+ else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) )
+ {
+ Sequence< beans::Property > seq(1);
+ seq[0] = beans::Property(
+ rtl::OUString::createFromAscii("CasePreservingURL"),
+ -1,
+ getCppuType( static_cast< sal_Bool* >(0) ),
+ 0 );
+ Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq );
+ rtl::OUString CasePreservingURL = xRow->getString(1);
+ if(!xRow->wasNull())
+ aAny <<= CasePreservingURL;
+ }
+ else if( ! aCommand.Name.compareToAscii( "createNewContent" ) )
+ {
+ ucb::ContentInfo aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ m_pMyShell->installError( CommandId,
+ TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT );
+ else
+ aAny <<= createNewContent( aArg );
+ }
+ else
+ m_pMyShell->installError( CommandId,
+ TASKHANDLER_UNSUPPORTED_COMMAND );
+
+
+ // This is the only function allowed to throw an exception
+ endTask( CommandId );
+
+ return aAny;
+}
+
+
+
+void SAL_CALL
+BaseContent::addPropertiesChangeListener(
+ const Sequence< rtl::OUString >& PropertyNames,
+ const Reference< beans::XPropertiesChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ if( ! Listener.is() )
+ return;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( ! m_pPropertyListener )
+ m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex );
+
+
+ if( PropertyNames.getLength() == 0 )
+ m_pPropertyListener->addInterface( rtl::OUString(),Listener );
+ else
+ {
+ Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath );
+ for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
+ if( xProp->hasPropertyByName( PropertyNames[i] ) )
+ m_pPropertyListener->addInterface( PropertyNames[i],Listener );
+ }
+}
+
+
+void SAL_CALL
+BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames,
+ const Reference< beans::XPropertiesChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ if( ! Listener.is() )
+ return;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( ! m_pPropertyListener )
+ return;
+
+ for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i )
+ m_pPropertyListener->removeInterface( PropertyNames[i],Listener );
+
+ m_pPropertyListener->removeInterface( rtl::OUString(), Listener );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// XContent
+/////////////////////////////////////////////////////////////////////////////////////////
+
+Reference< ucb::XContentIdentifier > SAL_CALL
+BaseContent::getIdentifier()
+ throw( RuntimeException )
+{
+ return m_xContentIdentifier;
+}
+
+
+rtl::OUString SAL_CALL
+BaseContent::getContentType()
+ throw( RuntimeException )
+{
+ if( !( m_nState & Deleted ) )
+ {
+ if( m_nState & JustInserted )
+ {
+ if ( m_bFolder )
+ return m_pMyShell->FolderContentType;
+ else
+ return m_pMyShell->FileContentType;
+ }
+ else
+ {
+ try
+ {
+ // Who am I ?
+ Sequence< beans::Property > seq(1);
+ seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
+ -1,
+ getCppuType( static_cast< sal_Bool* >(0) ),
+ 0 );
+ Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
+ sal_Bool IsDocument = xRow->getBoolean( 1 );
+
+ if ( !xRow->wasNull() )
+ {
+ if ( IsDocument )
+ return m_pMyShell->FileContentType;
+ else
+ return m_pMyShell->FolderContentType;
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ "BaseContent::getContentType - Property value was null!" );
+ }
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ OSL_ENSURE( false,
+ "BaseContent::getContentType - Caught SQLException!" );
+ }
+ }
+ }
+
+ return rtl::OUString();
+}
+
+
+
+void SAL_CALL
+BaseContent::addContentEventListener(
+ const Reference< XContentEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ! m_pContentEventListeners )
+ m_pContentEventListeners =
+ new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+
+
+ m_pContentEventListeners->addInterface( Listener );
+}
+
+
+void SAL_CALL
+BaseContent::removeContentEventListener(
+ const Reference< XContentEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pContentEventListeners )
+ m_pContentEventListeners->removeInterface( Listener );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// XPropertyContainer
+////////////////////////////////////////////////////////////////////////////////
+
+
+void SAL_CALL
+BaseContent::addProperty(
+ const rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const Any& DefaultValue )
+ throw( beans::PropertyExistException,
+ beans::IllegalTypeException,
+ lang::IllegalArgumentException,
+ RuntimeException)
+{
+ if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() )
+ {
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ }
+
+ m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes );
+}
+
+
+void SAL_CALL
+BaseContent::removeProperty(
+ const rtl::OUString& Name )
+ throw( beans::UnknownPropertyException,
+ beans::NotRemoveableException,
+ RuntimeException)
+{
+
+ if( m_nState & Deleted )
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_pMyShell->deassociate( m_aUncPath, Name );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// XContentCreator
+////////////////////////////////////////////////////////////////////////////////
+
+Sequence< ContentInfo > SAL_CALL
+BaseContent::queryCreatableContentsInfo(
+ void )
+ throw( RuntimeException )
+{
+ return m_pMyShell->queryCreatableContentsInfo();
+}
+
+
+Reference< XContent > SAL_CALL
+BaseContent::createNewContent(
+ const ContentInfo& Info )
+ throw( RuntimeException )
+{
+ // Check type.
+ if ( !Info.Type.getLength() )
+ return Reference< XContent >();
+
+ sal_Bool bFolder
+ = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 );
+ if ( !bFolder )
+ {
+ if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 )
+ {
+ // Neither folder nor file to create!
+ return Reference< XContent >();
+ }
+ }
+
+ // Who am I ?
+ sal_Bool IsDocument = false;
+
+ try
+ {
+ Sequence< beans::Property > seq(1);
+ seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
+ -1,
+ getCppuType( static_cast< sal_Bool* >(0) ),
+ 0 );
+ Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
+ IsDocument = xRow->getBoolean( 1 );
+
+ if ( xRow->wasNull() )
+ {
+ IsDocument = false;
+// OSL_ENSURE( false,
+// "BaseContent::createNewContent - Property value was null!" );
+// return Reference< XContent >();
+ }
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ OSL_ENSURE( false,
+ "BaseContent::createNewContent - Caught SQLException!" );
+ return Reference< XContent >();
+ }
+
+ rtl::OUString dstUncPath;
+
+ if( IsDocument )
+ {
+ // KSO: Why is a document a XContentCreator? This is quite unusual.
+ dstUncPath = getParentName( m_aUncPath );
+ }
+ else
+ dstUncPath = m_aUncPath;
+
+ BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder );
+ return Reference< XContent >( p );
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// XPropertySetInfoChangeNotifier
+////////////////////////////////////////////////////////////////////////////////
+
+
+void SAL_CALL
+BaseContent::addPropertySetInfoChangeListener(
+ const Reference< beans::XPropertySetInfoChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ if( ! m_pPropertySetInfoChangeListeners )
+ m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+
+ m_pPropertySetInfoChangeListeners->addInterface( Listener );
+}
+
+
+void SAL_CALL
+BaseContent::removePropertySetInfoChangeListener(
+ const Reference< beans::XPropertySetInfoChangeListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( m_pPropertySetInfoChangeListeners )
+ m_pPropertySetInfoChangeListeners->removeInterface( Listener );
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// XChild
+////////////////////////////////////////////////////////////////////////////////
+
+Reference< XInterface > SAL_CALL
+BaseContent::getParent(
+ void )
+ throw( RuntimeException )
+{
+ rtl::OUString ParentUnq = getParentName( m_aUncPath );
+ rtl::OUString ParentUrl;
+
+
+ sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl );
+ if( err )
+ return Reference< XInterface >( 0 );
+
+ FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq );
+ Reference< XContentIdentifier > Identifier( p );
+
+ try
+ {
+ Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier );
+ return Reference<XInterface>(content,UNO_QUERY);
+ }
+ catch( IllegalIdentifierException )
+ {
+ return Reference< XInterface >();
+ }
+}
+
+
+void SAL_CALL
+BaseContent::setParent(
+ const Reference< XInterface >& )
+ throw( lang::NoSupportException,
+ RuntimeException)
+{
+ throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Private Methods
+//////////////////////////////////////////////////////////////////////////////////////////
+
+
+Reference< XCommandInfo > SAL_CALL
+BaseContent::getCommandInfo()
+ throw( RuntimeException )
+{
+ if( m_nState & Deleted )
+ return Reference< XCommandInfo >();
+
+ return m_pMyShell->info_c();
+}
+
+
+Reference< beans::XPropertySetInfo > SAL_CALL
+BaseContent::getPropertySetInfo(
+ sal_Int32 )
+ throw( RuntimeException )
+{
+ if( m_nState & Deleted )
+ return Reference< beans::XPropertySetInfo >();
+
+ return m_pMyShell->info_p( m_aUncPath );
+}
+
+
+
+
+Reference< sdbc::XRow > SAL_CALL
+BaseContent::getPropertyValues(
+ sal_Int32 nMyCommandIdentifier,
+ const Sequence< beans::Property >& PropertySet )
+ throw( RuntimeException )
+{
+ sal_Int32 nProps = PropertySet.getLength();
+ if ( !nProps )
+ return Reference< sdbc::XRow >();
+
+ if( m_nState & Deleted )
+ {
+ Sequence< Any > aValues( nProps );
+ return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) );
+ }
+
+ if( m_nState & JustInserted )
+ {
+ Sequence< Any > aValues( nProps );
+ Any* pValues = aValues.getArray();
+
+ const beans::Property* pProps = PropertySet.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nProps; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+ Any& rValue = pValues[ n ];
+
+ if( rProp.Name.compareToAscii( "ContentType" ) == 0 )
+ {
+ rValue <<= m_bFolder ? m_pMyShell->FolderContentType
+ : m_pMyShell->FileContentType;
+ }
+ else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 )
+ {
+ rValue <<= m_bFolder;
+ }
+ else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 )
+ {
+ rValue <<= sal_Bool( !m_bFolder );
+ }
+ }
+
+ return Reference< sdbc::XRow >(
+ new XRow_impl( m_pMyShell, aValues ) );
+ }
+
+ return m_pMyShell->getv( nMyCommandIdentifier,
+ m_aUncPath,
+ PropertySet );
+}
+
+
+Sequence< Any > SAL_CALL
+BaseContent::setPropertyValues(
+ sal_Int32 nMyCommandIdentifier,
+ const Sequence< beans::PropertyValue >& Values )
+ throw()
+{
+ if( m_nState & Deleted )
+ { // To do
+ return Sequence< Any >( Values.getLength() );
+ }
+
+ const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" );
+
+ // Special handling for files which have to be inserted
+ if( m_nState & JustInserted )
+ {
+ for( sal_Int32 i = 0; i < Values.getLength(); ++i )
+ {
+ if( Values[i].Name == Title )
+ {
+ rtl::OUString NewTitle;
+ if( Values[i].Value >>= NewTitle )
+ {
+ if ( m_nState & NameForInsertionSet )
+ {
+ // User wants to set another Title before "insert".
+ // m_aUncPath contains previous own URI.
+
+ sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' );
+ bool bTrailingSlash = false;
+ if ( nLastSlash == m_aUncPath.getLength() - 1 )
+ {
+ bTrailingSlash = true;
+ nLastSlash
+ = m_aUncPath.lastIndexOf( '/', nLastSlash );
+ }
+
+ OSL_ENSURE( nLastSlash != -1,
+ "BaseContent::setPropertyValues: "
+ "Invalid URL!" );
+
+ rtl::OUStringBuffer aBuf(
+ m_aUncPath.copy( 0, nLastSlash + 1 ) );
+
+ if ( NewTitle.getLength() > 0 )
+ {
+ aBuf.append( NewTitle );
+ if ( bTrailingSlash )
+ aBuf.append( sal_Unicode( '/' ) );
+ }
+ else
+ {
+ m_nState &= ~NameForInsertionSet;
+ }
+
+ m_aUncPath = aBuf.makeStringAndClear();
+ }
+ else
+ {
+ if ( NewTitle.getLength() > 0 )
+ {
+ // Initial Title before "insert".
+ // m_aUncPath contains parent's URI.
+
+ if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
+ m_aUncPath += rtl::OUString::createFromAscii("/");
+
+ m_aUncPath += rtl::Uri::encode( NewTitle,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ m_nState |= NameForInsertionSet;
+ }
+ }
+ }
+ }
+ }
+
+ return Sequence< Any >( Values.getLength() );
+ }
+ else
+ {
+ Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title
+ Values );
+
+ // Special handling Title: Setting Title is equivalent to a renaming of the underlying file
+ for( sal_Int32 i = 0; i < Values.getLength(); ++i )
+ {
+ if( Values[i].Name != Title )
+ continue; // handled by setv
+
+ rtl::OUString NewTitle;
+ if( !( Values[i].Value >>= NewTitle ) )
+ {
+ ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ break;
+ }
+ else if( ! NewTitle.getLength() )
+ {
+ ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ break;
+ }
+
+
+ rtl::OUString aDstName = getParentName( m_aUncPath );
+ if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 )
+ aDstName += rtl::OUString::createFromAscii("/");
+
+ aDstName += rtl::Uri::encode( NewTitle,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+
+ m_pMyShell->move( nMyCommandIdentifier, // move notifies the childs also;
+ m_aUncPath,
+ aDstName,
+ NameClash::KEEP );
+
+ try
+ {
+ endTask( nMyCommandIdentifier );
+ }
+ catch( const Exception& e )
+ {
+ ret[i] <<= e;
+ }
+
+ // NameChanges come back trough a ContentEvent
+ break; // only handling Title
+ } // end for
+
+ return ret;
+ }
+}
+
+
+
+Reference< XDynamicResultSet > SAL_CALL
+BaseContent::open(
+ sal_Int32 nMyCommandIdentifier,
+ const OpenCommandArgument2& aCommandArgument )
+ throw()
+{
+ Reference< XDynamicResultSet > retValue( 0 );
+
+ if( ( m_nState & Deleted ) )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND );
+ }
+ else if( m_nState & JustInserted )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND );
+ }
+ else
+ {
+ if( aCommandArgument.Mode == OpenMode::DOCUMENT ||
+ aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE )
+
+ {
+ Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY );
+ if( outputStream.is() )
+ {
+ m_pMyShell->page( nMyCommandIdentifier,
+ m_aUncPath,
+ outputStream );
+ }
+
+ sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE );
+
+ Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY );
+ if( activeDataSink.is() )
+ {
+ activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier,
+ m_aUncPath,
+ bLock ) );
+ }
+
+ Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY );
+ if( activeDataStreamer.is() )
+ {
+ activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier,
+ m_aUncPath,
+ bLock ) );
+ }
+ }
+ else if ( aCommandArgument.Mode == OpenMode::ALL ||
+ aCommandArgument.Mode == OpenMode::FOLDERS ||
+ aCommandArgument.Mode == OpenMode::DOCUMENTS )
+ {
+ retValue = m_pMyShell->ls( nMyCommandIdentifier,
+ m_aUncPath,
+ aCommandArgument.Mode,
+ aCommandArgument.Properties,
+ aCommandArgument.SortingInfo );
+ }
+// else if( aCommandArgument.Mode ==
+// OpenMode::DOCUMENT_SHARE_DENY_NONE ||
+// aCommandArgument.Mode ==
+// OpenMode::DOCUMENT_SHARE_DENY_WRITE )
+// m_pMyShell->installError( nMyCommandIdentifier,
+// TASKHANDLING_UNSUPPORTED_OPEN_MODE,
+// aCommandArgument.Mode);
+ else
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_UNSUPPORTED_OPEN_MODE,
+ aCommandArgument.Mode);
+ }
+
+ return retValue;
+}
+
+
+
+void SAL_CALL
+BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier )
+ throw()
+{
+ if( m_nState & Deleted )
+ return;
+
+ if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nState |= Deleted;
+ }
+}
+
+
+
+void SAL_CALL
+BaseContent::transfer( sal_Int32 nMyCommandIdentifier,
+ const TransferInfo& aTransferInfo )
+ throw()
+{
+ if( m_nState & Deleted )
+ return;
+
+ if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_TRANSFER_INVALIDSCHEME );
+ return;
+ }
+
+ rtl::OUString srcUnc;
+ if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_TRANSFER_INVALIDURL );
+ return;
+ }
+
+ rtl::OUString srcUncPath = srcUnc;
+
+ // Determine the new title !
+ rtl::OUString NewTitle;
+ if( aTransferInfo.NewTitle.getLength() )
+ NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ else
+ NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) );
+
+ // Is destination a document or a folder ?
+ Sequence< beans::Property > seq(1);
+ seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
+ -1,
+ getCppuType( static_cast< sal_Bool* >(0) ),
+ 0 );
+ Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq );
+ sal_Bool IsDocument = xRow->getBoolean( 1 );
+ if( xRow->wasNull() )
+ { // Destination file type could not be determined
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_TRANSFER_DESTFILETYPE );
+ return;
+ }
+
+ rtl::OUString dstUncPath;
+ if( IsDocument )
+ { // as sibling
+ sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') );
+ dstUncPath = m_aUncPath.copy(0,lastSlash );
+ }
+ else
+ // as child
+ dstUncPath = m_aUncPath;
+
+ dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle );
+
+ sal_Int32 NameClash = aTransferInfo.NameClash;
+
+ if( aTransferInfo.MoveData )
+ m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
+ else
+ m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash );
+}
+
+
+
+
+void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier,
+ const InsertCommandArgument& aInsertArgument )
+ throw()
+{
+ if( m_nState & FullFeatured )
+ {
+ m_pMyShell->write( nMyCommandIdentifier,
+ m_aUncPath,
+ aInsertArgument.ReplaceExisting,
+ aInsertArgument.Data );
+ return;
+ }
+
+ if( ! ( m_nState & JustInserted ) )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND );
+ return;
+ }
+
+ // Inserts the content, which has the flag m_bIsFresh
+
+ if( ! m_nState & NameForInsertionSet )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_NONAMESET_INSERT_COMMAND );
+ return;
+ }
+
+ // Inserting a document or a file?
+ sal_Bool bDocument = false;
+
+ Sequence< beans::Property > seq(1);
+ seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"),
+ -1,
+ getCppuType( static_cast< sal_Bool* >(0) ),
+ 0 );
+
+ Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq );
+
+ bool contentTypeSet = true; // is set to false, if contentType not set
+ try
+ {
+ bDocument = xRow->getBoolean( 1 );
+ if( xRow->wasNull() )
+ contentTypeSet = false;
+
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ OSL_ENSURE( false,
+ "BaseContent::insert - Caught SQLException!" );
+ contentTypeSet = false;
+ }
+
+ if( ! contentTypeSet )
+ {
+ m_pMyShell->installError( nMyCommandIdentifier,
+ TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND );
+ return;
+ }
+
+
+ sal_Bool success = false;
+ if( bDocument )
+ success = m_pMyShell->mkfil( nMyCommandIdentifier,
+ m_aUncPath,
+ aInsertArgument.ReplaceExisting,
+ aInsertArgument.Data );
+ else
+ {
+ while( ! success )
+ {
+ success = m_pMyShell->mkdir( nMyCommandIdentifier,
+ m_aUncPath,
+ aInsertArgument.ReplaceExisting );
+ if( success )
+ break;
+
+ XInteractionRequestImpl *aRequestImpl =
+ new XInteractionRequestImpl(
+ rtl::Uri::decode(
+ getTitle(m_aUncPath),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8),
+ (cppu::OWeakObject*)this,
+ m_pMyShell,nMyCommandIdentifier);
+ uno::Reference< task::XInteractionRequest > aReq( aRequestImpl );
+
+ m_pMyShell->handleTask( nMyCommandIdentifier,aReq );
+ if( aRequestImpl->aborted() ||
+ !aRequestImpl->newName().getLength() )
+ // means aborting
+ break;
+
+ // determine new uncpath
+ m_pMyShell->clearError( nMyCommandIdentifier );
+ m_aUncPath = getParentName( m_aUncPath );
+ if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 )
+ m_aUncPath += rtl::OUString::createFromAscii("/");
+
+ m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ }
+ }
+
+ if ( ! success )
+ return;
+
+ FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath );
+ m_xContentIdentifier = Reference< XContentIdentifier >( p );
+
+ m_pMyShell->registerNotifier( m_aUncPath,this );
+ m_pMyShell->insertDefaultProperties( m_aUncPath );
+
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nState = FullFeatured;
+}
+
+
+
+void SAL_CALL BaseContent::endTask( sal_Int32 CommandId )
+{
+ // This is the only function allowed to throw an exception
+ m_pMyShell->endTask( CommandId,m_aUncPath,this );
+}
+
+
+
+ContentEventNotifier*
+BaseContent::cDEL( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ m_nState |= Deleted;
+
+ ContentEventNotifier* p;
+ if( m_pContentEventListeners )
+ p = new ContentEventNotifier( m_pMyShell,
+ this,
+ m_xContentIdentifier,
+ m_pContentEventListeners->getElements() );
+ else
+ p = 0;
+
+ return p;
+}
+
+
+ContentEventNotifier*
+BaseContent::cEXC( const rtl::OUString aNewName )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ Reference< XContentIdentifier > xOldRef = m_xContentIdentifier;
+ m_aUncPath = aNewName;
+ FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName );
+ m_xContentIdentifier = Reference< XContentIdentifier >( pp );
+
+ ContentEventNotifier* p = 0;
+ if( m_pContentEventListeners )
+ p = new ContentEventNotifier( m_pMyShell,
+ this,
+ m_xContentIdentifier,
+ xOldRef,
+ m_pContentEventListeners->getElements() );
+
+ return p;
+}
+
+
+ContentEventNotifier*
+BaseContent::cCEL( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ ContentEventNotifier* p = 0;
+ if( m_pContentEventListeners )
+ p = new ContentEventNotifier( m_pMyShell,
+ this,
+ m_xContentIdentifier,
+ m_pContentEventListeners->getElements() );
+
+ return p;
+}
+
+PropertySetInfoChangeNotifier*
+BaseContent::cPSL( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ PropertySetInfoChangeNotifier* p = 0;
+ if( m_pPropertySetInfoChangeListeners )
+ p = new PropertySetInfoChangeNotifier( m_pMyShell,
+ this,
+ m_xContentIdentifier,
+ m_pPropertySetInfoChangeListeners->getElements() );
+
+ return p;
+}
+
+
+
+PropertyChangeNotifier*
+BaseContent::cPCL( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ Sequence< rtl::OUString > seqNames;
+
+ if( m_pPropertyListener )
+ seqNames = m_pPropertyListener->getContainedTypes();
+
+ PropertyChangeNotifier* p = 0;
+
+ sal_Int32 length = seqNames.getLength();
+
+ if( length )
+ {
+ ListenerMap* listener = new ListenerMap();
+ for( sal_Int32 i = 0; i < length; ++i )
+ {
+ (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements();
+ }
+
+ p = new PropertyChangeNotifier( m_pMyShell,
+ this,
+ m_xContentIdentifier,
+ listener );
+ }
+
+ return p;
+}
+
+
+rtl::OUString BaseContent::getKey( void )
+{
+ return m_aUncPath;
+}
diff --git a/ucb/source/ucp/file/bc.hxx b/ucb/source/ucp/file/bc.hxx
new file mode 100644
index 000000000000..2163758bfffc
--- /dev/null
+++ b/ucb/source/ucp/file/bc.hxx
@@ -0,0 +1,353 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _BC_HXX_
+#define _BC_HXX_
+
+#include "osl/mutex.hxx"
+#include "rtl/ustring.hxx"
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#ifndef _COM_SUN_STAR_UCB_XRESULTSET_HPP_
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#endif
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertySetInfoChangeNotifier.hpp>
+#include <com/sun/star/beans/XPropertySetInfoChangeListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#ifndef _COM_SUN_STAR_UCB_SHELL_HXX_
+#include "shell.hxx"
+#endif
+
+
+namespace fileaccess {
+
+ class PropertyListeners;
+ class shell;
+ class FileProvider;
+
+ class BaseContent:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XCommandProcessor,
+ public com::sun::star::beans::XPropertiesChangeNotifier,
+ public com::sun::star::beans::XPropertyContainer,
+ public com::sun::star::beans::XPropertySetInfoChangeNotifier,
+ public com::sun::star::ucb::XContentCreator,
+ public com::sun::star::container::XChild,
+ public com::sun::star::ucb::XContent,
+ public fileaccess::Notifier // implementation class
+ {
+ private:
+
+ // A special creator for inserted contents; Creates an ugly object
+ BaseContent( shell* pMyShell,
+ const rtl::OUString& parentName,
+ sal_Bool bFolder );
+
+ public:
+ BaseContent(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xContentIdentifier,
+ const rtl::OUString& aUnqPath );
+
+ virtual ~BaseContent();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addEventListener(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XCommandProcessor
+ virtual sal_Int32 SAL_CALL
+ createCommandIdentifier(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute(
+ const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ abort(
+ sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XContent
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ getIdentifier(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getContentType(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addContentEventListener(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeContentEventListener(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XPropertiesChangeNotifier
+
+ virtual void SAL_CALL
+ addPropertiesChangeListener(
+ const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removePropertiesChangeListener( const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XPropertyContainer
+
+ virtual void SAL_CALL
+ addProperty(
+ const rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const com::sun::star::uno::Any& DefaultValue )
+ throw( com::sun::star::beans::PropertyExistException,
+ com::sun::star::beans::IllegalTypeException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeProperty(
+ const rtl::OUString& Name )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::NotRemoveableException,
+ com::sun::star::uno::RuntimeException );
+
+ // XPropertySetInfoChangeNotifier
+
+ virtual void SAL_CALL
+ addPropertySetInfoChangeListener(
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removePropertySetInfoChangeListener(
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfoChangeListener >& Listener )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XContentCreator
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent(
+ const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XChild
+ virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ getParent(
+ void ) throw( com::sun::star::uno::RuntimeException );
+
+ // Not supported
+ virtual void SAL_CALL
+ setParent( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& Parent )
+ throw( com::sun::star::lang::NoSupportException,
+ com::sun::star::uno::RuntimeException);
+
+
+ // Notifier
+
+ ContentEventNotifier* cDEL( void );
+ ContentEventNotifier* cEXC( const rtl::OUString aNewName );
+ ContentEventNotifier* cCEL( void );
+ PropertySetInfoChangeNotifier* cPSL( void );
+ PropertyChangeNotifier* cPCL( void );
+ rtl::OUString getKey( void );
+
+ private:
+ // Data members
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xContentIdentifier;
+ rtl::OUString m_aUncPath;
+
+ enum state { NameForInsertionSet = 1,
+ JustInserted = 2,
+ Deleted = 4,
+ FullFeatured = 8,
+ Connected = 16 };
+ sal_Bool m_bFolder;
+ sal_uInt16 m_nState;
+
+ osl::Mutex m_aMutex;
+
+ osl::Mutex m_aEventListenerMutex;
+ cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
+ cppu::OInterfaceContainerHelper* m_pContentEventListeners;
+ cppu::OInterfaceContainerHelper* m_pPropertySetInfoChangeListeners;
+ PropertyListeners* m_pPropertyListener;
+
+
+ // Private Methods
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo > SAL_CALL
+ getCommandInfo()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo(
+ sal_Int32 nMyCommandIdentifier )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL
+ getPropertyValues(
+ sal_Int32 nMyCommandIdentifier,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& PropertySet )
+ throw( com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any > SAL_CALL
+ setPropertyValues(
+ sal_Int32 nMyCommandIdentifier,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& Values )
+ throw( );
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > SAL_CALL
+ open(
+ sal_Int32 nMyCommandIdentifier,
+ const com::sun::star::ucb::OpenCommandArgument2& aCommandArgument )
+ throw();
+
+ void SAL_CALL
+ deleteContent( sal_Int32 nMyCommandIdentifier )
+ throw();
+
+
+ void SAL_CALL
+ transfer( sal_Int32 nMyCommandIdentifier,
+ const com::sun::star::ucb::TransferInfo& aTransferInfo )
+ throw();
+
+ void SAL_CALL
+ insert( sal_Int32 nMyCommandIdentifier,
+ const com::sun::star::ucb::InsertCommandArgument& aInsertArgument )
+ throw();
+
+ void SAL_CALL endTask( sal_Int32 CommandId );
+
+ friend class ContentEventNotifier;
+ };
+
+} // end namespace fileaccess
+
+#endif
+
diff --git a/ucb/source/ucp/file/exports2.dxp b/ucb/source/ucp/file/exports2.dxp
new file mode 100644
index 000000000000..6c42314f228b
--- /dev/null
+++ b/ucb/source/ucp/file/exports2.dxp
@@ -0,0 +1,9 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
+
+_ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE
+_ZTIN3com3sun4star3ucb22InteractiveIOExceptionE
+_ZTIN3com3sun4star4task28ClassifiedInteractionRequestE
+_ZTIN3com3sun4star3ucb18NameClashExceptionE
+_ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE
diff --git a/ucb/source/ucp/file/filcmd.cxx b/ucb/source/ucp/file/filcmd.cxx
new file mode 100644
index 000000000000..776482957c1e
--- /dev/null
+++ b/ucb/source/ucp/file/filcmd.cxx
@@ -0,0 +1,141 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filcmd.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+XCommandInfo_impl::XCommandInfo_impl( shell* pMyShell )
+ : m_pMyShell( pMyShell ),
+ m_xProvider( pMyShell->m_pProvider )
+{
+}
+
+XCommandInfo_impl::~XCommandInfo_impl()
+{
+}
+
+
+
+void SAL_CALL
+XCommandInfo_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XCommandInfo_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+uno::Any SAL_CALL
+XCommandInfo_impl::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( XCommandInfo*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+uno::Sequence< CommandInfo > SAL_CALL
+XCommandInfo_impl::getCommands(
+ void )
+ throw( uno::RuntimeException )
+{
+ return m_pMyShell->m_sCommandInfo;
+}
+
+
+CommandInfo SAL_CALL
+XCommandInfo_impl::getCommandInfoByName(
+ const rtl::OUString& aName )
+ throw( UnsupportedCommandException,
+ uno::RuntimeException)
+{
+ for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); i++ )
+ if( m_pMyShell->m_sCommandInfo[i].Name == aName )
+ return m_pMyShell->m_sCommandInfo[i];
+
+ throw UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+CommandInfo SAL_CALL
+XCommandInfo_impl::getCommandInfoByHandle(
+ sal_Int32 Handle )
+ throw( UnsupportedCommandException,
+ uno::RuntimeException )
+{
+ for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i )
+ if( m_pMyShell->m_sCommandInfo[i].Handle == Handle )
+ return m_pMyShell->m_sCommandInfo[i];
+
+ throw UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+sal_Bool SAL_CALL
+XCommandInfo_impl::hasCommandByName(
+ const rtl::OUString& aName )
+ throw( uno::RuntimeException )
+{
+ for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i )
+ if( m_pMyShell->m_sCommandInfo[i].Name == aName )
+ return true;
+
+ return false;
+}
+
+
+sal_Bool SAL_CALL
+XCommandInfo_impl::hasCommandByHandle(
+ sal_Int32 Handle )
+ throw( uno::RuntimeException )
+{
+ for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i )
+ if( m_pMyShell->m_sCommandInfo[i].Handle == Handle )
+ return true;
+
+ return false;
+}
diff --git a/ucb/source/ucp/file/filcmd.hxx b/ucb/source/ucp/file/filcmd.hxx
new file mode 100644
index 000000000000..6a6725bfcb17
--- /dev/null
+++ b/ucb/source/ucp/file/filcmd.hxx
@@ -0,0 +1,108 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILCMD_HXX_
+#define _FILCMD_HXX_
+
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+
+
+namespace fileaccess {
+
+
+ // forward
+ class shell;
+
+
+ class XCommandInfo_impl
+ : public cppu::OWeakObject,
+ public com::sun::star::ucb::XCommandInfo
+ {
+ public:
+
+ XCommandInfo_impl( shell* pMyShell );
+
+ virtual ~XCommandInfo_impl();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ // XCommandInfo
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > SAL_CALL
+ getCommands(
+ void )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::ucb::CommandInfo SAL_CALL
+ getCommandInfoByName(
+ const rtl::OUString& Name )
+ throw( com::sun::star::ucb::UnsupportedCommandException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::ucb::CommandInfo SAL_CALL
+ getCommandInfoByHandle(
+ sal_Int32 Handle )
+ throw( com::sun::star::ucb::UnsupportedCommandException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ hasCommandByName(
+ const rtl::OUString& Name )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ hasCommandByHandle(
+ sal_Int32 Handle )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ private:
+
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider;
+ };
+
+}
+
+#endif
diff --git a/ucb/source/ucp/file/filerror.hxx b/ucb/source/ucp/file/filerror.hxx
new file mode 100644
index 000000000000..35b0d8ae5ce8
--- /dev/null
+++ b/ucb/source/ucp/file/filerror.hxx
@@ -0,0 +1,118 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILERROR_HXX_
+
+namespace fileaccess {
+
+// Error codes used to deliver the resulting exceptions
+#define LOWEST_FREE_ERROR 72
+
+#define TASKHANDLER_NO_ERROR 0
+#define TASKHANDLER_UNSUPPORTED_COMMAND 1
+#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT 2
+#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT 3
+#define TASKHANDLING_WRONG_OPEN_ARGUMENT 4
+#define TASKHANDLING_WRONG_DELETE_ARGUMENT 5
+#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT 6
+#define TASKHANDLING_WRONG_INSERT_ARGUMENT 7
+#define TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT 8
+#define TASKHANDLING_UNSUPPORTED_OPEN_MODE 9
+
+#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND 10
+#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND 11
+
+#define TASKHANDLING_OPEN_FILE_FOR_PAGING 12
+#define TASKHANDLING_NOTCONNECTED_FOR_PAGING 13
+#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING 14
+#define TASKHANDLING_IOEXCEPTION_FOR_PAGING 15
+#define TASKHANDLING_READING_FILE_FOR_PAGING 16
+
+#define TASKHANDLING_OPEN_FOR_INPUTSTREAM 17
+#define TASKHANDLING_OPEN_FOR_STREAM 18
+#define TASKHANDLING_OPEN_FOR_DIRECTORYLISTING 19
+
+#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND 22
+#define TASKHANDLING_NONAMESET_INSERT_COMMAND 23
+#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND 24
+
+#define TASKHANDLING_ANYOTHER_WRITE 25 // not used
+#define TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE 26
+#define TASKHANDLING_NO_OPEN_FILE_FOR_WRITE 27
+#define TASKHANDLING_NOTCONNECTED_FOR_WRITE 28
+#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE 29
+#define TASKHANDLING_IOEXCEPTION_FOR_WRITE 30
+#define TASKHANDLING_FILEIOERROR_FOR_WRITE 31
+#define TASKHANDLING_FILEIOERROR_FOR_NO_SPACE 71
+#define TASKHANDLING_FILESIZE_FOR_WRITE 32
+#define TASKHANDLING_INPUTSTREAM_FOR_WRITE 33
+#define TASKHANDLING_NOREPLACE_FOR_WRITE 34
+#define TASKHANDLING_ENSUREDIR_FOR_WRITE 35
+
+#define TASKHANDLING_FOLDER_EXISTS_MKDIR 69
+#define TASKHANDLING_INVALID_NAME_MKDIR 70
+#define TASKHANDLING_CREATEDIRECTORY_MKDIR 36
+
+#define TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE 38
+#define TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE 39
+#define TASKHANDLING_OPENDIRECTORY_FOR_REMOVE 40
+#define TASKHANDLING_DELETEFILE_FOR_REMOVE 41
+#define TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE 42
+#define TASKHANDLING_FILETYPE_FOR_REMOVE 43
+#define TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE 44
+#define TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE 45
+
+#define TASKHANDLING_TRANSFER_ACCESSINGROOT 46
+#define TASKHANDLING_TRANSFER_INVALIDSCHEME 47
+#define TASKHANDLING_TRANSFER_INVALIDURL 48
+#define TASKHANDLING_TRANSFER_DESTFILETYPE 50
+#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCE 51
+#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT 52
+#define TASKHANDLING_KEEPERROR_FOR_MOVE 53
+#define TASKHANDLING_NAMECLASH_FOR_MOVE 54
+#define TASKHANDLING_NAMECLASHMOVE_FOR_MOVE 55
+#define TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE 56
+#define TASKHANDLING_OVERWRITE_FOR_MOVE 57
+#define TASKHANDLING_RENAME_FOR_MOVE 58
+#define TASKHANDLING_RENAMEMOVE_FOR_MOVE 59
+
+#define TASKHANDLING_TRANSFER_BY_COPY_SOURCE 60
+#define TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT 61
+#define TASKHANDLING_KEEPERROR_FOR_COPY 62
+#define TASKHANDLING_OVERWRITE_FOR_COPY 63
+#define TASKHANDLING_RENAME_FOR_COPY 64
+#define TASKHANDLING_RENAMEMOVE_FOR_COPY 65
+#define TASKHANDLING_NAMECLASH_FOR_COPY 66
+#define TASKHANDLING_NAMECLASHMOVE_FOR_COPY 67
+#define TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY 68
+
+}
+
+#endif
+
+
+
+
diff --git a/ucb/source/ucp/file/filglob.cxx b/ucb/source/ucp/file/filglob.cxx
new file mode 100644
index 000000000000..e947c68da1ba
--- /dev/null
+++ b/ucb/source/ucp/file/filglob.cxx
@@ -0,0 +1,954 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <stdio.h>
+#include "filglob.hxx"
+#ifndef _FILERROR_HXX_
+#include "filerror.hxx"
+#endif
+#include "shell.hxx"
+#include "bc.hxx"
+#include <osl/file.hxx>
+#ifndef INCLUDED_STL_VECTOR
+#include <vector>
+#define INCLUDED_STL_VECTOR
+#endif
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include "com/sun/star/beans/PropertyState.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "osl/diagnose.h"
+#include "rtl/ustrbuf.hxx"
+#include <rtl/uri.hxx>
+#include <rtl/ustring.hxx>
+#include "sal/types.h"
+
+using namespace ucbhelper;
+using namespace osl;
+using namespace ::com::sun::star;
+using namespace com::sun::star::task;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+
+namespace {
+
+ Sequence< Any > generateErrorArguments(
+ rtl::OUString const & rPhysicalUrl)
+ {
+ rtl::OUString aResourceName;
+ rtl::OUString aResourceType;
+ sal_Bool bRemovable;
+ bool bResourceName = false;
+ bool bResourceType = false;
+ bool bRemoveProperty = false;
+
+ if (osl::FileBase::getSystemPathFromFileURL(
+ rPhysicalUrl,
+ aResourceName)
+ == osl::FileBase::E_None)
+ bResourceName = true;
+
+ // The resource types "folder" (i.e., directory) and
+ // "volume" seem to be
+ // the most interesting when producing meaningful error messages:
+ osl::DirectoryItem aItem;
+ if (osl::DirectoryItem::get(rPhysicalUrl, aItem) ==
+ osl::FileBase::E_None)
+ {
+ osl::FileStatus aStatus( FileStatusMask_Type );
+ if (aItem.getFileStatus(aStatus) == osl::FileBase::E_None)
+ switch (aStatus.getFileType())
+ {
+ case osl::FileStatus::Directory:
+ aResourceType
+ = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("folder"));
+ bResourceType = true;
+ break;
+
+ case osl::FileStatus::Volume:
+ {
+ aResourceType
+ = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("volume"));
+ bResourceType = true;
+ osl::VolumeInfo aVolumeInfo(
+ VolumeInfoMask_Attributes );
+ if( osl::Directory::getVolumeInfo(
+ rPhysicalUrl,aVolumeInfo ) ==
+ osl::FileBase::E_None )
+ {
+ bRemovable = aVolumeInfo.getRemoveableFlag();
+ bRemoveProperty = true;
+ }
+ }
+ break;
+ case osl::FileStatus::Regular:
+ case osl::FileStatus::Fifo:
+ case osl::FileStatus::Socket:
+ case osl::FileStatus::Link:
+ case osl::FileStatus::Special:
+ case osl::FileStatus::Unknown:
+ // do nothing for now
+ break;
+ }
+ }
+
+ Sequence< Any > aArguments( 1 +
+ (bResourceName ? 1 : 0) +
+ (bResourceType ? 1 : 0) +
+ (bRemoveProperty ? 1 : 0) );
+ sal_Int32 i = 0;
+ aArguments[i++]
+ <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ makeAny(rPhysicalUrl),
+ PropertyState_DIRECT_VALUE);
+ if (bResourceName)
+ aArguments[i++]
+ <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ResourceName")),
+ -1,
+ makeAny(aResourceName),
+ PropertyState_DIRECT_VALUE);
+ if (bResourceType)
+ aArguments[i++]
+ <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ResourceType")),
+ -1,
+ makeAny(aResourceType),
+ PropertyState_DIRECT_VALUE);
+ if (bRemoveProperty)
+ aArguments[i++]
+ <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Removable")),
+ -1,
+ makeAny(bRemovable),
+ PropertyState_DIRECT_VALUE);
+
+ return aArguments;
+ }
+}
+
+
+
+namespace fileaccess {
+
+
+ sal_Bool isChild( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath )
+ {
+ static sal_Unicode slash = '/';
+ // Simple lexical comparison
+ sal_Int32 srcL = srcUnqPath.getLength();
+ sal_Int32 dstL = dstUnqPath.getLength();
+
+ return (
+ ( srcUnqPath == dstUnqPath )
+ ||
+ ( ( dstL > srcL )
+ &&
+ ( srcUnqPath.compareTo( dstUnqPath, srcL ) == 0 )
+ &&
+ ( dstUnqPath[ srcL ] == slash ) )
+ );
+ }
+
+
+ rtl::OUString newName(
+ const rtl::OUString& aNewPrefix,
+ const rtl::OUString& aOldPrefix,
+ const rtl::OUString& old_Name )
+ {
+ sal_Int32 srcL = aOldPrefix.getLength();
+
+ rtl::OUString new_Name = old_Name.copy( srcL );
+ new_Name = ( aNewPrefix + new_Name );
+ return new_Name;
+ }
+
+
+ rtl::OUString getTitle( const rtl::OUString& aPath )
+ {
+ sal_Unicode slash = '/';
+ sal_Int32 lastIndex = aPath.lastIndexOf( slash );
+ return aPath.copy( lastIndex + 1 );
+ }
+
+
+ rtl::OUString getParentName( const rtl::OUString& aFileName )
+ {
+ sal_Int32 lastIndex = aFileName.lastIndexOf( sal_Unicode('/') );
+ rtl::OUString aParent = aFileName.copy( 0,lastIndex );
+
+ if( aParent[ aParent.getLength()-1] == sal_Unicode(':') && aParent.getLength() == 6 )
+ aParent += rtl::OUString::createFromAscii( "/" );
+
+ if( 0 == aParent.compareToAscii( "file://" ) )
+ aParent = rtl::OUString::createFromAscii( "file:///" );
+
+ return aParent;
+ }
+
+
+ osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath,
+ const rtl::OUString& strDestPath,
+ sal_Bool test )
+ {
+ if( test )
+ {
+ osl::DirectoryItem aItem;
+ if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT )
+ return osl::FileBase::E_EXIST;
+ }
+
+ return osl::File::copy( strPath,strDestPath );
+ }
+
+
+ osl::FileBase::RC osl_File_move( const rtl::OUString& strPath,
+ const rtl::OUString& strDestPath,
+ sal_Bool test )
+ {
+ if( test )
+ {
+ osl::DirectoryItem aItem;
+ if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT )
+ return osl::FileBase::E_EXIST;
+ }
+
+ return osl::File::move( strPath,strDestPath );
+ }
+
+ void throw_handler(
+ sal_Int32 errorCode,
+ sal_Int32 minorCode,
+ const Reference< XCommandEnvironment >& xEnv,
+ const rtl::OUString& aUncPath,
+ BaseContent* pContent,
+ bool isHandled )
+ {
+ Reference<XCommandProcessor> xComProc(pContent);
+ Any aAny;
+ IOErrorCode ioErrorCode;
+
+ if( errorCode == TASKHANDLER_UNSUPPORTED_COMMAND )
+ {
+ aAny <<= UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ cancelCommandExecution( aAny,xEnv );
+ }
+ else if( errorCode == TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_OPEN_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_DELETE_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_TRANSFER_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_INSERT_ARGUMENT ||
+ errorCode == TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT )
+ {
+ IllegalArgumentException excep;
+ excep.ArgumentPosition = 0;
+ aAny <<= excep;
+ cancelCommandExecution(
+ aAny,xEnv);
+ }
+ else if( errorCode == TASKHANDLING_UNSUPPORTED_OPEN_MODE )
+ {
+ UnsupportedOpenModeException excep;
+ excep.Mode = sal::static_int_cast< sal_Int16 >(minorCode);
+ aAny <<= excep;
+ cancelCommandExecution( aAny,xEnv );
+ }
+ else if(errorCode == TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND ||
+ errorCode == TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND ||
+ errorCode == TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND )
+ {
+ // What to do here?
+ }
+ else if(
+ // error in opening file
+ errorCode == TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE ||
+ // error in opening file
+ errorCode == TASKHANDLING_NO_OPEN_FILE_FOR_WRITE ||
+ // error in opening file
+ errorCode == TASKHANDLING_OPEN_FOR_STREAM ||
+ // error in opening file
+ errorCode == TASKHANDLING_OPEN_FOR_INPUTSTREAM ||
+ // error in opening file
+ errorCode == TASKHANDLING_OPEN_FILE_FOR_PAGING )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_NAMETOOLONG:
+ // pathname was too long
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case FileBase::E_NXIO:
+ // No such device or address
+ case FileBase::E_NODEV:
+ // No such device
+ ioErrorCode = IOErrorCode_INVALID_DEVICE;
+ break;
+ case FileBase::E_NOENT:
+ // No such file or directory
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ break;
+ case FileBase::E_ROFS:
+ // #i4735# handle ROFS transparently as ACCESS_DENIED
+ case FileBase::E_ACCES:
+ // permission denied<P>
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_ISDIR:
+ // Is a directory<p>
+ ioErrorCode = IOErrorCode_NO_FILE;
+ break;
+ case FileBase::E_NOTREADY:
+ ioErrorCode = IOErrorCode_DEVICE_NOT_READY;
+ break;
+ case FileBase::E_MFILE:
+ // too many open files used by the process
+ case FileBase::E_NFILE:
+ // too many open files in the system
+ ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES;
+ break;
+ case FileBase::E_INVAL:
+ // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_NOMEM:
+ // not enough memory for allocating structures
+ ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case FileBase::E_BUSY:
+ // Text file busy
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+ case FileBase::E_AGAIN:
+ // Operation would block
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+ case FileBase::E_NOLCK: // No record locks available
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+
+ case FileBase::E_FAULT: // Bad address
+ case FileBase::E_LOOP: // Too many symbolic links encountered
+ case FileBase::E_NOSPC: // No space left on device
+ case FileBase::E_INTR: // function call was interrupted
+ case FileBase::E_IO: // I/O error
+ case FileBase::E_MULTIHOP: // Multihop attempted
+ case FileBase::E_NOLINK: // Link has been severed
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "an error occured during file opening")),
+ xComProc);
+ }
+ else if( errorCode == TASKHANDLING_OPEN_FOR_DIRECTORYLISTING ||
+ errorCode == TASKHANDLING_OPENDIRECTORY_FOR_REMOVE )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_INVAL:
+ // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_NOENT:
+ // the specified path doesn't exist
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ break;
+ case FileBase::E_NOTDIR:
+ // the specified path is not an directory
+ ioErrorCode = IOErrorCode_NO_DIRECTORY;
+ break;
+ case FileBase::E_NOMEM:
+ // not enough memory for allocating structures
+ ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case FileBase::E_ROFS:
+ // #i4735# handle ROFS transparently as ACCESS_DENIED
+ case FileBase::E_ACCES: // permission denied
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_NOTREADY:
+ ioErrorCode = IOErrorCode_DEVICE_NOT_READY;
+ break;
+ case FileBase::E_MFILE:
+ // too many open files used by the process
+ case FileBase::E_NFILE:
+ // too many open files in the system
+ ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES;
+ break;
+ case FileBase::E_NAMETOOLONG:
+ // File name too long
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case FileBase::E_LOOP:
+ // Too many symbolic links encountered<p>
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "an error occured during opening a directory")),
+ xComProc);
+ }
+ else if( errorCode == TASKHANDLING_NOTCONNECTED_FOR_WRITE ||
+ errorCode == TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE ||
+ errorCode == TASKHANDLING_IOEXCEPTION_FOR_WRITE ||
+ errorCode == TASKHANDLING_NOTCONNECTED_FOR_PAGING ||
+ errorCode == TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING ||
+ errorCode == TASKHANDLING_IOEXCEPTION_FOR_PAGING )
+ {
+ ioErrorCode = IOErrorCode_UNKNOWN;
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "an error occured writing or reading from a file")),
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_FILEIOERROR_FOR_NO_SPACE )
+ {
+ ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE;
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "device full")),
+ xComProc);
+ }
+ else if( errorCode == TASKHANDLING_FILEIOERROR_FOR_WRITE ||
+ errorCode == TASKHANDLING_READING_FILE_FOR_PAGING )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_INVAL:
+ // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_FBIG:
+ // File too large
+ ioErrorCode = IOErrorCode_CANT_WRITE;
+ break;
+ case FileBase::E_NOSPC:
+ // No space left on device
+ ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE;
+ break;
+ case FileBase::E_NXIO:
+ // No such device or address
+ ioErrorCode = IOErrorCode_INVALID_DEVICE;
+ break;
+ case FileBase::E_NOLINK:
+ // Link has been severed
+ case FileBase::E_ISDIR:
+ // Is a directory
+ ioErrorCode = IOErrorCode_NO_FILE;
+ break;
+ case FileBase::E_AGAIN:
+ // Operation would block
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+ case FileBase::E_TIMEDOUT:
+ ioErrorCode = IOErrorCode_DEVICE_NOT_READY;
+ break;
+ case FileBase::E_NOLCK: // No record locks available
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+ case FileBase::E_IO: // I/O error
+ case FileBase::E_BADF: // Bad file
+ case FileBase::E_FAULT: // Bad address
+ case FileBase::E_INTR: // function call was interrupted
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "an error occured during opening a file")),
+ xComProc);
+ }
+ else if( errorCode == TASKHANDLING_NONAMESET_INSERT_COMMAND ||
+ errorCode == TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND )
+ {
+ Sequence< ::rtl::OUString > aSeq( 1 );
+ aSeq[0] =
+ ( errorCode == TASKHANDLING_NONAMESET_INSERT_COMMAND ) ?
+ rtl::OUString::createFromAscii( "Title" ) :
+ rtl::OUString::createFromAscii( "ContentType" );
+
+ aAny <<= MissingPropertiesException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a property is missing necessary"
+ "to create a content")),
+ xComProc,
+ aSeq);
+ cancelCommandExecution(aAny,xEnv);
+ }
+ else if( errorCode == TASKHANDLING_FILESIZE_FOR_WRITE )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_INVAL:
+ // the format of the parameters was not valid
+ case FileBase::E_OVERFLOW:
+ // The resulting file offset would be a value which cannot
+ // be represented correctly for regular files
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "there were problems with the filesize")),
+ xComProc);
+ }
+ else if(errorCode == TASKHANDLING_INPUTSTREAM_FOR_WRITE)
+ {
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+ aAny <<=
+ MissingInputStreamException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "the inputstream is missing necessary"
+ "to create a content")),
+ xContext);
+ cancelCommandExecution(aAny,xEnv);
+ }
+ else if( errorCode == TASKHANDLING_NOREPLACE_FOR_WRITE )
+ // Overwrite = false and file exists
+ {
+ NameClashException excep;
+ excep.Name = getTitle(aUncPath);
+ excep.Classification = InteractionClassification_ERROR;
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+ excep.Context = xContext;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file exists and overwrite forbidden"));
+ aAny <<= excep;
+ cancelCommandExecution( aAny,xEnv );
+ }
+ else if( errorCode == TASKHANDLING_INVALID_NAME_MKDIR )
+ {
+ InteractiveAugmentedIOException excep;
+ excep.Code = IOErrorCode_INVALID_CHARACTER;
+ PropertyValue prop;
+ prop.Name = rtl::OUString::createFromAscii("ResourceName");
+ prop.Handle = -1;
+ rtl::OUString m_aClashingName(
+ rtl::Uri::decode(
+ getTitle(aUncPath),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8));
+ prop.Value <<= m_aClashingName;
+ Sequence<Any> seq(1);
+ seq[0] <<= prop;
+ excep.Arguments = seq;
+ excep.Classification = InteractionClassification_ERROR;
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+ excep.Context = xContext;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "the name contained invalid characters"));
+ if(isHandled)
+ throw excep;
+ else {
+ aAny <<= excep;
+ cancelCommandExecution( aAny,xEnv );
+ }
+// ioErrorCode = IOErrorCode_INVALID_CHARACTER;
+// cancelCommandExecution(
+// ioErrorCode,
+// generateErrorArguments(aUncPath),
+// xEnv,
+// rtl::OUString(
+// RTL_CONSTASCII_USTRINGPARAM(
+// "the name contained invalid characters")),
+// xComProc );
+ }
+ else if( errorCode == TASKHANDLING_FOLDER_EXISTS_MKDIR )
+ {
+ NameClashException excep;
+ excep.Name = getTitle(aUncPath);
+ excep.Classification = InteractionClassification_ERROR;
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+ excep.Context = xContext;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "folder exists and overwrite forbidden"));
+ if(isHandled)
+ throw excep;
+ else {
+ aAny <<= excep;
+ cancelCommandExecution( aAny,xEnv );
+ }
+// ioErrorCode = IOErrorCode_ALREADY_EXISTING;
+// cancelCommandExecution(
+// ioErrorCode,
+// generateErrorArguments(aUncPath),
+// xEnv,
+// rtl::OUString(
+// RTL_CONSTASCII_USTRINGPARAM(
+// "the folder exists")),
+// xComProc );
+ }
+ else if( errorCode == TASKHANDLING_ENSUREDIR_FOR_WRITE ||
+ errorCode == TASKHANDLING_CREATEDIRECTORY_MKDIR )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_ACCES:
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_ROFS:
+ ioErrorCode = IOErrorCode_WRITE_PROTECTED;
+ break;
+ case FileBase::E_NAMETOOLONG:
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ default:
+ ioErrorCode = IOErrorCode_NOT_EXISTING_PATH;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(getParentName(aUncPath)),
+ //TODO! ok to supply physical URL to getParentName()?
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a folder could not be created")),
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE ||
+ errorCode == TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE ||
+ errorCode == TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_INVAL: // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_NOMEM: // not enough memory for allocating structures
+ ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case FileBase::E_ROFS: // #i4735# handle ROFS transparently as ACCESS_DENIED
+ case FileBase::E_ACCES: // permission denied
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_MFILE: // too many open files used by the process
+ case FileBase::E_NFILE: // too many open files in the system
+ ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES;
+ break;
+ case FileBase::E_NOLINK: // Link has been severed
+ case FileBase::E_NOENT: // No such file or directory
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ break;
+ case FileBase::E_NAMETOOLONG: // File name too long
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case FileBase::E_NOTDIR: // A component of the path prefix of path is not a directory
+ ioErrorCode = IOErrorCode_NOT_EXISTING_PATH;
+ break;
+ case FileBase::E_LOOP: // Too many symbolic links encountered
+ case FileBase::E_IO: // I/O error
+ case FileBase::E_MULTIHOP: // Multihop attempted
+ case FileBase::E_FAULT: // Bad address
+ case FileBase::E_INTR: // function call was interrupted
+ case FileBase::E_NOSYS: // Function not implemented
+ case FileBase::E_NOSPC: // No space left on device
+ case FileBase::E_NXIO: // No such device or address
+ case FileBase::E_OVERFLOW: // Value too large for defined data type
+ case FileBase::E_BADF: // Invalid oslDirectoryItem parameter
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a file status object could not be filled")),
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_DELETEFILE_FOR_REMOVE ||
+ errorCode == TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE )
+ {
+ switch( minorCode )
+ {
+ case FileBase::E_INVAL: // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_NOMEM: // not enough memory for allocating structures
+ ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case FileBase::E_ACCES: // Permission denied
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_PERM: // Operation not permitted
+ ioErrorCode = IOErrorCode_NOT_SUPPORTED;
+ break;
+ case FileBase::E_NAMETOOLONG: // File name too long
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case FileBase::E_NOLINK: // Link has been severed
+ case FileBase::E_NOENT: // No such file or directory
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ break;
+ case FileBase::E_ISDIR: // Is a directory
+ case FileBase::E_ROFS: // Read-only file system
+ ioErrorCode = IOErrorCode_NOT_SUPPORTED;
+ break;
+ case FileBase::E_BUSY: // Device or resource busy
+ ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
+ break;
+ case FileBase::E_FAULT: // Bad address
+ case FileBase::E_LOOP: // Too many symbolic links encountered
+ case FileBase::E_IO: // I/O error
+ case FileBase::E_INTR: // function call was interrupted
+ case FileBase::E_MULTIHOP: // Multihop attempted
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "a file or directory could not be deleted")),
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCE ||
+ errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT ||
+ errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCE ||
+ errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT ||
+ errorCode == TASKHANDLING_TRANSFER_DESTFILETYPE ||
+ errorCode == TASKHANDLING_FILETYPE_FOR_REMOVE ||
+ errorCode == TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE ||
+ errorCode == TASKHANDLING_TRANSFER_INVALIDURL )
+ {
+ rtl::OUString aMsg;
+ switch( minorCode )
+ {
+ case FileBase::E_NOENT: // No such file or directory
+ if ( errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCE ||
+ errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT ||
+ errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCE ||
+ errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT )
+ {
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "source file/folder does not exist"));
+ break;
+ }
+ else
+ {
+ ioErrorCode = IOErrorCode_GENERAL;
+ aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "a general error during transfer command"));
+ break;
+ }
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "a general error during transfer command"));
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ aMsg,
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_TRANSFER_ACCESSINGROOT )
+ {
+ ioErrorCode = IOErrorCode_WRITE_PROTECTED;
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "accessing the root during transfer")),
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_TRANSFER_INVALIDSCHEME )
+ {
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+
+ aAny <<=
+ InteractiveBadTransferURLException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "bad tranfer url")),
+ xContext);
+ cancelCommandExecution( aAny,xEnv );
+ }
+ else if( errorCode == TASKHANDLING_OVERWRITE_FOR_MOVE ||
+ errorCode == TASKHANDLING_OVERWRITE_FOR_COPY ||
+ errorCode == TASKHANDLING_NAMECLASHMOVE_FOR_MOVE ||
+ errorCode == TASKHANDLING_NAMECLASHMOVE_FOR_COPY ||
+ errorCode == TASKHANDLING_KEEPERROR_FOR_MOVE ||
+ errorCode == TASKHANDLING_KEEPERROR_FOR_COPY ||
+ errorCode == TASKHANDLING_RENAME_FOR_MOVE ||
+ errorCode == TASKHANDLING_RENAME_FOR_COPY ||
+ errorCode == TASKHANDLING_RENAMEMOVE_FOR_MOVE ||
+ errorCode == TASKHANDLING_RENAMEMOVE_FOR_COPY )
+ {
+ rtl::OUString aMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "general error during transfer"));
+
+ switch( minorCode )
+ {
+ case FileBase::E_EXIST:
+ ioErrorCode = IOErrorCode_ALREADY_EXISTING;
+ break;
+ case FileBase::E_INVAL: // the format of the parameters was not valid
+ ioErrorCode = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case FileBase::E_NOMEM: // not enough memory for allocating structures
+ ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case FileBase::E_ACCES: // Permission denied
+ ioErrorCode = IOErrorCode_ACCESS_DENIED;
+ break;
+ case FileBase::E_PERM: // Operation not permitted
+ ioErrorCode = IOErrorCode_NOT_SUPPORTED;
+ break;
+ case FileBase::E_NAMETOOLONG: // File name too long
+ ioErrorCode = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case FileBase::E_NOENT: // No such file or directory
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ aMsg = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "file/folder does not exist"));
+ break;
+ case FileBase::E_ROFS: // Read-only file system<p>
+ ioErrorCode = IOErrorCode_NOT_EXISTING;
+ break;
+ default:
+ ioErrorCode = IOErrorCode_GENERAL;
+ break;
+ }
+ cancelCommandExecution(
+ ioErrorCode,
+ generateErrorArguments(aUncPath),
+ xEnv,
+ aMsg,
+ xComProc );
+ }
+ else if( errorCode == TASKHANDLING_NAMECLASH_FOR_COPY ||
+ errorCode == TASKHANDLING_NAMECLASH_FOR_MOVE )
+ {
+ NameClashException excep;
+ excep.Name = getTitle(aUncPath);
+ excep.Classification = InteractionClassification_ERROR;
+ Reference<XInterface> xContext(xComProc,UNO_QUERY);
+ excep.Context = xContext;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "name clash during copy or move"));
+ aAny <<= excep;
+
+ cancelCommandExecution(aAny,xEnv);
+ }
+ else if( errorCode == TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE ||
+ errorCode == TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY )
+ {
+ Reference<XInterface> xContext(
+ xComProc,UNO_QUERY);
+ UnsupportedNameClashException excep;
+ excep.NameClash = minorCode;
+ excep.Context = xContext;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "name clash value not supported during copy or move"));
+
+ aAny <<= excep;
+ cancelCommandExecution(aAny,xEnv);
+ }
+ else
+ {
+ // case TASKHANDLER_NO_ERROR:
+ return;
+ }
+ }
+
+
+} // end namespace fileaccess
diff --git a/ucb/source/ucp/file/filglob.hxx b/ucb/source/ucp/file/filglob.hxx
new file mode 100644
index 000000000000..015128e6588b
--- /dev/null
+++ b/ucb/source/ucp/file/filglob.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILGLOB_HXX_
+#define _FILGLOB_HXX_
+
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+
+
+namespace fileaccess {
+
+ class BaseContent;
+
+ struct equalOUString
+ {
+ bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
+ {
+ return !!( rKey1 == rKey2 );
+ }
+ };
+
+
+ struct hashOUString
+ {
+ size_t operator()( const rtl::OUString& rName ) const
+ {
+ return rName.hashCode();
+ }
+ };
+
+
+ /******************************************************************************/
+ /* */
+ /* Helper functions */
+ /* */
+ /******************************************************************************/
+
+
+ // Returns true if dstUnqPath is a child from srcUnqPath or both are equal
+
+ extern sal_Bool isChild( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath );
+
+
+ // Changes the prefix in name
+ extern rtl::OUString newName( const rtl::OUString& aNewPrefix,
+ const rtl::OUString& aOldPrefix,
+ const rtl::OUString& old_Name );
+
+ // returns the last part of the given url as title
+ extern rtl::OUString getTitle( const rtl::OUString& aPath );
+
+ // returns the url without last part as parentname
+ // In case aFileName is root ( file:/// ) root is returned
+
+ extern rtl::OUString getParentName( const rtl::OUString& aFileName );
+
+ /**
+ * special copy:
+ * On test = true, the implementation determines whether the
+ * destination exists and returns the appropriate errorcode E_EXIST.
+ * osl::File::copy copies unchecked.
+ */
+
+ extern osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath,
+ const rtl::OUString& strDestPath,
+ sal_Bool test = false );
+
+ /**
+ * special move:
+ * On test = true, the implementation determines whether the
+ * destination exists and returns the appropriate errorcode E_EXIST.
+ * osl::File::move moves unchecked
+ */
+
+ extern osl::FileBase::RC osl_File_move( const rtl::OUString& strPath,
+ const rtl::OUString& strDestPath,
+ sal_Bool test = false );
+
+ // This function implements the global exception handler of the file_ucp;
+ // It never returns;
+
+ extern void throw_handler( sal_Int32 errorCode,
+ sal_Int32 minorCode,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv,
+ const rtl::OUString& aUncPath,
+ BaseContent* pContent,
+ bool isHandled = false);
+ // the physical URL of the object
+
+} // end namespace fileaccess
+
+#endif
diff --git a/ucb/source/ucp/file/filid.cxx b/ucb/source/ucp/file/filid.cxx
new file mode 100644
index 000000000000..8ccd8980fb9b
--- /dev/null
+++ b/ucb/source/ucp/file/filid.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filid.hxx"
+#include "shell.hxx"
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+FileContentIdentifier::FileContentIdentifier(
+ shell* pMyShell,
+ const rtl::OUString& aUnqPath,
+ sal_Bool IsNormalized )
+ : m_pMyShell( pMyShell ),
+ m_bNormalized( IsNormalized )
+{
+ if( IsNormalized )
+ {
+ m_pMyShell->getUrlFromUnq( aUnqPath,m_aContentId );
+ m_aNormalizedId = aUnqPath;
+ m_pMyShell->getScheme( m_aProviderScheme );
+ }
+ else
+ {
+ m_pMyShell->getUnqFromUrl( aUnqPath,m_aNormalizedId );
+ m_aContentId = aUnqPath;
+ m_pMyShell->getScheme( m_aProviderScheme );
+ }
+}
+
+FileContentIdentifier::~FileContentIdentifier()
+{
+}
+
+
+void SAL_CALL
+FileContentIdentifier::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+FileContentIdentifier::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+uno::Any SAL_CALL
+FileContentIdentifier::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this),
+ SAL_STATIC_CAST( XContentIdentifier*, this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+uno::Sequence< sal_Int8 > SAL_CALL
+FileContentIdentifier::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static cppu::OImplementationId* pId = NULL;
+ if ( !pId )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pId )
+ {
+ static cppu::OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return (*pId).getImplementationId();
+}
+
+
+uno::Sequence< uno::Type > SAL_CALL
+FileContentIdentifier::getTypes(
+ void )
+ throw( uno::RuntimeException )
+{
+ static cppu::OTypeCollection* pCollection = NULL;
+ if ( !pCollection ) {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection collection(
+ getCppuType( static_cast< uno::Reference< lang::XTypeProvider >* >( 0 ) ),
+ getCppuType( static_cast< uno::Reference< XContentIdentifier >* >( 0 ) ) );
+ pCollection = &collection;
+ }
+ }
+ return (*pCollection).getTypes();
+}
+
+
+rtl::OUString
+SAL_CALL
+FileContentIdentifier::getContentIdentifier(
+ void )
+ throw( uno::RuntimeException )
+{
+ return m_aContentId;
+}
+
+
+rtl::OUString SAL_CALL
+FileContentIdentifier::getContentProviderScheme(
+ void )
+ throw( uno::RuntimeException )
+{
+ return m_aProviderScheme;
+}
diff --git a/ucb/source/ucp/file/filid.hxx b/ucb/source/ucp/file/filid.hxx
new file mode 100644
index 000000000000..36c774353120
--- /dev/null
+++ b/ucb/source/ucp/file/filid.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILID_HXX_
+#define _FILID_HXX_
+
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+
+namespace fileaccess {
+
+ class shell;
+
+ class FileContentIdentifier :
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XContentIdentifier
+ {
+
+ // This implementation has to be reworked
+ public:
+ FileContentIdentifier( shell* pMyShell,
+ const rtl::OUString& aUnqPath,
+ sal_Bool IsNormalized = true );
+
+ virtual ~FileContentIdentifier();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ // XTypeProvider
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XContentIdentifier
+ virtual rtl::OUString SAL_CALL
+ getContentIdentifier(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getContentProviderScheme(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ private:
+ shell* m_pMyShell;
+ rtl::OUString m_aContentId; // The URL string
+ rtl::OUString m_aNormalizedId; // The somehow normalized string
+ rtl::OUString m_aProviderScheme;
+ sal_Bool m_bNormalized;
+ };
+
+} // end namespace fileaccess
+
+
+#endif
diff --git a/ucb/source/ucp/file/filinl.hxx b/ucb/source/ucp/file/filinl.hxx
new file mode 100644
index 000000000000..d28af751403b
--- /dev/null
+++ b/ucb/source/ucp/file/filinl.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILINL_HXX_
+#define _FILINL_HXX_
+
+inline const sal_Bool& SAL_CALL shell::MyProperty::IsNative() const
+{
+ return isNative;
+}
+inline const sal_Int32& SAL_CALL shell::MyProperty::getHandle() const
+{
+ return Handle;
+}
+inline const com::sun::star::uno::Type& SAL_CALL shell::MyProperty::getType() const
+{
+ return Typ;
+}
+inline const com::sun::star::uno::Any& SAL_CALL shell::MyProperty::getValue() const
+{
+ return Value;
+}
+inline const com::sun::star::beans::PropertyState& SAL_CALL shell::MyProperty::getState() const
+{
+ return State;
+}
+inline const sal_Int16& SAL_CALL shell::MyProperty::getAttributes() const
+{
+ return Attributes;
+}
+inline void SAL_CALL shell::MyProperty::setHandle( const sal_Int32& __Handle ) const
+{
+ (( MyProperty* )this )->Handle = __Handle;
+}
+inline void SAL_CALL shell::MyProperty::setType( const com::sun::star::uno::Type& __Typ ) const
+{
+ (( MyProperty* )this )->Typ = __Typ;
+}
+inline void SAL_CALL shell::MyProperty::setValue( const com::sun::star::uno::Any& __Value ) const
+{
+ (( MyProperty* )this )->Value = __Value;
+}
+inline void SAL_CALL shell::MyProperty::setState( const com::sun::star::beans::PropertyState& __State ) const
+{
+ (( MyProperty* )this )->State = __State;
+}
+inline void SAL_CALL shell::MyProperty::setAttributes( const sal_Int16& __Attributes ) const
+{
+ (( MyProperty* )this )->Attributes = __Attributes;
+}
+
+
+#endif
diff --git a/ucb/source/ucp/file/filinpstr.cxx b/ucb/source/ucp/file/filinpstr.cxx
new file mode 100644
index 000000000000..a66a0daf5def
--- /dev/null
+++ b/ucb/source/ucp/file/filinpstr.cxx
@@ -0,0 +1,262 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filinpstr.hxx"
+#ifndef _FILERROR_HXX_
+#include "filerror.hxx"
+#endif
+#include "shell.hxx"
+#include "prov.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+
+XInputStream_impl::XInputStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock )
+ : m_pMyShell( pMyShell ),
+ m_xProvider( pMyShell->m_pProvider ),
+ m_bLock( bLock ),
+ m_aFile( aUncPath ),
+ m_nErrorCode( TASKHANDLER_NO_ERROR ),
+ m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
+{
+ sal_uInt32 nFlags = OpenFlag_Read;
+ if ( !bLock )
+ nFlags |= OpenFlag_NoLock;
+
+ osl::FileBase::RC err = m_aFile.open( nFlags );
+ if( err != osl::FileBase::E_None )
+ {
+ m_nIsOpen = false;
+ m_aFile.close();
+
+ m_nErrorCode = TASKHANDLING_OPEN_FOR_INPUTSTREAM;
+ m_nMinorErrorCode = err;
+ }
+ else
+ m_nIsOpen = true;
+}
+
+
+XInputStream_impl::~XInputStream_impl()
+{
+ try
+ {
+ closeInput();
+ }
+ catch (io::IOException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+ catch (uno::RuntimeException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+}
+
+
+sal_Int32 SAL_CALL XInputStream_impl::CtorSuccess()
+{
+ return m_nErrorCode;
+};
+
+
+
+sal_Int32 SAL_CALL XInputStream_impl::getMinorError()
+{
+ return m_nMinorErrorCode;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+
+XTYPEPROVIDER_IMPL_3( XInputStream_impl,
+ lang::XTypeProvider,
+ io::XSeekable,
+ io::XInputStream )
+
+
+
+uno::Any SAL_CALL
+XInputStream_impl::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException)
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( io::XInputStream*,this ),
+ SAL_STATIC_CAST( lang::XTypeProvider*,this ),
+ SAL_STATIC_CAST( io::XSeekable*,this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+void SAL_CALL
+XInputStream_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XInputStream_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+sal_Int32 SAL_CALL
+XInputStream_impl::readBytes(
+ uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ if( ! m_nIsOpen ) throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ aData.realloc(nBytesToRead);
+ //TODO! translate memory exhaustion (if it were detectable...) into
+ // io::BufferSizeExceededException
+
+ sal_uInt64 nrc(0);
+ if(m_aFile.read( aData.getArray(),sal_uInt64(nBytesToRead),nrc )
+ != osl::FileBase::E_None)
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Shrink aData in case we read less than nBytesToRead (XInputStream
+ // documentation does not tell whether this is required, and I do not know
+ // if any code relies on this, so be conservative---SB):
+ if (sal::static_int_cast<sal_Int32>(nrc) != nBytesToRead)
+ aData.realloc(sal_Int32(nrc));
+ return ( sal_Int32 ) nrc;
+}
+
+sal_Int32 SAL_CALL
+XInputStream_impl::readSomeBytes(
+ uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ return readBytes( aData,nMaxBytesToRead );
+}
+
+
+void SAL_CALL
+XInputStream_impl::skipBytes(
+ sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) );
+}
+
+
+sal_Int32 SAL_CALL
+XInputStream_impl::available(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ return 0;
+}
+
+
+void SAL_CALL
+XInputStream_impl::closeInput(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if( m_nIsOpen )
+ {
+ osl::FileBase::RC err = m_aFile.close();
+ if( err != osl::FileBase::E_None )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ m_nIsOpen = false;
+ }
+}
+
+
+void SAL_CALL
+XInputStream_impl::seek(
+ sal_Int64 location )
+ throw( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if( location < 0 )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+sal_Int64 SAL_CALL
+XInputStream_impl::getPosition(
+ void )
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ sal_uInt64 uPos;
+ if( osl::FileBase::E_None != m_aFile.getPos( uPos ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return sal_Int64( uPos );
+}
+
+sal_Int64 SAL_CALL
+XInputStream_impl::getLength(
+ void )
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ sal_uInt64 uEndPos;
+ if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else
+ return sal_Int64( uEndPos );
+}
diff --git a/ucb/source/ucp/file/filinpstr.hxx b/ucb/source/ucp/file/filinpstr.hxx
new file mode 100644
index 000000000000..cb0668c10c82
--- /dev/null
+++ b/ucb/source/ucp/file/filinpstr.hxx
@@ -0,0 +1,164 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILINPSTR_HXX_
+#define _FILINPSTR_HXX_
+
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+
+#include "filrec.hxx"
+
+namespace fileaccess {
+
+ // forward declaration
+
+ class shell;
+
+
+ class XInputStream_impl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::io::XInputStream,
+ public com::sun::star::io::XSeekable
+ {
+ public:
+
+ XInputStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock );
+
+ virtual ~XInputStream_impl();
+
+ /**
+ * Returns an error code as given by filerror.hxx
+ */
+
+ sal_Int32 SAL_CALL CtorSuccess();
+ sal_Int32 SAL_CALL getMinorError();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ virtual sal_Int32 SAL_CALL
+ readBytes(
+ com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ readSomeBytes(
+ com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ skipBytes(
+ sal_Int32 nBytesToSkip )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ available(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeInput(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ seek(
+ sal_Int64 location )
+ throw( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL
+ getPosition(
+ void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL
+ getLength(
+ void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ private:
+
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > m_xProvider;
+ sal_Bool m_nIsOpen;
+
+ sal_Bool m_bLock;
+
+ ReconnectingFile m_aFile;
+
+ sal_Int32 m_nErrorCode;
+ sal_Int32 m_nMinorErrorCode;
+ };
+
+
+} // end namespace XInputStream_impl
+
+#endif
diff --git a/ucb/source/ucp/file/filinsreq.cxx b/ucb/source/ucp/file/filinsreq.cxx
new file mode 100644
index 000000000000..586c9a6f3c85
--- /dev/null
+++ b/ucb/source/ucp/file/filinsreq.cxx
@@ -0,0 +1,224 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filinsreq.hxx"
+#include "shell.hxx"
+#include "filglob.hxx"
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+
+
+using namespace cppu;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::task;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::beans;
+using namespace fileaccess;
+
+
+
+void SAL_CALL
+XInteractionSupplyNameImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL
+XInteractionSupplyNameImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionSupplyNameImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionSupplyName*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionSupplyNameImpl,
+ XTypeProvider,
+ XInteractionSupplyName )
+
+
+
+void SAL_CALL
+XInteractionAbortImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL
+XInteractionAbortImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionAbortImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionAbort*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionAbortImpl,
+ XTypeProvider,
+ XInteractionAbort )
+
+
+
+XInteractionRequestImpl::XInteractionRequestImpl(
+ const rtl::OUString& aClashingName,
+ const Reference<XInterface>& xOrigin,
+ shell *pShell,sal_Int32 CommandId)
+ : p1( new XInteractionSupplyNameImpl ),
+ p2( new XInteractionAbortImpl ),
+ m_nErrorCode(0),
+ m_nMinorError(0),
+ m_aSeq( 2 ),
+ m_aClashingName(aClashingName),
+ m_xOrigin(xOrigin)
+{
+ if( pShell )
+ pShell->retrieveError(CommandId,m_nErrorCode,m_nMinorError);
+ m_aSeq[0] = Reference<XInteractionContinuation>(p1);
+ m_aSeq[1] = Reference<XInteractionContinuation>(p2);
+}
+
+
+void SAL_CALL
+XInteractionRequestImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL
+XInteractionRequestImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionRequestImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet =
+ cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionRequest*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionRequestImpl,
+ XTypeProvider,
+ XInteractionRequest )
+
+
+Any SAL_CALL
+XInteractionRequestImpl::getRequest()
+ throw(RuntimeException)
+{
+ Any aAny;
+ if(m_nErrorCode == TASKHANDLING_FOLDER_EXISTS_MKDIR)
+ {
+ NameClashException excep;
+ excep.Name = m_aClashingName;
+ excep.Classification = InteractionClassification_ERROR;
+ excep.Context = m_xOrigin;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "folder exists and overwritte forbidden"));
+ aAny <<= excep;
+ }
+ else if(m_nErrorCode == TASKHANDLING_INVALID_NAME_MKDIR)
+ {
+ InteractiveAugmentedIOException excep;
+ excep.Code = IOErrorCode_INVALID_CHARACTER;
+ PropertyValue prop;
+ prop.Name = rtl::OUString::createFromAscii("ResourceName");
+ prop.Handle = -1;
+ prop.Value <<= m_aClashingName;
+ Sequence<Any> seq(1);
+ seq[0] <<= prop;
+ excep.Arguments = seq;
+ excep.Classification = InteractionClassification_ERROR;
+ excep.Context = m_xOrigin;
+ excep.Message = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "the name contained invalid characters"));
+ aAny <<= excep;
+
+ }
+ return aAny;
+}
diff --git a/ucb/source/ucp/file/filinsreq.hxx b/ucb/source/ucp/file/filinsreq.hxx
new file mode 100644
index 000000000000..bb78bd4c2973
--- /dev/null
+++ b/ucb/source/ucp/file/filinsreq.hxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _FILINSREQ_HXX_
+#define _FILINSREQ_HXX_
+
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ucb/XInteractionSupplyName.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+
+
+namespace fileaccess {
+
+
+ class shell;
+
+
+ class XInteractionSupplyNameImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XInteractionSupplyName
+ {
+ public:
+
+ XInteractionSupplyNameImpl()
+ : m_bSelected(false)
+ {
+ }
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+
+ virtual void SAL_CALL select()
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ m_bSelected = true;
+ }
+
+ void SAL_CALL setName(const ::rtl::OUString& Name)
+ throw(::com::sun::star::uno::RuntimeException)
+ {
+ m_aNewName = Name;
+ }
+
+ rtl::OUString getName() const
+ {
+ return m_aNewName;
+ }
+
+ bool isSelected() const
+ {
+ return m_bSelected;
+ }
+
+ private:
+
+ bool m_bSelected;
+ rtl::OUString m_aNewName;
+ };
+
+
+
+ class XInteractionAbortImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::task::XInteractionAbort
+ {
+ public:
+
+ XInteractionAbortImpl()
+ : m_bSelected(false)
+ {
+ }
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+
+ virtual void SAL_CALL select()
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ m_bSelected = true;
+ }
+
+
+ bool isSelected() const
+ {
+ return m_bSelected;
+ }
+
+ private:
+
+ bool m_bSelected;
+ };
+
+
+
+ class XInteractionRequestImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::task::XInteractionRequest
+ {
+ public:
+
+ XInteractionRequestImpl(
+ const rtl::OUString& aClashingName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface>& xOrigin,
+ shell* pShell,
+ sal_Int32 CommandId);
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ ::com::sun::star::uno::Any SAL_CALL getRequest( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > SAL_CALL
+ getContinuations( )
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ return m_aSeq;
+ }
+
+ bool aborted() const
+ {
+ return p2->isSelected();
+ }
+
+ rtl::OUString newName() const
+ {
+ if( p1->isSelected() )
+ return p1->getName();
+ else
+ return rtl::OUString();
+ }
+
+ private:
+
+ XInteractionSupplyNameImpl* p1;
+ XInteractionAbortImpl* p2;
+ sal_Int32 m_nErrorCode,m_nMinorError;
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > m_aSeq;
+
+ rtl::OUString m_aClashingName;
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface> m_xOrigin;
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/file/filnot.cxx b/ucb/source/ucp/file/filnot.cxx
new file mode 100644
index 000000000000..0d2d5b4cb9b1
--- /dev/null
+++ b/ucb/source/ucp/file/filnot.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/ContentAction.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include "filnot.hxx"
+#include "filid.hxx"
+#include "bc.hxx"
+#include "prov.hxx"
+
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+ContentEventNotifier::ContentEventNotifier( shell* pMyShell,
+ const uno::Reference< XContent >& xCreatorContent,
+ const uno::Reference< XContentIdentifier >& xCreatorId,
+ const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners )
+ : m_pMyShell( pMyShell ),
+ m_xCreatorContent( xCreatorContent ),
+ m_xCreatorId( xCreatorId ),
+ m_sListeners( sListeners )
+{
+}
+
+
+ContentEventNotifier::ContentEventNotifier( shell* pMyShell,
+ const uno::Reference< XContent >& xCreatorContent,
+ const uno::Reference< XContentIdentifier >& xCreatorId,
+ const uno::Reference< XContentIdentifier >& xOldId,
+ const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners )
+ : m_pMyShell( pMyShell ),
+ m_xCreatorContent( xCreatorContent ),
+ m_xCreatorId( xCreatorId ),
+ m_xOldId( xOldId ),
+ m_sListeners( sListeners )
+{
+}
+
+
+
+void ContentEventNotifier::notifyChildInserted( const rtl::OUString& aChildName )
+{
+ FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,aChildName );
+ uno::Reference< XContentIdentifier > xChildId( p );
+
+ uno::Reference< XContent > xChildContent = m_pMyShell->m_pProvider->queryContent( xChildId );
+
+ ContentEvent aEvt( m_xCreatorContent,
+ ContentAction::INSERTED,
+ xChildContent,
+ m_xCreatorId );
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->contentEvent( aEvt );
+ }
+}
+
+void ContentEventNotifier::notifyDeleted( void )
+{
+
+ ContentEvent aEvt( m_xCreatorContent,
+ ContentAction::DELETED,
+ m_xCreatorContent,
+ m_xCreatorId );
+
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->contentEvent( aEvt );
+ }
+}
+
+
+
+void ContentEventNotifier::notifyRemoved( const rtl::OUString& aChildName )
+{
+ FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,aChildName );
+ uno::Reference< XContentIdentifier > xChildId( p );
+
+ BaseContent* pp = new BaseContent( m_pMyShell,xChildId,aChildName );
+ {
+ osl::MutexGuard aGuard( pp->m_aMutex );
+ pp->m_nState |= BaseContent::Deleted;
+ }
+
+ uno::Reference< XContent > xDeletedContent( pp );
+
+
+ ContentEvent aEvt( m_xCreatorContent,
+ ContentAction::REMOVED,
+ xDeletedContent,
+ m_xCreatorId );
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->contentEvent( aEvt );
+ }
+}
+
+void ContentEventNotifier::notifyExchanged()
+{
+ ContentEvent aEvt( m_xCreatorContent,
+ ContentAction::EXCHANGED,
+ m_xCreatorContent,
+ m_xOldId );
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->contentEvent( aEvt );
+ }
+}
+
+/*********************************************************************************/
+/* */
+/* PropertySetInfoChangeNotifier */
+/* */
+/*********************************************************************************/
+
+
+PropertySetInfoChangeNotifier::PropertySetInfoChangeNotifier(
+ shell* pMyShell,
+ const uno::Reference< XContent >& xCreatorContent,
+ const uno::Reference< XContentIdentifier >& xCreatorId,
+ const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners )
+ : m_pMyShell( pMyShell ),
+ m_xCreatorContent( xCreatorContent ),
+ m_xCreatorId( xCreatorId ),
+ m_sListeners( sListeners )
+{
+
+}
+
+
+void SAL_CALL
+PropertySetInfoChangeNotifier::notifyPropertyAdded( const rtl::OUString & aPropertyName )
+{
+ beans::PropertySetInfoChangeEvent aEvt( m_xCreatorContent,
+ aPropertyName,
+ -1,
+ beans::PropertySetInfoChange::PROPERTY_INSERTED );
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< beans::XPropertySetInfoChangeListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->propertySetInfoChange( aEvt );
+ }
+}
+
+
+void SAL_CALL
+PropertySetInfoChangeNotifier::notifyPropertyRemoved( const rtl::OUString & aPropertyName )
+{
+ beans::PropertySetInfoChangeEvent aEvt( m_xCreatorContent,
+ aPropertyName,
+ -1,
+ beans::PropertySetInfoChange::PROPERTY_REMOVED );
+
+ for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i )
+ {
+ uno::Reference< beans::XPropertySetInfoChangeListener > ref( m_sListeners[i],uno::UNO_QUERY );
+ if( ref.is() )
+ ref->propertySetInfoChange( aEvt );
+ }
+}
+
+
+/*********************************************************************************/
+/* */
+/* PropertySetInfoChangeNotifier */
+/* */
+/*********************************************************************************/
+
+
+PropertyChangeNotifier::PropertyChangeNotifier(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< XContent >& xCreatorContent,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId,
+ ListenerMap* pListeners )
+ : m_pMyShell( pMyShell ),
+ m_xCreatorContent( xCreatorContent ),
+ m_xCreatorId( xCreatorId ),
+ m_pListeners( pListeners )
+{
+}
+
+
+PropertyChangeNotifier::~PropertyChangeNotifier()
+{
+ delete m_pListeners;
+}
+
+
+void PropertyChangeNotifier::notifyPropertyChanged(
+ uno::Sequence< beans::PropertyChangeEvent > Changes )
+{
+ sal_Int32 j;
+
+ for( j = 0; j < Changes.getLength(); ++j )
+ Changes[j].Source = m_xCreatorContent;
+
+ // notify listeners for all Events
+
+ uno::Sequence< uno::Reference< uno::XInterface > > seqList = (*m_pListeners)[ rtl::OUString() ];
+ for( j = 0; j < seqList.getLength(); ++j )
+ {
+ uno::Reference< beans::XPropertiesChangeListener > aListener( seqList[j],uno::UNO_QUERY );
+ if( aListener.is() )
+ {
+ aListener->propertiesChange( Changes );
+ }
+ }
+
+ uno::Sequence< beans::PropertyChangeEvent > seq(1);
+ for( j = 0; j < Changes.getLength(); ++j )
+ {
+ seq[0] = Changes[j];
+ seqList = (*m_pListeners)[ seq[0].PropertyName ];
+
+ for( sal_Int32 i = 0; i < seqList.getLength(); ++i )
+ {
+ uno::Reference< beans::XPropertiesChangeListener > aListener( seqList[j],uno::UNO_QUERY );
+ if( aListener.is() )
+ {
+ aListener->propertiesChange( seq );
+ }
+ }
+ }
+}
diff --git a/ucb/source/ucp/file/filnot.hxx b/ucb/source/ucp/file/filnot.hxx
new file mode 100644
index 000000000000..24f982372328
--- /dev/null
+++ b/ucb/source/ucp/file/filnot.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILNOT_HXX_
+#define _FILNOT_HXX_
+
+#include <hash_map>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include "filglob.hxx"
+
+
+namespace fileaccess {
+
+ class shell;
+ class BaseContent;
+
+ class ContentEventNotifier
+ {
+ private:
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xOldId;
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > > m_sListeners;
+ public:
+
+ ContentEventNotifier(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners );
+
+ ContentEventNotifier(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xOldId,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners );
+
+ void notifyChildInserted( const rtl::OUString& aChildName );
+ void notifyDeleted( void );
+ void notifyRemoved( const rtl::OUString& aChildName );
+ void notifyExchanged( );
+ };
+
+
+ class PropertySetInfoChangeNotifier
+ {
+ private:
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId;
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > > m_sListeners;
+ public:
+ PropertySetInfoChangeNotifier(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners );
+
+ void SAL_CALL notifyPropertyAdded( const rtl::OUString & aPropertyName );
+ void SAL_CALL notifyPropertyRemoved( const rtl::OUString & aPropertyName );
+ };
+
+
+ typedef std::hash_map< rtl::OUString,
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >,
+ hashOUString,
+ equalOUString > ListenerMap;
+
+ class PropertyChangeNotifier
+ {
+ private:
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId;
+ ListenerMap* m_pListeners;
+ public:
+ PropertyChangeNotifier(
+ shell* pMyShell,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId,
+ ListenerMap* pListeners );
+
+ ~PropertyChangeNotifier();
+
+ void notifyPropertyChanged(
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyChangeEvent > seqChanged );
+ };
+
+
+ class Notifier
+ {
+ public:
+ // Side effect of this function is the change of the name
+ virtual ContentEventNotifier* cEXC( const rtl::OUString aNewName ) = 0;
+ // Side effect is the change of the state of the object to "deleted".
+ virtual ContentEventNotifier* cDEL( void ) = 0;
+ virtual ContentEventNotifier* cCEL( void ) = 0;
+ virtual PropertySetInfoChangeNotifier* cPSL( void ) = 0;
+ virtual PropertyChangeNotifier* cPCL( void ) = 0;
+ virtual rtl::OUString getKey( void ) = 0;
+ };
+
+
+} // end namespace fileaccess
+
+#endif
diff --git a/ucb/source/ucp/file/filprp.cxx b/ucb/source/ucp/file/filprp.cxx
new file mode 100644
index 000000000000..86c494cbd710
--- /dev/null
+++ b/ucb/source/ucp/file/filprp.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+#include "filprp.hxx"
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+
+
+#include "filinl.hxx"
+
+
+XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath )
+ : m_pMyShell( pMyShell ),
+ m_xProvider( pMyShell->m_pProvider ),
+ m_count( 0 ),
+ m_seq( 0 )
+{
+ m_pMyShell->m_pProvider->acquire();
+
+ shell::ContentMap::iterator it = m_pMyShell->m_aContent.find( aUnqPath );
+
+ shell::PropertySet& properties = *(it->second.properties);
+ shell::PropertySet::iterator it1 = properties.begin();
+
+ m_seq.realloc( properties.size() );
+
+ while( it1 != properties.end() )
+ {
+ m_seq[ m_count++ ] = beans::Property( it1->getPropertyName(),
+ it1->getHandle(),
+ it1->getType(),
+ it1->getAttributes() );
+ ++it1;
+ }
+}
+
+
+XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const Sequence< beans::Property >& seq )
+ : m_pMyShell( pMyShell ),
+ m_count( seq.getLength() ),
+ m_seq( seq )
+{
+ m_pMyShell->m_pProvider->acquire();
+}
+
+
+XPropertySetInfo_impl::~XPropertySetInfo_impl()
+{
+ m_pMyShell->m_pProvider->release();
+}
+
+
+void SAL_CALL
+XPropertySetInfo_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XPropertySetInfo_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+XTYPEPROVIDER_IMPL_2( XPropertySetInfo_impl,
+ lang::XTypeProvider,
+ beans::XPropertySetInfo )
+
+
+Any SAL_CALL
+XPropertySetInfo_impl::queryInterface(
+ const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*,this),
+ SAL_STATIC_CAST( beans::XPropertySetInfo*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+beans::Property SAL_CALL
+XPropertySetInfo_impl::getPropertyByName(
+ const rtl::OUString& aName )
+ throw( beans::UnknownPropertyException,
+ RuntimeException)
+{
+ for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
+ if( m_seq[i].Name == aName ) return m_seq[i];
+
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+
+Sequence< beans::Property > SAL_CALL
+XPropertySetInfo_impl::getProperties(
+ void )
+ throw( RuntimeException )
+{
+ return m_seq;
+}
+
+
+sal_Bool SAL_CALL
+XPropertySetInfo_impl::hasPropertyByName(
+ const rtl::OUString& aName )
+ throw( RuntimeException )
+{
+ for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
+ if( m_seq[i].Name == aName ) return true;
+ return false;
+}
diff --git a/ucb/source/ucp/file/filprp.hxx b/ucb/source/ucp/file/filprp.hxx
new file mode 100644
index 000000000000..24d1bf324339
--- /dev/null
+++ b/ucb/source/ucp/file/filprp.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILPRP_HXX_
+#define _FILPRP_HXX_
+
+#include <ucbhelper/macros.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+
+
+namespace fileaccess {
+
+ class shell;
+
+ class XPropertySetInfo_impl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::beans::XPropertySetInfo
+ {
+ public:
+ XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath );
+ XPropertySetInfo_impl( shell* pMyShell,const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq );
+
+ virtual ~XPropertySetInfo_impl();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property > SAL_CALL
+ getProperties(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::beans::Property SAL_CALL
+ getPropertyByName(
+ const rtl::OUString& aName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasPropertyByName( const rtl::OUString& Name )
+ throw( com::sun::star::uno::RuntimeException );
+
+ private:
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider;
+ sal_Int32 m_count;
+ com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_seq;
+ };
+}
+
+#endif
+
diff --git a/ucb/source/ucp/file/filrec.cxx b/ucb/source/ucp/file/filrec.cxx
new file mode 100644
index 000000000000..c0e9b02ddb70
--- /dev/null
+++ b/ucb/source/ucp/file/filrec.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "filrec.hxx"
+
+namespace fileaccess {
+
+void ReconnectingFile::disconnect()
+{
+ m_aFile.close();
+ m_bDisconnect = sal_True;
+}
+
+sal_Bool ReconnectingFile::reconnect()
+{
+ sal_Bool bResult = sal_False;
+ if ( m_bFlagsSet )
+ {
+ disconnect();
+ if ( m_aFile.open( m_nFlags ) == ::osl::FileBase::E_None
+ || m_aFile.open( OpenFlag_Read ) == ::osl::FileBase::E_None )
+ {
+ m_bDisconnect = sal_False;
+ bResult = sal_True;
+ }
+ }
+
+ return bResult;
+}
+
+::osl::FileBase::RC ReconnectingFile::open( sal_uInt32 uFlags )
+{
+ ::osl::FileBase::RC nResult = m_aFile.open( uFlags );
+ if ( nResult == ::osl::FileBase::E_None )
+ {
+ if ( uFlags & OpenFlag_Create )
+ m_nFlags = (uFlags & ( ~OpenFlag_Create )) | OpenFlag_Write;
+ else
+ m_nFlags = uFlags;
+
+ m_bFlagsSet = sal_True;
+ }
+
+ return nResult;
+}
+
+::osl::FileBase::RC ReconnectingFile::close()
+{
+ m_nFlags = 0;
+ m_bFlagsSet = sal_False;
+ m_bDisconnect = sal_False;
+
+ return m_aFile.close();
+}
+
+::osl::FileBase::RC ReconnectingFile::setPos( sal_uInt32 uHow, sal_Int64 uPos )
+{
+ ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK;
+
+ if ( uHow == Pos_Absolut && uPos > 0 )
+ {
+ if ( m_bDisconnect )
+ {
+ if ( reconnect() )
+ nRes = m_aFile.setPos( uHow, uPos );
+ }
+ else
+ {
+ // E_INVAL error code means in this case that
+ // the file handler is invalid
+ nRes = m_aFile.setPos( uHow, uPos );
+ if ( ( nRes == ::osl::FileBase::E_NETWORK
+ || nRes == ::osl::FileBase::E_INVAL )
+ && reconnect() )
+ nRes = m_aFile.setPos( uHow, uPos );
+ }
+ }
+ else
+ {
+ if ( !m_bDisconnect )
+ nRes = m_aFile.setPos( uHow, uPos );
+ }
+
+ return nRes;
+}
+
+::osl::FileBase::RC ReconnectingFile::getPos( sal_uInt64& uPos )
+{
+ if ( m_bDisconnect )
+ return ::osl::FileBase::E_NETWORK;
+
+ return m_aFile.getPos( uPos );
+}
+
+::osl::FileBase::RC ReconnectingFile::setSize( sal_uInt64 uSize )
+{
+ ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK;
+
+ if ( uSize == 0 )
+ {
+ if ( m_bDisconnect )
+ {
+ if ( reconnect() )
+ nRes = m_aFile.setSize( uSize );
+ }
+ else
+ {
+ // E_INVAL error code means in this case that
+ // the file handler is invalid
+ nRes = m_aFile.setSize( uSize );
+ if ( ( nRes == ::osl::FileBase::E_NETWORK
+ || nRes == ::osl::FileBase::E_INVAL )
+ && reconnect() )
+ nRes = m_aFile.setSize( uSize );
+ }
+ }
+ else
+ {
+ if ( !m_bDisconnect )
+ nRes = m_aFile.setSize( uSize );
+ }
+
+ return nRes;
+}
+
+::osl::FileBase::RC ReconnectingFile::getSize( sal_uInt64 &rSize )
+{
+ ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK;
+
+ if ( !m_bDisconnect )
+ nRes = m_aFile.getSize( rSize );
+
+ // E_INVAL error code means in this case that
+ // the file handler is invalid
+ if ( ( nRes == ::osl::FileBase::E_NETWORK
+ || nRes == ::osl::FileBase::E_INVAL )
+ && reconnect() )
+ {
+ nRes = m_aFile.getSize( rSize );
+
+ // the repairing should be disconnected, since the position might be wrong
+ // but the result should be retrieved
+ disconnect();
+ }
+
+ return nRes;
+}
+
+::osl::FileBase::RC ReconnectingFile::read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead )
+{
+ if ( m_bDisconnect )
+ return ::osl::FileBase::E_NETWORK;
+
+ return m_aFile.read( pBuffer, uBytesRequested, rBytesRead );
+}
+
+::osl::FileBase::RC ReconnectingFile::write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten)
+{
+ if ( m_bDisconnect )
+ return ::osl::FileBase::E_NETWORK;
+
+ return m_aFile.write( pBuffer, uBytesToWrite, rBytesWritten );
+}
+
+::osl::FileBase::RC ReconnectingFile::sync() const
+{
+ if ( m_bDisconnect )
+ return ::osl::FileBase::E_NETWORK;
+
+ return m_aFile.sync();
+}
+
+} // namespace fileaccess
+
diff --git a/ucb/source/ucp/file/filrec.hxx b/ucb/source/ucp/file/filrec.hxx
new file mode 100644
index 000000000000..90168da2c9a5
--- /dev/null
+++ b/ucb/source/ucp/file/filrec.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FILREC_HXX_
+#define _FILREC_HXX_
+
+#include <osl/file.hxx>
+
+namespace fileaccess {
+
+class ReconnectingFile
+{
+ ::osl::File m_aFile;
+
+ sal_uInt32 m_nFlags;
+ sal_Bool m_bFlagsSet;
+
+ sal_Bool m_bDisconnect;
+
+ ReconnectingFile( ReconnectingFile& );
+
+ ReconnectingFile& operator=( ReconnectingFile& );
+
+public:
+
+ ReconnectingFile( const ::rtl::OUString& aFileURL )
+ : m_aFile( aFileURL )
+ , m_nFlags( 0 )
+ , m_bFlagsSet( sal_False )
+ , m_bDisconnect( sal_False )
+ {}
+
+ ~ReconnectingFile()
+ {
+ close();
+ }
+
+ void disconnect();
+ sal_Bool reconnect();
+
+ ::osl::FileBase::RC open( sal_uInt32 uFlags );
+
+ ::osl::FileBase::RC close();
+
+ ::osl::FileBase::RC setPos( sal_uInt32 uHow, sal_Int64 uPos );
+
+ ::osl::FileBase::RC getPos( sal_uInt64& uPos );
+
+ ::osl::FileBase::RC setSize( sal_uInt64 uSize );
+
+ ::osl::FileBase::RC getSize( sal_uInt64 &rSize );
+
+ ::osl::FileBase::RC read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead );
+
+ ::osl::FileBase::RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten);
+
+ ::osl::FileBase::RC sync() const;
+};
+
+} // namespace fileaccess
+#endif // _FILREC_HXX_
+
diff --git a/ucb/source/ucp/file/filrow.cxx b/ucb/source/ucp/file/filrow.cxx
new file mode 100644
index 000000000000..5b135358cf31
--- /dev/null
+++ b/ucb/source/ucp/file/filrow.cxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filrow.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+//using namespace com::sun::star::ucb;
+
+
+// Funktion for TypeConverting
+
+
+template< class _type_ >
+sal_Bool convert( shell* pShell,
+ uno::Reference< script::XTypeConverter >& xConverter,
+ uno::Any& rValue,
+ _type_& aReturn )
+{
+ // Try first without converting
+ sal_Bool no_success = ! ( rValue >>= aReturn );
+
+ if ( no_success )
+ {
+ if( ! xConverter.is() )
+ {
+ xConverter = uno::Reference< script::XTypeConverter >(
+ pShell->m_xMultiServiceFactory->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.script.Converter" ) ),uno::UNO_QUERY );
+
+/* DBG_ASSERT( m_xTypeConverter.is(),
+ "PropertyValueSet::getTypeConverter() - "
+ "Service 'com.sun.star.script.Converter' n/a!" );*/
+ }
+
+ try
+ {
+ if( rValue.hasValue() )
+ {
+ uno::Any aConvertedValue
+ = xConverter->convertTo( rValue,getCppuType( static_cast< const _type_* >(0) ) );
+ no_success = ! ( aConvertedValue >>= aReturn );
+ }
+ else
+ no_success = sal_True;
+ }
+ catch ( lang::IllegalArgumentException )
+ {
+ no_success = sal_True;
+ }
+ catch ( script::CannotConvertException )
+ {
+ no_success = sal_True;
+ }
+ }
+ return no_success;
+}
+
+
+XRow_impl::XRow_impl( shell* pMyShell,const uno::Sequence< uno::Any >& seq )
+ : m_aValueMap( seq ),
+ m_pMyShell( pMyShell ),
+ m_xProvider( pMyShell->m_pProvider ),
+ m_xTypeConverter( 0 )
+{
+}
+
+XRow_impl::~XRow_impl()
+{
+}
+
+
+void SAL_CALL
+XRow_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL
+XRow_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+uno::Any SAL_CALL
+XRow_impl::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*,this),
+ SAL_STATIC_CAST( sdbc::XRow*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+XTYPEPROVIDER_IMPL_2( XRow_impl,
+ lang::XTypeProvider,
+ sdbc::XRow )
+
+
+sal_Bool SAL_CALL
+XRow_impl::wasNull(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ return m_nWasNull;
+}
+
+
+rtl::OUString SAL_CALL
+XRow_impl::getString(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ rtl::OUString Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<rtl::OUString>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+sal_Bool SAL_CALL
+XRow_impl::getBoolean(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ sal_Bool Value( false );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<sal_Bool>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+
+sal_Int8 SAL_CALL
+XRow_impl::getByte(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ sal_Int8 Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<sal_Int8>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+sal_Int16 SAL_CALL
+XRow_impl::getShort(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ sal_Int16 Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<sal_Int16>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+
+sal_Int32 SAL_CALL
+XRow_impl::getInt(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ sal_Int32 Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<sal_Int32>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+sal_Int64 SAL_CALL
+XRow_impl::getLong(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ sal_Int64 Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<sal_Int64>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+float SAL_CALL
+XRow_impl::getFloat(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ float Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<float>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+double SAL_CALL
+XRow_impl::getDouble(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ double Value( 0 );
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<double>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL
+XRow_impl::getBytes(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Sequence< sal_Int8 > Value(0);
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Sequence< sal_Int8 > >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+util::Date SAL_CALL
+XRow_impl::getDate(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ util::Date Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<util::Date>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+util::Time SAL_CALL
+XRow_impl::getTime(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ util::Time Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<util::Time>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+util::DateTime SAL_CALL
+XRow_impl::getTimestamp(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ util::DateTime Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<util::DateTime>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+
+uno::Reference< io::XInputStream > SAL_CALL
+XRow_impl::getBinaryStream(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< io::XInputStream > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Reference< io::XInputStream > >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+
+uno::Reference< io::XInputStream > SAL_CALL
+XRow_impl::getCharacterStream(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< io::XInputStream > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert< uno::Reference< io::XInputStream> >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+
+uno::Any SAL_CALL
+XRow_impl::getObject(
+ sal_Int32 columnIndex,
+ const uno::Reference< container::XNameAccess >& )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Any Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Any>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value );
+ return Value;
+}
+
+uno::Reference< sdbc::XRef > SAL_CALL
+XRow_impl::getRef(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< sdbc::XRef > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Reference< sdbc::XRef> >( m_pMyShell,
+ m_xTypeConverter,
+ m_aValueMap[ --columnIndex ],
+ Value );
+ return Value;
+}
+
+uno::Reference< sdbc::XBlob > SAL_CALL
+XRow_impl::getBlob(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< sdbc::XBlob > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Reference< sdbc::XBlob> >( m_pMyShell,
+ m_xTypeConverter,
+ m_aValueMap[ --columnIndex ],
+ Value );
+ return Value;
+}
+
+uno::Reference< sdbc::XClob > SAL_CALL
+XRow_impl::getClob(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< sdbc::XClob > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Reference< sdbc::XClob> >( m_pMyShell,
+ m_xTypeConverter,
+ m_aValueMap[ --columnIndex ],
+ Value );
+ return Value;
+}
+
+
+uno::Reference< sdbc::XArray > SAL_CALL
+XRow_impl::getArray(
+ sal_Int32 columnIndex )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ uno::Reference< sdbc::XArray > Value;
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nWasNull = ::convert<uno::Reference< sdbc::XArray> >( m_pMyShell,
+ m_xTypeConverter,
+ m_aValueMap[ --columnIndex ],
+ Value );
+ return Value;
+}
diff --git a/ucb/source/ucp/file/filrow.hxx b/ucb/source/ucp/file/filrow.hxx
new file mode 100644
index 000000000000..bc8954da3510
--- /dev/null
+++ b/ucb/source/ucp/file/filrow.hxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILROW_HXX_
+#define _FILROW_HXX_
+
+#include <ucbhelper/macros.hxx>
+
+#include "osl/mutex.hxx"
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+
+namespace fileaccess {
+
+ class shell;
+
+ class XRow_impl:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::sdbc::XRow
+ {
+ public:
+ XRow_impl( shell* pShell,const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& __m_aValueMap );
+ ~XRow_impl();
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ virtual sal_Bool SAL_CALL
+ wasNull(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getString(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ getBoolean(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int8 SAL_CALL
+ getByte(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int16 SAL_CALL
+ getShort(
+ sal_Int32 columnIndex )
+ throw(
+ com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ getInt(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL
+ getLong(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual float SAL_CALL
+ getFloat(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual double SAL_CALL
+ getDouble(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject(
+ sal_Int32 columnIndex,
+ const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL
+ getRef(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL
+ getClob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL
+ getArray(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ private:
+ osl::Mutex m_aMutex;
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_aValueMap;
+ sal_Bool m_nWasNull;
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider;
+ com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > m_xTypeConverter;
+ };
+
+} // end namespace fileaccess
+
+#endif
diff --git a/ucb/source/ucp/file/filrset.cxx b/ucb/source/ucp/file/filrset.cxx
new file mode 100644
index 000000000000..5dcdd8445556
--- /dev/null
+++ b/ucb/source/ucp/file/filrset.cxx
@@ -0,0 +1,936 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
+#include "filid.hxx"
+#include "shell.hxx"
+#include "filprp.hxx"
+#include "filrset.hxx"
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include "prov.hxx"
+#include <com/sun/star/uno/Reference.h>
+
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/XSourceInitialization.hpp>
+#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
+#include <ucbhelper/resultsetmetadata.hxx>
+
+using namespace fileaccess;
+using namespace com::sun::star;
+
+XResultSet_impl::XResultSet_impl(
+ shell* pMyShell,
+ const rtl::OUString& aUnqPath,
+ sal_Int32 OpenMode,
+ const uno::Sequence< beans::Property >& seq,
+ const uno::Sequence< ucb::NumberedSortingInfo >& seqSort )
+ : m_pMyShell( pMyShell ),
+ m_xProvider( pMyShell->m_pProvider ),
+ m_nRow( -1 ),
+ m_nOpenMode( OpenMode ),
+ m_bRowCountFinal( false ),
+ m_aBaseDirectory( aUnqPath ),
+ m_aFolder( aUnqPath ),
+ m_sProperty( seq ),
+ m_sSortingInfo( seqSort ),
+ m_pDisposeEventListeners( 0 ),
+ m_pRowCountListeners( 0 ),
+ m_pIsFinalListeners( 0 ),
+ m_bStatic( false ),
+ m_nErrorCode( TASKHANDLER_NO_ERROR ),
+ m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
+{
+ osl::FileBase::RC err = m_aFolder.open();
+ if( err != osl::FileBase::E_None )
+ {
+ m_nIsOpen = false;
+ m_aFolder.close();
+
+ m_nErrorCode = TASKHANDLING_OPEN_FOR_DIRECTORYLISTING;
+ m_nMinorErrorCode = err;
+ }
+ else
+ m_nIsOpen = true;
+
+ m_pMyShell->registerNotifier( m_aBaseDirectory,this );
+}
+
+
+XResultSet_impl::~XResultSet_impl()
+{
+ m_pMyShell->deregisterNotifier( m_aBaseDirectory,this );
+
+ if( m_nIsOpen )
+ m_aFolder.close();
+
+ delete m_pDisposeEventListeners;
+ delete m_pRowCountListeners;
+ delete m_pIsFinalListeners;
+}
+
+
+
+sal_Int32 SAL_CALL XResultSet_impl::CtorSuccess()
+{
+ return m_nErrorCode;
+}
+
+
+
+sal_Int32 SAL_CALL XResultSet_impl::getMinorError()
+{
+ return m_nMinorErrorCode;
+}
+
+
+void SAL_CALL
+XResultSet_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XResultSet_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+uno::Any SAL_CALL
+XResultSet_impl::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XComponent*, this),
+ SAL_STATIC_CAST( lang::XTypeProvider*, this),
+ SAL_STATIC_CAST( lang::XEventListener*, this),
+ SAL_STATIC_CAST( sdbc::XRow*, this),
+ SAL_STATIC_CAST( sdbc::XResultSet*, this),
+ SAL_STATIC_CAST( sdbc::XCloseable*, this),
+ SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this),
+ SAL_STATIC_CAST( beans::XPropertySet*, this ),
+ SAL_STATIC_CAST( ucb::XContentAccess*, this),
+ SAL_STATIC_CAST( ucb::XDynamicResultSet*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+void SAL_CALL
+XResultSet_impl::disposing( const lang::EventObject& )
+ throw( uno::RuntimeException )
+{
+ // To do, but what
+}
+
+
+XTYPEPROVIDER_IMPL_10( XResultSet_impl,
+ lang::XTypeProvider,
+ lang::XTypeProvider,
+ lang::XEventListener,
+ sdbc::XRow,
+ sdbc::XResultSet,
+ XDynamicResultSet,
+ sdbc::XCloseable,
+ sdbc::XResultSetMetaDataSupplier,
+ beans::XPropertySet,
+ ucb::XContentAccess )
+
+
+void SAL_CALL
+XResultSet_impl::addEventListener(
+ const uno::Reference< lang::XEventListener >& Listener )
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ! m_pDisposeEventListeners )
+ m_pDisposeEventListeners =
+ new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+
+void SAL_CALL
+XResultSet_impl::removeEventListener(
+ const uno::Reference< lang::XEventListener >& Listener )
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+
+
+void SAL_CALL
+XResultSet_impl::dispose()
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ lang::EventObject aEvt;
+ aEvt.Source = static_cast< lang::XComponent * >( this );
+
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+ if( m_pRowCountListeners && m_pRowCountListeners->getLength() )
+ {
+ m_pRowCountListeners->disposeAndClear( aEvt );
+ }
+ if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() )
+ {
+ m_pIsFinalListeners->disposeAndClear( aEvt );
+ }
+}
+
+
+
+void XResultSet_impl::rowCountChanged()
+{
+ sal_Int32 aOldValue,aNewValue;
+ uno::Sequence< uno::Reference< uno::XInterface > > seq;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if( m_pRowCountListeners )
+ seq = m_pRowCountListeners->getElements();
+ aNewValue = m_aItems.size();
+ aOldValue = aNewValue-1;
+ }
+ beans::PropertyChangeEvent aEv;
+ aEv.PropertyName = rtl::OUString::createFromAscii( "RowCount" );
+ aEv.Further = false;
+ aEv.PropertyHandle = -1;
+ aEv.OldValue <<= aOldValue;
+ aEv.NewValue <<= aNewValue;
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ uno::Reference< beans::XPropertyChangeListener > listener(
+ seq[i], uno::UNO_QUERY );
+ if( listener.is() )
+ listener->propertyChange( aEv );
+ }
+}
+
+
+void XResultSet_impl::isFinalChanged()
+{
+ uno::Sequence< uno::Reference< XInterface > > seq;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if( m_pIsFinalListeners )
+ seq = m_pIsFinalListeners->getElements();
+ m_bRowCountFinal = true;
+ }
+ beans::PropertyChangeEvent aEv;
+ aEv.PropertyName = rtl::OUString::createFromAscii( "IsRowCountFinal" );
+ aEv.Further = false;
+ aEv.PropertyHandle = -1;
+ sal_Bool fval = false;
+ sal_Bool tval = true;
+ aEv.OldValue <<= fval;
+ aEv.NewValue <<= tval;
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ uno::Reference< beans::XPropertyChangeListener > listener(
+ seq[i], uno::UNO_QUERY );
+ if( listener.is() )
+ listener->propertyChange( aEv );
+ }
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::OneMore(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ if( ! m_nIsOpen )
+ return false;
+
+ osl::FileBase::RC err;
+ sal_Bool IsRegular;
+ rtl::OUString aUnqPath;
+ osl::DirectoryItem m_aDirIte;
+ uno::Reference< sdbc::XRow > aRow;
+
+ while( true )
+ {
+ err = m_aFolder.getNextItem( m_aDirIte );
+
+ if( err == osl::FileBase::E_NOENT || err == osl::FileBase::E_INVAL )
+ {
+ m_aFolder.close();
+ isFinalChanged();
+ return ( m_nIsOpen = false );
+ }
+ else if( err == osl::FileBase::E_None )
+ {
+ aRow = m_pMyShell->getv(
+ this, m_sProperty, m_aDirIte, aUnqPath, IsRegular );
+
+ if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && IsRegular )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_aItems.push_back( aRow );
+ m_aIdents.push_back(
+ uno::Reference< ucb::XContentIdentifier >() );
+ m_aUnqPath.push_back( aUnqPath );
+ rowCountChanged();
+ return true;
+
+ }
+ else if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && ! IsRegular )
+ {
+ continue;
+ }
+ else if( m_nOpenMode == ucb::OpenMode::FOLDERS && ! IsRegular )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_aItems.push_back( aRow );
+ m_aIdents.push_back(
+ uno::Reference< ucb::XContentIdentifier >() );
+ m_aUnqPath.push_back( aUnqPath );
+ rowCountChanged();
+ return true;
+ }
+ else if( m_nOpenMode == ucb::OpenMode::FOLDERS && IsRegular )
+ {
+ continue;
+ }
+ else
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_aItems.push_back( aRow );
+ m_aIdents.push_back(
+ uno::Reference< ucb::XContentIdentifier >() );
+ m_aUnqPath.push_back( aUnqPath );
+ rowCountChanged();
+ return true;
+ }
+ }
+ else // error fetching anything
+ {
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ }
+ }
+}
+
+
+
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::next(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ sal_Bool test;
+ if( ++m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) test = true;
+ else
+ test = OneMore();
+ return test;
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::isBeforeFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow == -1;
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::isAfterLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()); // Cannot happen, if m_aFolder.isOpen()
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::isFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow == 0;
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::isLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( m_nRow == sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1 )
+ return ! OneMore();
+ else
+ return false;
+}
+
+
+void SAL_CALL
+XResultSet_impl::beforeFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ m_nRow = -1;
+}
+
+
+void SAL_CALL
+XResultSet_impl::afterLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size());
+ while( OneMore() )
+ ++m_nRow;
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::first(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ m_nRow = -1;
+ return next();
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::last(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1;
+ while( OneMore() )
+ ++m_nRow;
+ return true;
+}
+
+
+sal_Int32 SAL_CALL
+XResultSet_impl::getRow(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ // Test, whether behind last row
+ if( -1 == m_nRow || m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return 0;
+ else
+ return m_nRow+1;
+}
+
+
+
+sal_Bool SAL_CALL XResultSet_impl::absolute( sal_Int32 row )
+ throw( sdbc::SQLException, uno::RuntimeException)
+{
+ if( row >= 0 )
+ {
+ m_nRow = row - 1;
+ if( row >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ while( row-- && OneMore() )
+ ;
+ }
+ else
+ {
+ last();
+ m_nRow += ( row + 1 );
+ if( m_nRow < -1 )
+ m_nRow = -1;
+ }
+
+ return 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::relative(
+ sal_Int32 row )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( isAfterLast() || isBeforeFirst() )
+ throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
+ if( row > 0 )
+ while( row-- ) next();
+ else if( row < 0 )
+ while( row++ && m_nRow > - 1 ) previous();
+
+ return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::previous(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( m_nRow > sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()); // Correct Handling of afterLast
+ if( 0 <= m_nRow ) -- m_nRow;
+
+ return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+void SAL_CALL
+XResultSet_impl::refreshRow(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ // get the row from the filesystem
+ return;
+}
+
+
+sal_Bool SAL_CALL
+XResultSet_impl::rowUpdated(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+sal_Bool SAL_CALL
+XResultSet_impl::rowInserted(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+sal_Bool SAL_CALL
+XResultSet_impl::rowDeleted(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+
+uno::Reference< uno::XInterface > SAL_CALL
+XResultSet_impl::getStatement(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return uno::Reference< uno::XInterface >();
+}
+
+
+// XCloseable
+
+void SAL_CALL
+XResultSet_impl::close(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( m_nIsOpen )
+ {
+ m_aFolder.close();
+ isFinalChanged();
+ osl::MutexGuard aGuard( m_aMutex );
+ m_nIsOpen = false;
+ }
+}
+
+
+
+rtl::OUString SAL_CALL
+XResultSet_impl::queryContentIdentifierString(
+ void )
+ throw( uno::RuntimeException )
+{
+ uno::Reference< ucb::XContentIdentifier > xContentId
+ = queryContentIdentifier();
+
+ if( xContentId.is() )
+ return xContentId->getContentIdentifier();
+ else
+ return rtl::OUString();
+}
+
+
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+XResultSet_impl::queryContentIdentifier(
+ void )
+ throw( uno::RuntimeException )
+{
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ {
+ if( ! m_aIdents[m_nRow].is() )
+ {
+ FileContentIdentifier* p
+ = new FileContentIdentifier( m_pMyShell,
+ m_aUnqPath[ m_nRow ] );
+ m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >(p);
+ }
+ return m_aIdents[m_nRow];
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+
+uno::Reference< ucb::XContent > SAL_CALL
+XResultSet_impl::queryContent(
+ void )
+ throw( uno::RuntimeException )
+{
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_pMyShell->m_pProvider->queryContent( queryContentIdentifier() );
+ else
+ return uno::Reference< ucb::XContent >();
+}
+
+
+// XDynamicResultSet
+
+
+// virtual
+uno::Reference< sdbc::XResultSet > SAL_CALL
+XResultSet_impl::getStaticResultSet()
+ throw( ucb::ListenerAlreadySetException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_xListener.is() )
+ throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return uno::Reference< sdbc::XResultSet >( this );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+XResultSet_impl::setListener(
+ const uno::Reference< ucb::XDynamicResultSetListener >& Listener )
+ throw( ucb::ListenerAlreadySetException,
+ uno::RuntimeException )
+{
+ osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ if ( m_xListener.is() )
+ throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ m_xListener = Listener;
+
+ //////////////////////////////////////////////////////////////////////
+ // Create "welcome event" and send it to listener.
+ //////////////////////////////////////////////////////////////////////
+
+ // Note: We only have the implementation for a static result set at the
+ // moment (src590). The dynamic result sets passed to the listener
+ // are a fake. This implementation will never call "notify" at the
+ // listener to propagate any changes!!!
+
+ uno::Any aInfo;
+ aInfo <<= ucb::WelcomeDynamicResultSetStruct( this, /* "old" */
+ this /* "new" */ );
+
+ uno::Sequence< ucb::ListAction > aActions( 1 );
+ aActions.getArray()[ 0 ] = ucb::ListAction( 0, // Position; not used
+ 0, // Count; not used
+ ucb::ListActionType::WELCOME,
+ aInfo );
+ aGuard.clear();
+
+ Listener->notify(
+ ucb::ListEvent(
+ static_cast< cppu::OWeakObject * >( this ), aActions ) );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+XResultSet_impl::connectToCache(
+ const uno::Reference< ucb::XDynamicResultSet > & xCache )
+ throw( ucb::ListenerAlreadySetException,
+ ucb::AlreadyInitializedException,
+ ucb::ServiceNotFoundException,
+ uno::RuntimeException )
+{
+ uno::Reference< lang::XMultiServiceFactory > mxSMgr
+ = m_pMyShell->m_xMultiServiceFactory;
+
+ if( m_xListener.is() )
+ throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ if( m_bStatic )
+ throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ uno::Reference< ucb::XSourceInitialization > xTarget(
+ xCache, uno::UNO_QUERY );
+ if( xTarget.is() && mxSMgr.is() )
+ {
+ uno::Reference< ucb::XCachedDynamicResultSetStubFactory > xStubFactory;
+ try
+ {
+ xStubFactory
+ = uno::Reference< ucb::XCachedDynamicResultSetStubFactory >(
+ mxSMgr->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ if( xStubFactory.is() )
+ {
+ xStubFactory->connectToCache(
+ this, xCache,m_sSortingInfo, NULL );
+ return;
+ }
+ }
+ throw ucb::ServiceNotFoundException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+//=========================================================================
+// virtual
+sal_Int16 SAL_CALL
+XResultSet_impl::getCapabilities()
+ throw( uno::RuntimeException )
+{
+ // Never set ucb::ContentResultSetCapability::SORTED
+ // - Underlying content cannot provide sorted data...
+ return 0;
+}
+
+// XResultSetMetaDataSupplier
+uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
+XResultSet_impl::getMetaData(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ for ( sal_Int32 n = 0; n < m_sProperty.getLength(); ++n )
+ {
+ if ( m_sProperty.getConstArray()[ n ].Name.compareToAscii( "Title" )
+ == 0 )
+ {
+ // @@@ #82177# - Determine correct value!
+ sal_Bool bCaseSensitiveChildren = sal_False;
+
+ std::vector< ::ucbhelper::ResultSetColumnData >
+ aColumnData( m_sProperty.getLength() );
+ aColumnData[ n ].isCaseSensitive = bCaseSensitiveChildren;
+
+ ::ucbhelper::ResultSetMetaData* p =
+ new ::ucbhelper::ResultSetMetaData(
+ m_pMyShell->m_xMultiServiceFactory,
+ m_sProperty,
+ aColumnData );
+ return uno::Reference< sdbc::XResultSetMetaData >( p );
+ }
+ }
+
+ ::ucbhelper::ResultSetMetaData* p =
+ new ::ucbhelper::ResultSetMetaData(
+ m_pMyShell->m_xMultiServiceFactory, m_sProperty );
+ return uno::Reference< sdbc::XResultSetMetaData >( p );
+}
+
+
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+XResultSet_impl::getPropertySetInfo()
+ throw( uno::RuntimeException)
+{
+
+ uno::Sequence< beans::Property > seq(2);
+ seq[0].Name = rtl::OUString::createFromAscii( "RowCount" );
+ seq[0].Handle = -1;
+ seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) );
+ seq[0].Attributes = beans::PropertyAttribute::READONLY;
+
+ seq[0].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" );
+ seq[0].Handle = -1;
+ seq[0].Type = getCppuType( static_cast< sal_Bool* >(0) );
+ seq[0].Attributes = beans::PropertyAttribute::READONLY;
+
+ XPropertySetInfo_impl* p = new XPropertySetInfo_impl( m_pMyShell,
+ seq );
+ return uno::Reference< beans::XPropertySetInfo > ( p );
+}
+
+
+
+void SAL_CALL XResultSet_impl::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& )
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ||
+ aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ return;
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+uno::Any SAL_CALL XResultSet_impl::getPropertyValue(
+ const rtl::OUString& PropertyName )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
+ {
+ uno::Any aAny;
+ aAny <<= m_bRowCountFinal;
+ return aAny;
+ }
+ else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ {
+ uno::Any aAny;
+ sal_Int32 count = sal::static_int_cast<sal_Int32>(m_aItems.size());
+ aAny <<= count;
+ return aAny;
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+void SAL_CALL XResultSet_impl::addPropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( ! m_pIsFinalListeners )
+ m_pIsFinalListeners =
+ new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+
+ m_pIsFinalListeners->addInterface( xListener );
+ }
+ else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( ! m_pRowCountListeners )
+ m_pRowCountListeners =
+ new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
+ m_pRowCountListeners->addInterface( xListener );
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+void SAL_CALL XResultSet_impl::removePropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& aListener )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) &&
+ m_pIsFinalListeners )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_pIsFinalListeners->removeInterface( aListener );
+ }
+ else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) &&
+ m_pRowCountListeners )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ m_pRowCountListeners->removeInterface( aListener );
+ }
+ else
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+void SAL_CALL XResultSet_impl::addVetoableChangeListener(
+ const rtl::OUString&,
+ const uno::Reference< beans::XVetoableChangeListener >& )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
+
+
+void SAL_CALL XResultSet_impl::removeVetoableChangeListener(
+ const rtl::OUString&,
+ const uno::Reference< beans::XVetoableChangeListener >& )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
diff --git a/ucb/source/ucp/file/filrset.hxx b/ucb/source/ucp/file/filrset.hxx
new file mode 100644
index 000000000000..977eddec8ccd
--- /dev/null
+++ b/ucb/source/ucp/file/filrset.hxx
@@ -0,0 +1,683 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILRSET_HXX_
+#define _FILRSET_HXX_
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+#include <ucbhelper/macros.hxx>
+#include <osl/file.hxx>
+
+#include "osl/mutex.hxx"
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#ifndef _COM_SUN_STAR_UCB_XDYNAMICRESULTSET_HPP__
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#endif
+#include <com/sun/star/ucb/XDynamicResultSetListener.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include "filrow.hxx"
+#include "filnot.hxx"
+
+
+
+namespace fileaccess {
+
+ class Notifier;
+
+ class XResultSet_impl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XEventListener,
+ public com::sun::star::sdbc::XRow,
+ public com::sun::star::sdbc::XResultSet,
+ public com::sun::star::ucb::XDynamicResultSet,
+ public com::sun::star::sdbc::XCloseable,
+ public com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ public com::sun::star::beans::XPropertySet,
+ public com::sun::star::ucb::XContentAccess,
+ public Notifier
+ {
+ public:
+
+ XResultSet_impl( shell* pMyShell,
+ const rtl::OUString& aUnqPath,
+ sal_Int32 OpenMode,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq,
+ const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort );
+
+ virtual ~XResultSet_impl();
+
+ virtual ContentEventNotifier* cDEL( void )
+ {
+ return 0;
+ }
+
+ virtual ContentEventNotifier* cEXC( const rtl::OUString )
+ {
+ return 0;
+ }
+
+ virtual ContentEventNotifier* cCEL( void )
+ {
+ return 0;
+ }
+
+ virtual PropertySetInfoChangeNotifier* cPSL( void )
+ {
+ return 0;
+ }
+
+ virtual PropertyChangeNotifier* cPCL( void )
+ {
+ return 0;
+ }
+
+ virtual rtl::OUString getKey( void )
+ {
+ return m_aBaseDirectory;
+ }
+
+ sal_Int32 SAL_CALL CtorSuccess();
+ sal_Int32 SAL_CALL getMinorError();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+
+ // XEventListener
+ virtual void SAL_CALL
+ disposing(
+ const com::sun::star::lang::EventObject& Source )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addEventListener(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XRow
+ virtual sal_Bool SAL_CALL
+ wasNull(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ m_nWasNull = m_aItems[m_nRow]->wasNull();
+ else
+ m_nWasNull = true;
+ return m_nWasNull;
+ }
+
+ virtual rtl::OUString SAL_CALL
+ getString(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getString( columnIndex );
+ else
+ return rtl::OUString();
+ }
+
+ virtual sal_Bool SAL_CALL
+ getBoolean(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBoolean( columnIndex );
+ else
+ return false;
+ }
+
+ virtual sal_Int8 SAL_CALL
+ getByte(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getByte( columnIndex );
+ else
+ return sal_Int8( 0 );
+ }
+
+ virtual sal_Int16 SAL_CALL
+ getShort(
+ sal_Int32 columnIndex )
+ throw(
+ com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getShort( columnIndex );
+ else
+ return sal_Int16( 0 );
+ }
+
+ virtual sal_Int32 SAL_CALL
+ getInt(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getInt( columnIndex );
+ else
+ return sal_Int32( 0 );
+ }
+
+ virtual sal_Int64 SAL_CALL
+ getLong(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getLong( columnIndex );
+ else
+ return sal_Int64( 0 );
+ }
+
+ virtual float SAL_CALL
+ getFloat(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getFloat( columnIndex );
+ else
+ return float( 0 );
+ }
+
+ virtual double SAL_CALL
+ getDouble(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getDouble( columnIndex );
+ else
+ return double( 0 );
+ }
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBytes( columnIndex );
+ else
+ return com::sun::star::uno::Sequence< sal_Int8 >();
+ }
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getDate( columnIndex );
+ else
+ return com::sun::star::util::Date();
+ }
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getTime( columnIndex );
+ else
+ return com::sun::star::util::Time();
+ }
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getTimestamp( columnIndex );
+ else
+ return com::sun::star::util::DateTime();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBinaryStream( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getCharacterStream( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >();
+ }
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject(
+ sal_Int32 columnIndex,
+ const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getObject( columnIndex,typeMap );
+ else
+ return com::sun::star::uno::Any();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL
+ getRef(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getRef( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XRef >();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBlob( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob >();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL
+ getClob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getClob( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XClob >();
+ }
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL
+ getArray(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getArray( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XArray >();
+ }
+
+
+ // XResultSet
+
+ virtual sal_Bool SAL_CALL
+ next(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isAfterLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ beforeFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ afterLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ first(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ last(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ getRow(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ absolute(
+ sal_Int32 row )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ relative(
+ sal_Int32 rows )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ previous(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ refreshRow(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowUpdated(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowInserted(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowDeleted(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+
+ virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ getStatement(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+
+ // XDynamicResultSet
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > SAL_CALL
+ getStaticResultSet(
+ void )
+ throw( com::sun::star::ucb::ListenerAlreadySetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ setListener(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XDynamicResultSetListener >& Listener )
+ throw( com::sun::star::ucb::ListenerAlreadySetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ connectToCache( const com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > & xCache )
+ throw( com::sun::star::ucb::ListenerAlreadySetException,
+ com::sun::star::ucb::AlreadyInitializedException,
+ com::sun::star::ucb::ServiceNotFoundException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL
+ getCapabilities()
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XCloseable
+
+ virtual void SAL_CALL
+ close(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ // XContentAccess
+
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ queryContent(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XResultSetMetaDataSupplier
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > SAL_CALL
+ getMetaData(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+
+ // XPropertySet
+ virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL setPropertyValue(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue(
+ const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removePropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ private:
+
+ // Members
+ // const uno::Reference< lang::XMultiServiceFactory > m_xMSF;
+ // const uno::Reference< ucb::XContentProvider > m_xProvider;
+
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider;
+ sal_Bool m_nIsOpen;
+ sal_Int32 m_nRow;
+ sal_Bool m_nWasNull;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bRowCountFinal;
+
+ typedef std::vector< com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > > IdentSet;
+ typedef std::vector< com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > > ItemSet;
+ typedef std::vector< rtl::OUString > UnqPathSet;
+
+ IdentSet m_aIdents;
+ ItemSet m_aItems;
+ UnqPathSet m_aUnqPath;
+ const rtl::OUString m_aBaseDirectory;
+
+ osl::Directory m_aFolder;
+ com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_sProperty;
+ com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > m_sSortingInfo;
+
+ osl::Mutex m_aMutex;
+ osl::Mutex m_aEventListenerMutex;
+ cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
+
+ cppu::OInterfaceContainerHelper* m_pRowCountListeners;
+ cppu::OInterfaceContainerHelper* m_pIsFinalListeners;
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSetListener > m_xListener;
+ sal_Bool m_bStatic;
+
+ sal_Int32 m_nErrorCode;
+ sal_Int32 m_nMinorErrorCode;
+
+ // Methods
+ sal_Bool SAL_CALL OneMore( void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException );
+
+ void rowCountChanged();
+ void isFinalChanged();
+ };
+
+
+} // end namespace fileaccess
+
+
+#endif
diff --git a/ucb/source/ucp/file/filstr.cxx b/ucb/source/ucp/file/filstr.cxx
new file mode 100644
index 000000000000..2e45e22b790b
--- /dev/null
+++ b/ucb/source/ucp/file/filstr.cxx
@@ -0,0 +1,404 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "com/sun/star/io/IOException.hpp"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "osl/diagnose.h"
+#include "filstr.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+
+/******************************************************************************/
+/* */
+/* XStream_impl implementation */
+/* */
+/******************************************************************************/
+
+
+uno::Any SAL_CALL
+XStream_impl::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException)
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*,this ),
+ SAL_STATIC_CAST( io::XStream*,this ),
+ SAL_STATIC_CAST( io::XInputStream*,this ),
+ SAL_STATIC_CAST( io::XOutputStream*,this ),
+ SAL_STATIC_CAST( io::XSeekable*,this ),
+ SAL_STATIC_CAST( io::XTruncate*,this ),
+ SAL_STATIC_CAST( io::XAsyncOutputMonitor*,this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+void SAL_CALL
+XStream_impl::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XStream_impl::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////////////////
+
+
+XTYPEPROVIDER_IMPL_7( XStream_impl,
+ lang::XTypeProvider,
+ io::XStream,
+ io::XSeekable,
+ io::XInputStream,
+ io::XOutputStream,
+ io::XTruncate,
+ io::XAsyncOutputMonitor )
+
+
+
+XStream_impl::XStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock )
+ : m_bInputStreamCalled( false ),
+ m_bOutputStreamCalled( false ),
+ m_pMyShell( pMyShell ),
+ m_xProvider( m_pMyShell->m_pProvider ),
+ m_bLock( bLock ),
+ m_aFile( aUncPath ),
+ m_nErrorCode( TASKHANDLER_NO_ERROR ),
+ m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
+{
+ sal_uInt32 nFlags = ( OpenFlag_Read | OpenFlag_Write );
+ if ( !bLock )
+ nFlags |= OpenFlag_NoLock;
+
+ osl::FileBase::RC err = m_aFile.open( nFlags );
+ if( err != osl::FileBase::E_None )
+ {
+ m_nIsOpen = false;
+ m_aFile.close();
+
+ m_nErrorCode = TASKHANDLING_OPEN_FOR_STREAM;
+ m_nMinorErrorCode = err;
+ }
+ else
+ m_nIsOpen = true;
+}
+
+
+XStream_impl::~XStream_impl()
+{
+ try
+ {
+ closeStream();
+ }
+ catch (io::IOException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+ catch (uno::RuntimeException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+}
+
+
+sal_Int32 SAL_CALL XStream_impl::CtorSuccess()
+{
+ return m_nErrorCode;
+}
+
+
+
+sal_Int32 SAL_CALL XStream_impl::getMinorError()
+{
+ return m_nMinorErrorCode;
+}
+
+
+
+uno::Reference< io::XInputStream > SAL_CALL
+XStream_impl::getInputStream( )
+ throw( uno::RuntimeException)
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = true;
+ }
+ return uno::Reference< io::XInputStream >( this );
+}
+
+
+uno::Reference< io::XOutputStream > SAL_CALL
+XStream_impl::getOutputStream( )
+ throw( uno::RuntimeException )
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = true;
+ }
+ return uno::Reference< io::XOutputStream >( this );
+}
+
+
+void SAL_CALL XStream_impl::truncate(void)
+ throw( io::IOException, uno::RuntimeException )
+{
+ if (osl::FileBase::E_None != m_aFile.setSize(0))
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ if (osl::FileBase::E_None != m_aFile.setPos(Pos_Absolut,sal_uInt64(0)))
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+
+//===========================================================================
+// XStream_impl private non interface methods
+//===========================================================================
+
+sal_Int32 SAL_CALL
+XStream_impl::readBytes(
+ uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ if( ! m_nIsOpen )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ sal_Int8 * buffer;
+ try
+ {
+ buffer = new sal_Int8[nBytesToRead];
+ }
+ catch( std::bad_alloc )
+ {
+ if( m_nIsOpen ) m_aFile.close();
+ throw io::BufferSizeExceededException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+
+ sal_uInt64 nrc(0);
+ if(m_aFile.read( (void* )buffer,sal_uInt64(nBytesToRead),nrc )
+ != osl::FileBase::E_None)
+ {
+ delete[] buffer;
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ aData = uno::Sequence< sal_Int8 > ( buffer, (sal_uInt32)nrc );
+ delete[] buffer;
+ return ( sal_Int32 ) nrc;
+}
+
+
+sal_Int32 SAL_CALL
+XStream_impl::readSomeBytes(
+ uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ return readBytes( aData,nMaxBytesToRead );
+}
+
+
+void SAL_CALL
+XStream_impl::skipBytes(
+ sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) );
+}
+
+
+sal_Int32 SAL_CALL
+XStream_impl::available(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ return 0;
+}
+
+
+void SAL_CALL
+XStream_impl::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ sal_uInt32 length = aData.getLength();
+ if(length)
+ {
+ sal_uInt64 nWrittenBytes(0);
+ const sal_Int8* p = aData.getConstArray();
+ if(osl::FileBase::E_None != m_aFile.write(((void*)(p)),sal_uInt64(length),nWrittenBytes) ||
+ nWrittenBytes != length )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+}
+
+
+void SAL_CALL
+XStream_impl::closeStream(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if( m_nIsOpen )
+ {
+ osl::FileBase::RC err = m_aFile.close();
+
+ if( err != osl::FileBase::E_None ) {
+ io::IOException ex;
+ ex.Message = rtl::OUString::createFromAscii(
+ "could not close file");
+ throw ex;
+ }
+
+ m_nIsOpen = false;
+ }
+}
+
+void SAL_CALL
+XStream_impl::closeInput(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = false;
+
+ if( ! m_bOutputStreamCalled )
+ closeStream();
+}
+
+
+void SAL_CALL
+XStream_impl::closeOutput(
+ void )
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = false;
+
+ if( ! m_bInputStreamCalled )
+ closeStream();
+}
+
+
+void SAL_CALL
+XStream_impl::seek(
+ sal_Int64 location )
+ throw( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if( location < 0 )
+ throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
+ if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+sal_Int64 SAL_CALL
+XStream_impl::getPosition(
+ void )
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ sal_uInt64 uPos;
+ if( osl::FileBase::E_None != m_aFile.getPos( uPos ) )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ return sal_Int64( uPos );
+}
+
+sal_Int64 SAL_CALL
+XStream_impl::getLength(
+ void )
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ sal_uInt64 uEndPos;
+ if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None )
+ throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ else
+ return sal_Int64( uEndPos );
+}
+
+void SAL_CALL
+XStream_impl::flush()
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{}
+
+void XStream_impl::waitForCompletion()
+ throw (io::IOException, uno::RuntimeException)
+{
+ // At least on UNIX, to reliably learn about any errors encountered by
+ // asynchronous NFS write operations, without closing the file directly
+ // afterwards, there appears to be no cheaper way than to call fsync:
+ if (m_nIsOpen && m_aFile.sync() != osl::FileBase::E_None) {
+ throw io::IOException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "could not synchronize file to disc")),
+ static_cast< OWeakObject * >(this));
+ }
+}
diff --git a/ucb/source/ucp/file/filstr.hxx b/ucb/source/ucp/file/filstr.hxx
new file mode 100644
index 000000000000..b5ffae2a5ea2
--- /dev/null
+++ b/ucb/source/ucp/file/filstr.hxx
@@ -0,0 +1,246 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILSTR_HXX_
+#define _FILSTR_HXX_
+
+#include <osl/mutex.hxx>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include "com/sun/star/io/XAsyncOutputMonitor.hpp"
+#include <com/sun/star/ucb/XContentProvider.hpp>
+
+#include "filrec.hxx"
+
+namespace fileaccess {
+
+ // forward:
+ class shell;
+ class XInputStreamForStream;
+ class XOutputStreamForStream;
+
+ class XStream_impl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::io::XStream,
+ public com::sun::star::io::XSeekable,
+ public com::sun::star::io::XInputStream,
+ public com::sun::star::io::XOutputStream,
+ public com::sun::star::io::XTruncate,
+ public com::sun::star::io::XAsyncOutputMonitor
+ {
+ friend class XInputStreamForStream;
+ friend class XOutputStreamForStream;
+
+ public:
+
+ XStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock );
+
+ /**
+ * Returns an error code as given by filerror.hxx
+ */
+
+ sal_Int32 SAL_CALL CtorSuccess();
+ sal_Int32 SAL_CALL getMinorError();
+
+ virtual ~XStream_impl();
+
+
+ // OWeakObject
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+
+ // XStream
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ getInputStream( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
+ getOutputStream( )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XTruncate
+
+ virtual void SAL_CALL truncate( void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+
+ // XInputStream
+
+ sal_Int32 SAL_CALL
+ readBytes(
+ com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ sal_Int32 SAL_CALL
+ readSomeBytes(
+ com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+
+ void SAL_CALL
+ skipBytes(
+ sal_Int32 nBytesToSkip )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Int32 SAL_CALL
+ available(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL
+ closeInput(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XSeekable
+
+ void SAL_CALL
+ seek(
+ sal_Int64 location )
+ throw( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Int64 SAL_CALL
+ getPosition(
+ void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Int64 SAL_CALL
+ getLength(
+ void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+
+ // XOutputStream
+
+ void SAL_CALL
+ writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+
+
+ void SAL_CALL
+ flush()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+
+ void SAL_CALL
+ closeOutput(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL waitForCompletion()
+ throw (
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ private:
+
+ osl::Mutex m_aMutex;
+ bool m_bInputStreamCalled,m_bOutputStreamCalled;
+
+ shell* m_pMyShell;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider;
+ sal_Bool m_nIsOpen;
+
+ sal_Bool m_bLock;
+
+ ReconnectingFile m_aFile;
+
+ sal_Int32 m_nErrorCode;
+ sal_Int32 m_nMinorErrorCode;
+
+ // Implementation methods
+
+ void SAL_CALL
+ closeStream(
+ void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ };
+
+} // end namespace XStream_impl
+
+#endif
diff --git a/ucb/source/ucp/file/filtask.cxx b/ucb/source/ucp/file/filtask.cxx
new file mode 100644
index 000000000000..a1350bb4cfaf
--- /dev/null
+++ b/ucb/source/ucp/file/filtask.cxx
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "filtask.hxx"
+#include "filglob.hxx"
+
+/******************************************************************************/
+/* */
+/* TaskHandling */
+/* */
+/******************************************************************************/
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+
+
+
+TaskManager::TaskManager()
+ : m_nCommandId( 0 )
+{
+}
+
+
+
+TaskManager::~TaskManager()
+{
+}
+
+
+
+void SAL_CALL
+TaskManager::startTask(
+ sal_Int32 CommandId,
+ const uno::Reference< XCommandEnvironment >& xCommandEnv )
+ throw( DuplicateCommandIdentifierException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it != m_aTaskMap.end() )
+ {
+ throw DuplicateCommandIdentifierException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ m_aTaskMap[ CommandId ] = TaskHandling( xCommandEnv );
+}
+
+
+
+void SAL_CALL
+TaskManager::endTask( sal_Int32 CommandId,
+ const rtl::OUString& aUncPath,
+ BaseContent* pContent)
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it == m_aTaskMap.end() )
+ return;
+
+ sal_Int32 ErrorCode = it->second.getInstalledError();
+ sal_Int32 MinorCode = it->second.getMinorErrorCode();
+ bool isHandled = it->second.isHandled();
+
+ Reference< XCommandEnvironment > xComEnv
+ = it->second.getCommandEnvironment();
+
+ m_aTaskMap.erase( it );
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ throw_handler(
+ ErrorCode,
+ MinorCode,
+ xComEnv,
+ aUncPath,
+ pContent,
+ isHandled);
+}
+
+
+
+void SAL_CALL
+TaskManager::abort( sal_Int32 CommandId )
+{
+ if( CommandId )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it == m_aTaskMap.end() )
+ return;
+ else
+ it->second.abort();
+ }
+}
+
+
+void SAL_CALL TaskManager::clearError( sal_Int32 CommandId )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it != m_aTaskMap.end() )
+ it->second.clearError();
+}
+
+
+void SAL_CALL TaskManager::retrieveError( sal_Int32 CommandId,
+ sal_Int32 &ErrorCode,
+ sal_Int32 &minorCode)
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it != m_aTaskMap.end() )
+ {
+ ErrorCode = it->second.getInstalledError();
+ minorCode = it->second. getMinorErrorCode();
+ }
+}
+
+
+
+void SAL_CALL TaskManager::installError( sal_Int32 CommandId,
+ sal_Int32 ErrorCode,
+ sal_Int32 MinorCode )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ if( it != m_aTaskMap.end() )
+ it->second.installError( ErrorCode,MinorCode );
+}
+
+
+
+sal_Int32 SAL_CALL
+TaskManager::getCommandId( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ return ++m_nCommandId;
+}
+
+
+
+void SAL_CALL TaskManager::handleTask(
+ sal_Int32 CommandId,
+ const uno::Reference< task::XInteractionRequest >& request )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ TaskMap::iterator it = m_aTaskMap.find( CommandId );
+ uno::Reference< task::XInteractionHandler > xInt;
+ if( it != m_aTaskMap.end() )
+ {
+ xInt = it->second.getInteractionHandler();
+ if( xInt.is() )
+ xInt->handle( request );
+ it->second.setHandled();
+ }
+}
diff --git a/ucb/source/ucp/file/filtask.hxx b/ucb/source/ucp/file/filtask.hxx
new file mode 100644
index 000000000000..6ce4f35b4240
--- /dev/null
+++ b/ucb/source/ucp/file/filtask.hxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FILTASK_HXX_
+#define _FILTASK_HXX_
+#endif
+
+#include <hash_map>
+#include <rtl/ustring.hxx>
+
+#include "osl/mutex.hxx"
+#include <com/sun/star/ucb/DuplicateCommandIdentifierException.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include "filerror.hxx"
+
+
+namespace fileaccess
+{
+ class BaseContent;
+
+ /*
+ * This implementation is inherited by class fileaccess::shell.
+ * The relevant methods in this class all have as first argument the CommandId,
+ * so if necessary, every method has access to its relevant XInteractionHandler and
+ * XProgressHandler.
+ */
+
+
+ class TaskManager
+ {
+ protected:
+
+ class TaskHandling
+ {
+ private:
+
+ bool m_bAbort,m_bHandled;
+ sal_Int32 m_nErrorCode,m_nMinorCode;
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInteractionHandler;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XProgressHandler > m_xProgressHandler;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xCommandEnvironment;
+
+
+ public:
+
+ TaskHandling(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xCommandEnv
+ = com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >( 0 ) )
+ : m_bAbort( false ),
+ m_bHandled( false ),
+ m_nErrorCode( TASKHANDLER_NO_ERROR ),
+ m_nMinorCode( TASKHANDLER_NO_ERROR ),
+ m_xInteractionHandler( 0 ),
+ m_xProgressHandler( 0 ),
+ m_xCommandEnvironment( xCommandEnv )
+ {
+ }
+
+ void SAL_CALL abort()
+ {
+ m_bAbort = true;
+ }
+
+ void setHandled()
+ {
+ m_bHandled = true;
+ }
+
+ bool isHandled()
+ {
+ return true;
+ }
+
+ void clearError()
+ {
+ m_nErrorCode = TASKHANDLER_NO_ERROR;
+ m_nMinorCode = TASKHANDLER_NO_ERROR;
+ }
+
+ void SAL_CALL installError( sal_Int32 nErrorCode,
+ sal_Int32 nMinorCode = TASKHANDLER_NO_ERROR )
+ {
+ m_nErrorCode = nErrorCode;
+ m_nMinorCode = nMinorCode;
+ }
+
+ sal_Int32 SAL_CALL getInstalledError()
+ {
+ return m_nErrorCode;
+ }
+
+ sal_Int32 SAL_CALL getMinorErrorCode()
+ {
+ return m_nMinorCode;
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XProgressHandler > SAL_CALL
+ getProgressHandler()
+ {
+ if( ! m_xProgressHandler.is() && m_xCommandEnvironment.is() )
+ m_xProgressHandler = m_xCommandEnvironment->getProgressHandler();
+
+ return m_xProgressHandler;
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler()
+ {
+ if( ! m_xInteractionHandler.is() && m_xCommandEnvironment.is() )
+ m_xInteractionHandler = m_xCommandEnvironment->getInteractionHandler();
+
+ return m_xInteractionHandler;
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > SAL_CALL
+ getCommandEnvironment()
+ {
+ return m_xCommandEnvironment;
+ }
+
+ }; // end class TaskHandling
+
+
+ typedef std::hash_map< sal_Int32,TaskHandling,std::hash< sal_Int32 > > TaskMap;
+
+
+ private:
+
+ osl::Mutex m_aMutex;
+ sal_Int32 m_nCommandId;
+ TaskMap m_aTaskMap;
+
+
+ public:
+
+ TaskManager();
+ virtual ~TaskManager();
+
+ void SAL_CALL startTask(
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xCommandEnv )
+ throw( com::sun::star::ucb::DuplicateCommandIdentifierException );
+
+ sal_Int32 SAL_CALL getCommandId( void );
+ void SAL_CALL abort( sal_Int32 CommandId );
+
+
+ /**
+ * The error code may be one of the error codes defined in
+ * filerror.hxx.
+ * The minor code refines the information given in ErrorCode.
+ */
+
+ void SAL_CALL clearError();
+
+ void SAL_CALL installError( sal_Int32 CommandId,
+ sal_Int32 ErrorCode,
+ sal_Int32 minorCode = TASKHANDLER_NO_ERROR );
+
+
+// void SAL_CALL installError( sal_Int32 CommandId,
+// sal_Int32 ErrorCode,
+// rtl::OUString message );
+
+// void SAL_CALL installError( sal_Int32 CommandId,
+// sal_Int32 ErrorCode,
+// rtl::OUString message );
+
+ void SAL_CALL retrieveError( sal_Int32 CommandId,
+ sal_Int32 &ErrorCode,
+ sal_Int32 &minorCode);
+
+ /**
+ * Deinstalls the task and evaluates a possibly set error code.
+ * "endTask" throws in case an error code is set the corresponding exception.
+ */
+
+ void SAL_CALL endTask( sal_Int32 CommandId,
+ // the physical URL of the object
+ const rtl::OUString& aUnqPath,
+ BaseContent* pContent);
+
+
+ /**
+ * Handles an interactionrequest
+ */
+
+ void SAL_CALL handleTask( sal_Int32 CommandId,
+ const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& request );
+
+ /**
+ * Clears any error which are set on the commandid
+ */
+
+ void SAL_CALL clearError( sal_Int32 );
+
+ };
+
+} // end namespace TaskHandling
diff --git a/ucb/source/ucp/file/makefile.mk b/ucb/source/ucp/file/makefile.mk
new file mode 100644
index 000000000000..8007a2492399
--- /dev/null
+++ b/ucb/source/ucp/file/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+TARGET=ucpfile
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCPFILE_MAJOR=1
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/prov.obj \
+ $(SLO)$/bc.obj \
+ $(SLO)$/shell.obj \
+ $(SLO)$/filtask.obj \
+ $(SLO)$/filrow.obj \
+ $(SLO)$/filrset.obj \
+ $(SLO)$/filid.obj \
+ $(SLO)$/filnot.obj \
+ $(SLO)$/filprp.obj \
+ $(SLO)$/filinpstr.obj \
+ $(SLO)$/filstr.obj \
+ $(SLO)$/filcmd.obj \
+ $(SLO)$/filglob.obj \
+ $(SLO)$/filinsreq.obj \
+ $(SLO)$/filrec.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(UCPFILE_MAJOR)
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(TARGET)
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+.IF "$(GUI)" == "OS2"
+DEF1EXPORTFILE=exports2.dxp
+.ENDIF
+
+DEF1NAME=$(SHL1TARGET)
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/file/prov.cxx b/ucb/source/ucp/file/prov.cxx
new file mode 100644
index 000000000000..a456d2acbd32
--- /dev/null
+++ b/ucb/source/ucp/file/prov.cxx
@@ -0,0 +1,738 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <osl/security.hxx>
+#include <osl/file.hxx>
+#include <osl/socket.h>
+#include <cppuhelper/factory.hxx>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#include <com/sun/star/ucb/FileSystemNotation.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include "filglob.hxx"
+#include "filid.hxx"
+#include "shell.hxx"
+#include "bc.hxx"
+#include "prov.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::container;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // File Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ fileaccess::shell::getImplementationName_static(),
+ fileaccess::shell::getSupportedServiceNames_static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // File Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( fileaccess::shell::getImplementationName_static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = FileProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+/****************************************************************************/
+/* */
+/* */
+/* FileProvider */
+/* */
+/* */
+/****************************************************************************/
+
+
+
+FileProvider::FileProvider( const Reference< XMultiServiceFactory >& xMultiServiceFactory )
+ : m_xMultiServiceFactory( xMultiServiceFactory ),
+ m_pMyShell( 0 )
+{
+}
+
+
+FileProvider::~FileProvider()
+{
+ if( m_pMyShell )
+ delete m_pMyShell;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// XInterface
+//////////////////////////////////////////////////////////////////////////
+
+void SAL_CALL
+FileProvider::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+FileProvider::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+Any SAL_CALL
+FileProvider::queryInterface(
+ const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( XContentProvider*, this ),
+ SAL_STATIC_CAST( XInitialization*, this ),
+ SAL_STATIC_CAST( XContentIdentifierFactory*, this ),
+ SAL_STATIC_CAST( XServiceInfo*, this ),
+ SAL_STATIC_CAST( XTypeProvider*, this ),
+ SAL_STATIC_CAST( XFileIdentifierConverter*,this ),
+ SAL_STATIC_CAST( XPropertySet*, this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// XInitialization
+
+void SAL_CALL FileProvider::init()
+{
+ if( ! m_pMyShell )
+ m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True );
+}
+
+
+void SAL_CALL
+FileProvider::initialize(
+ const Sequence< Any >& aArguments )
+ throw (Exception, RuntimeException)
+{
+ if( ! m_pMyShell ) {
+ rtl::OUString config;
+ if( aArguments.getLength() > 0 &&
+ (aArguments[0] >>= config) &&
+ config.compareToAscii("NoConfig") == 0 )
+ m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_False );
+ else
+ m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// XTypeProvider methods.
+
+
+XTYPEPROVIDER_IMPL_7( FileProvider,
+ XTypeProvider,
+ XServiceInfo,
+ XInitialization,
+ XContentIdentifierFactory,
+ XPropertySet,
+ XFileIdentifierConverter,
+ XContentProvider )
+
+
+////////////////////////////////////////////////////////////////////////////////
+// XServiceInfo methods.
+
+rtl::OUString SAL_CALL
+FileProvider::getImplementationName()
+ throw( RuntimeException )
+{
+ return fileaccess::shell::getImplementationName_static();
+}
+
+
+sal_Bool SAL_CALL
+FileProvider::supportsService(
+ const rtl::OUString& ServiceName )
+ throw( RuntimeException )
+{
+ return ServiceName == rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" );
+}
+
+
+Sequence< rtl::OUString > SAL_CALL
+FileProvider::getSupportedServiceNames(
+ void )
+ throw( RuntimeException )
+{
+ return fileaccess::shell::getSupportedServiceNames_static();
+}
+
+
+
+Reference< XSingleServiceFactory > SAL_CALL
+FileProvider::createServiceFactory(
+ const Reference< XMultiServiceFactory >& rxServiceMgr )
+{
+ /**
+ * Create a single service factory.<BR>
+ * Note: The function pointer ComponentInstantiation points to a function throws Exception.
+ *
+ * @param rServiceManager the service manager used by the implementation.
+ * @param rImplementationName the implementation name. An empty string is possible.
+ * @param ComponentInstantiation the function pointer to create an object.
+ * @param rServiceNames the service supported by the implementation.
+ * @return a factory that support the interfaces XServiceProvider, XServiceInfo
+ * XSingleServiceFactory and XComponent.
+ *
+ * @see createOneInstanceFactory
+ */
+ /*
+ * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory
+ * (
+ * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager,
+ * const ::rtl::OUString & rImplementationName,
+ * ComponentInstantiation pCreateFunction,
+
+ * const ::com::sun::star::Sequence< ::rtl::OUString > & rServiceNames
+ * );
+ */
+
+ return Reference< XSingleServiceFactory > ( cppu::createSingleFactory(
+ rxServiceMgr,
+ fileaccess::shell::getImplementationName_static(),
+ FileProvider::CreateInstance,
+ fileaccess::shell::getSupportedServiceNames_static() ) );
+}
+
+Reference< XInterface > SAL_CALL
+FileProvider::CreateInstance(
+ const Reference< XMultiServiceFactory >& xMultiServiceFactory )
+{
+ XServiceInfo* xP = (XServiceInfo*) new FileProvider( xMultiServiceFactory );
+ return Reference< XInterface >::query( xP );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// XContent
+////////////////////////////////////////////////////////////////////////////////
+
+
+Reference< XContent > SAL_CALL
+FileProvider::queryContent(
+ const Reference< XContentIdentifier >& xIdentifier )
+ throw( IllegalIdentifierException,
+ RuntimeException)
+{
+ init();
+ rtl::OUString aUnc;
+ sal_Bool err = m_pMyShell->getUnqFromUrl( xIdentifier->getContentIdentifier(),
+ aUnc );
+
+ if( err )
+ throw IllegalIdentifierException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ return Reference< XContent >( new BaseContent( m_pMyShell,xIdentifier,aUnc ) );
+}
+
+
+
+sal_Int32 SAL_CALL
+FileProvider::compareContentIds(
+ const Reference< XContentIdentifier >& Id1,
+ const Reference< XContentIdentifier >& Id2 )
+ throw( RuntimeException )
+{
+ init();
+ rtl::OUString aUrl1 = Id1->getContentIdentifier();
+ rtl::OUString aUrl2 = Id2->getContentIdentifier();
+
+ sal_Int32 iComp = aUrl1.compareTo( aUrl2 );
+
+ if ( 0 != iComp )
+ {
+ rtl::OUString aPath1, aPath2;
+
+ m_pMyShell->getUnqFromUrl( aUrl1, aPath1 );
+ m_pMyShell->getUnqFromUrl( aUrl2, aPath2 );
+
+ osl::FileBase::RC error;
+ osl::DirectoryItem aItem1, aItem2;
+
+ error = osl::DirectoryItem::get( aPath1, aItem1 );
+ if ( error == osl::FileBase::E_None )
+ error = osl::DirectoryItem::get( aPath2, aItem2 );
+
+ if ( error != osl::FileBase::E_None )
+ return iComp;
+
+ osl::FileStatus aStatus1( FileStatusMask_FileURL );
+ osl::FileStatus aStatus2( FileStatusMask_FileURL );
+ error = aItem1.getFileStatus( aStatus1 );
+ if ( error == osl::FileBase::E_None )
+ error = aItem2.getFileStatus( aStatus2 );
+
+ if ( error == osl::FileBase::E_None )
+ {
+ iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() );
+
+// Quick hack for Windows to threat all file systems as case insensitive
+#ifdef WNT
+ if ( 0 != iComp )
+ {
+ error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 );
+ if ( error == osl::FileBase::E_None )
+ error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 );
+
+ if ( error == osl::FileBase::E_None )
+ iComp = rtl_ustr_compareIgnoreAsciiCase( aPath1.getStr(), aPath2.getStr() );
+ }
+#endif
+ }
+ }
+
+ return iComp;
+}
+
+
+
+Reference< XContentIdentifier > SAL_CALL
+FileProvider::createContentIdentifier(
+ const rtl::OUString& ContentId )
+ throw( RuntimeException )
+{
+ init();
+ FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ContentId,false );
+ return Reference< XContentIdentifier >( p );
+}
+
+
+
+//XPropertySetInfoImpl
+
+class XPropertySetInfoImpl2
+ : public cppu::OWeakObject,
+ public XPropertySetInfo
+{
+public:
+ XPropertySetInfoImpl2();
+ ~XPropertySetInfoImpl2();
+
+ // XInterface
+ virtual Any SAL_CALL
+ queryInterface(
+ const Type& aType )
+ throw( RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ virtual Sequence< Property > SAL_CALL
+ getProperties(
+ void )
+ throw( RuntimeException );
+
+ virtual Property SAL_CALL
+ getPropertyByName(
+ const rtl::OUString& aName )
+ throw( UnknownPropertyException,
+ RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasPropertyByName( const rtl::OUString& Name )
+ throw( RuntimeException );
+
+
+private:
+ Sequence< Property > m_seq;
+};
+
+
+XPropertySetInfoImpl2::XPropertySetInfoImpl2()
+ : m_seq( 3 )
+{
+ m_seq[0] = Property( rtl::OUString::createFromAscii( "HostName" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ PropertyAttribute::READONLY );
+
+ m_seq[1] = Property( rtl::OUString::createFromAscii( "HomeDirectory" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ PropertyAttribute::READONLY );
+
+ m_seq[2] = Property( rtl::OUString::createFromAscii( "FileSystemNotation" ),
+ -1,
+ getCppuType( static_cast< sal_Int32* >( 0 ) ),
+ PropertyAttribute::READONLY );
+}
+
+
+XPropertySetInfoImpl2::~XPropertySetInfoImpl2()
+{
+ // nothing
+}
+
+
+void SAL_CALL
+XPropertySetInfoImpl2::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XPropertySetInfoImpl2::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+Any SAL_CALL
+XPropertySetInfoImpl2::queryInterface(
+ const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface( rType,
+ SAL_STATIC_CAST( XPropertySetInfo*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+Property SAL_CALL
+XPropertySetInfoImpl2::getPropertyByName(
+ const rtl::OUString& aName )
+ throw( UnknownPropertyException,
+ RuntimeException)
+{
+ for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
+ if( m_seq[i].Name == aName )
+ return m_seq[i];
+
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+
+Sequence< Property > SAL_CALL
+XPropertySetInfoImpl2::getProperties(
+ void )
+ throw( RuntimeException )
+{
+ return m_seq;
+}
+
+
+sal_Bool SAL_CALL
+XPropertySetInfoImpl2::hasPropertyByName(
+ const rtl::OUString& aName )
+ throw( RuntimeException )
+{
+ for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
+ if( m_seq[i].Name == aName )
+ return true;
+ return false;
+}
+
+
+
+
+
+void SAL_CALL FileProvider::initProperties( void )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ if( ! m_xPropertySetInfo.is() )
+ {
+ osl_getLocalHostname( &m_HostName.pData );
+
+#if defined ( UNX )
+ m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
+#elif defined( WNT ) || defined( OS2 )
+ m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
+#else
+ m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
+#endif
+ osl::Security aSecurity;
+ aSecurity.getHomeDir( m_HomeDirectory );
+
+ // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
+ // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
+ // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
+ // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
+
+ XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2();
+ m_xPropertySetInfo = Reference< XPropertySetInfo >( p );
+ }
+}
+
+
+// XPropertySet
+
+Reference< XPropertySetInfo > SAL_CALL
+FileProvider::getPropertySetInfo( )
+ throw( RuntimeException )
+{
+ initProperties();
+ return m_xPropertySetInfo;
+}
+
+
+void SAL_CALL
+FileProvider::setPropertyValue( const rtl::OUString& aPropertyName,
+ const Any& )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 ||
+ aPropertyName.compareToAscii( "HomeDirectory" ) == 0 ||
+ aPropertyName.compareToAscii( "HostName" ) == 0 )
+ return;
+ else
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+
+Any SAL_CALL
+FileProvider::getPropertyValue(
+ const rtl::OUString& aPropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ initProperties();
+ if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 )
+ {
+ Any aAny;
+ aAny <<= m_FileSystemNotation;
+ return aAny;
+ }
+ else if( aPropertyName.compareToAscii( "HomeDirectory" ) == 0 )
+ {
+ Any aAny;
+ aAny <<= m_HomeDirectory;
+ return aAny;
+ }
+ else if( aPropertyName.compareToAscii( "HostName" ) == 0 )
+ {
+ Any aAny;
+ aAny <<= m_HostName;
+ return aAny;
+ }
+ else
+ throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+}
+
+
+void SAL_CALL
+FileProvider::addPropertyChangeListener(
+ const rtl::OUString&,
+ const Reference< XPropertyChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ return;
+}
+
+
+void SAL_CALL
+FileProvider::removePropertyChangeListener(
+ const rtl::OUString&,
+ const Reference< XPropertyChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ return;
+}
+
+void SAL_CALL
+FileProvider::addVetoableChangeListener(
+ const rtl::OUString&,
+ const Reference< XVetoableChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ return;
+}
+
+
+void SAL_CALL
+FileProvider::removeVetoableChangeListener(
+ const rtl::OUString&,
+ const Reference< XVetoableChangeListener >& )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException)
+{
+ return;
+}
+
+
+
+// XFileIdentifierConverter
+
+sal_Int32 SAL_CALL
+FileProvider::getFileProviderLocality( const rtl::OUString& BaseURL )
+ throw( RuntimeException )
+{
+ // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
+ // return -1 (missmatch). What is missing is a fast comparison to ASCII,
+ // ignoring case:
+ return BaseURL.getLength() >= 5
+ && (BaseURL[0] == 'F' || BaseURL[0] == 'f')
+ && (BaseURL[1] == 'I' || BaseURL[1] == 'i')
+ && (BaseURL[2] == 'L' || BaseURL[2] == 'l')
+ && (BaseURL[3] == 'E' || BaseURL[3] == 'e')
+ && BaseURL[4] == ':' ?
+ 10 : -1;
+}
+
+rtl::OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const rtl::OUString&,
+ const rtl::OUString& SystemPath )
+ throw( RuntimeException )
+{
+ rtl::OUString aNormalizedPath;
+ if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
+ return rtl::OUString();
+
+ return aNormalizedPath;
+}
+
+rtl::OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const rtl::OUString& URL )
+ throw( RuntimeException )
+{
+ rtl::OUString aSystemPath;
+ if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
+ return rtl::OUString();
+
+ return aSystemPath;
+}
+
diff --git a/ucb/source/ucp/file/prov.hxx b/ucb/source/ucp/file/prov.hxx
new file mode 100644
index 000000000000..52f0ba35f3cb
--- /dev/null
+++ b/ucb/source/ucp/file/prov.hxx
@@ -0,0 +1,238 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PROV_HXX_
+#define _PROV_HXX_
+
+#include <cppuhelper/weak.hxx>
+
+#include "osl/mutex.hxx"
+#include <ucbhelper/macros.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ucb/XFileIdentifierConverter.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+// FileProvider
+
+
+
+namespace fileaccess {
+
+ // Forward declaration
+
+ class BaseContent;
+ class shell;
+
+ class FileProvider:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XInitialization,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XContentProvider,
+ public com::sun::star::ucb::XContentIdentifierFactory,
+ public com::sun::star::beans::XPropertySet,
+ public com::sun::star::ucb::XFileIdentifierConverter
+ {
+ friend class BaseContent;
+ public:
+
+ FileProvider( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF );
+ ~FileProvider();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService(
+ const rtl::OUString& ServiceName )
+ throw(com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ static com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > SAL_CALL
+ createServiceFactory(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxServiceMgr );
+
+ static com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ CreateInstance(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMultiServiceFactory );
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ queryContent(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+
+ // XContentIdentifierFactory
+
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ createContentIdentifier(
+ const rtl::OUString& ContentId )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ virtual sal_Int32 SAL_CALL
+ compareContentIds(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Id1,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Id2 )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XProperySet
+
+ virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ setPropertyValue(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue(
+ const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addPropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removePropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+
+ // XFileIdentifierConverter
+
+ virtual sal_Int32 SAL_CALL
+ getFileProviderLocality( const rtl::OUString& BaseURL )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getFileURLFromSystemPath( const rtl::OUString& BaseURL,
+ const rtl::OUString& SystemPath )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getSystemPathFromFileURL( const rtl::OUString& URL )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ private:
+ // methods
+ void SAL_CALL init();
+
+ // Members
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMultiServiceFactory;
+
+ void SAL_CALL initProperties( void );
+ osl::Mutex m_aMutex;
+ rtl::OUString m_HostName;
+ rtl::OUString m_HomeDirectory;
+ sal_Int32 m_FileSystemNotation;
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > m_xPropertySetInfo;
+
+ shell* m_pMyShell;
+ };
+
+} // end namespace fileaccess
+
+#endif
+
diff --git a/ucb/source/ucp/file/shell.cxx b/ucb/source/ucp/file/shell.cxx
new file mode 100644
index 000000000000..769e58c08819
--- /dev/null
+++ b/ucb/source/ucp/file/shell.cxx
@@ -0,0 +1,3068 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#ifndef INCLUDED_STL_STACK
+#include <stack>
+#define INCLUDED_STL_STACK
+#endif
+
+#include "osl/diagnose.h"
+#include <rtl/ustrbuf.hxx>
+#include <osl/time.h>
+#include <osl/file.hxx>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/beans/IllegalTypeException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument.hpp>
+#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <rtl/string.hxx>
+#include "filerror.hxx"
+#include "filglob.hxx"
+#include "filcmd.hxx"
+#include "filinpstr.hxx"
+#include "filstr.hxx"
+#include "filrset.hxx"
+#include "filrow.hxx"
+#include "filprp.hxx"
+#include "filid.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+#include "bc.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+shell::UnqPathData::UnqPathData()
+ : properties( 0 ),
+ notifier( 0 ),
+ xS( 0 ),
+ xC( 0 ),
+ xA( 0 )
+{
+ // empty
+}
+
+
+shell::UnqPathData::UnqPathData( const UnqPathData& a )
+ : properties( a.properties ),
+ notifier( a.notifier ),
+ xS( a.xS ),
+ xC( a.xC ),
+ xA( a.xA )
+{
+}
+
+
+shell::UnqPathData& shell::UnqPathData::operator=( UnqPathData& a )
+{
+ properties = a.properties;
+ notifier = a.notifier;
+ xS = a.xS;
+ xC = a.xC;
+ xA = a.xA;
+ a.properties = 0;
+ a.notifier = 0;
+ a.xS = 0;
+ a.xC = 0;
+ a.xA = 0;
+ return *this;
+}
+
+shell::UnqPathData::~UnqPathData()
+{
+ if( properties )
+ delete properties;
+ if( notifier )
+ delete notifier;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+shell::MyProperty::MyProperty( const rtl::OUString& __PropertyName )
+ : PropertyName( __PropertyName )
+{
+ // empty
+}
+
+
+shell::MyProperty::MyProperty( const sal_Bool& __isNative,
+ const rtl::OUString& __PropertyName,
+ const sal_Int32& __Handle,
+ const com::sun::star::uno::Type& __Typ,
+ const com::sun::star::uno::Any& __Value,
+ const com::sun::star::beans::PropertyState& __State,
+ const sal_Int16& __Attributes )
+ : PropertyName( __PropertyName ),
+ Handle( __Handle ),
+ isNative( __isNative ),
+ Typ( __Typ ),
+ Value( __Value ),
+ State( __State ),
+ Attributes( __Attributes )
+{
+ // empty
+}
+
+shell::MyProperty::~MyProperty()
+{
+ // empty for now
+}
+
+
+#include "filinl.hxx"
+
+
+shell::shell( const uno::Reference< lang::XMultiServiceFactory >& xMultiServiceFactory,
+ FileProvider* pProvider, sal_Bool bWithConfig )
+ : TaskManager(),
+ m_bWithConfig( bWithConfig ),
+ m_pProvider( pProvider ),
+ m_xMultiServiceFactory( xMultiServiceFactory ),
+ Title( rtl::OUString::createFromAscii( "Title" ) ),
+ CasePreservingURL(
+ rtl::OUString::createFromAscii( "CasePreservingURL" ) ),
+ IsDocument( rtl::OUString::createFromAscii( "IsDocument" ) ),
+ IsFolder( rtl::OUString::createFromAscii( "IsFolder" ) ),
+ DateModified( rtl::OUString::createFromAscii( "DateModified" ) ),
+ Size( rtl::OUString::createFromAscii( "Size" ) ),
+ IsVolume( rtl::OUString::createFromAscii( "IsVolume" ) ),
+ IsRemoveable( rtl::OUString::createFromAscii( "IsRemoveable" ) ),
+ IsRemote( rtl::OUString::createFromAscii( "IsRemote" ) ),
+ IsCompactDisc( rtl::OUString::createFromAscii( "IsCompactDisc" ) ),
+ IsFloppy( rtl::OUString::createFromAscii( "IsFloppy" ) ),
+ IsHidden( rtl::OUString::createFromAscii( "IsHidden" ) ),
+ ContentType( rtl::OUString::createFromAscii( "ContentType" ) ),
+ IsReadOnly( rtl::OUString::createFromAscii( "IsReadOnly" ) ),
+ CreatableContentsInfo( rtl::OUString::createFromAscii( "CreatableContentsInfo" ) ),
+ FolderContentType( rtl::OUString::createFromAscii( "application/vnd.sun.staroffice.fsys-folder" ) ),
+ FileContentType( rtl::OUString::createFromAscii( "application/vnd.sun.staroffice.fsys-file" ) ),
+ m_sCommandInfo( 9 )
+{
+ // Title
+ m_aDefaultProperties.insert( MyProperty( true,
+ Title,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // CasePreservingURL
+ m_aDefaultProperties.insert(
+ MyProperty( true,
+ CasePreservingURL,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // IsFolder
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsFolder,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // IsDocument
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsDocument,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Removable
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsVolume,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // Removable
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsRemoveable,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Remote
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsRemote,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // CompactDisc
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsCompactDisc,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Floppy
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsFloppy,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Hidden
+ m_aDefaultProperties.insert(
+ MyProperty(
+ true,
+ IsHidden,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+#if defined( WNT ) || defined( OS2 )
+ ));
+#else
+ | beans::PropertyAttribute::READONLY)); // under unix/linux only readable
+#endif
+
+
+ // ContentType
+ uno::Any aAny;
+ aAny <<= rtl::OUString();
+ m_aDefaultProperties.insert( MyProperty( false,
+ ContentType,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ aAny,
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // DateModified
+ m_aDefaultProperties.insert( MyProperty( true,
+ DateModified,
+ -1 ,
+ getCppuType( static_cast< util::DateTime* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // Size
+ m_aDefaultProperties.insert( MyProperty( true,
+ Size,
+ -1,
+ getCppuType( static_cast< sal_Int64* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // IsReadOnly
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsReadOnly,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+
+ // CreatableContentsInfo
+ m_aDefaultProperties.insert( MyProperty( true,
+ CreatableContentsInfo,
+ -1 ,
+ getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Commands
+ m_sCommandInfo[0].Name = rtl::OUString::createFromAscii( "getCommandInfo" );
+ m_sCommandInfo[0].Handle = -1;
+ m_sCommandInfo[0].ArgType = getCppuVoidType();
+
+ m_sCommandInfo[1].Name = rtl::OUString::createFromAscii( "getPropertySetInfo" );
+ m_sCommandInfo[1].Handle = -1;
+ m_sCommandInfo[1].ArgType = getCppuVoidType();
+
+ m_sCommandInfo[2].Name = rtl::OUString::createFromAscii( "getPropertyValues" );
+ m_sCommandInfo[2].Handle = -1;
+ m_sCommandInfo[2].ArgType = getCppuType( static_cast< uno::Sequence< beans::Property >* >( 0 ) );
+
+ m_sCommandInfo[3].Name = rtl::OUString::createFromAscii( "setPropertyValues" );
+ m_sCommandInfo[3].Handle = -1;
+ m_sCommandInfo[3].ArgType = getCppuType( static_cast< uno::Sequence< beans::PropertyValue >* >( 0 ) );
+
+ m_sCommandInfo[4].Name = rtl::OUString::createFromAscii( "open" );
+ m_sCommandInfo[4].Handle = -1;
+ m_sCommandInfo[4].ArgType = getCppuType( static_cast< OpenCommandArgument* >( 0 ) );
+
+ m_sCommandInfo[5].Name = rtl::OUString::createFromAscii( "transfer" );
+ m_sCommandInfo[5].Handle = -1;
+ m_sCommandInfo[5].ArgType = getCppuType( static_cast< TransferInfo* >( 0 ) );
+
+ m_sCommandInfo[6].Name = rtl::OUString::createFromAscii( "delete" );
+ m_sCommandInfo[6].Handle = -1;
+ m_sCommandInfo[6].ArgType = getCppuType( static_cast< sal_Bool* >( 0 ) );
+
+ m_sCommandInfo[7].Name = rtl::OUString::createFromAscii( "insert" );
+ m_sCommandInfo[7].Handle = -1;
+ m_sCommandInfo[7].ArgType = getCppuType( static_cast< InsertCommandArgument* > ( 0 ) );
+
+ m_sCommandInfo[7].Name = rtl::OUString::createFromAscii( "createNewContent" );
+ m_sCommandInfo[7].Handle = -1;
+ m_sCommandInfo[7].ArgType = getCppuType( static_cast< ucb::ContentInfo * > ( 0 ) );
+
+ if(m_bWithConfig)
+ {
+ rtl::OUString Store = rtl::OUString::createFromAscii( "com.sun.star.ucb.Store" );
+ uno::Reference< XPropertySetRegistryFactory > xRegFac(
+ m_xMultiServiceFactory->createInstance( Store ),
+ uno::UNO_QUERY );
+ if ( xRegFac.is() )
+ {
+ // Open/create a registry
+ m_xFileRegistry = xRegFac->createPropertySetRegistry( rtl::OUString() );
+ }
+ }
+}
+
+
+shell::~shell()
+{
+}
+
+
+/*********************************************************************************/
+/* */
+/* de/registerNotifier-Implementation */
+/* */
+/*********************************************************************************/
+
+//
+// This two methods register and deregister a change listener for the content belonging
+// to URL aUnqPath
+//
+
+void SAL_CALL
+shell::registerNotifier( const rtl::OUString& aUnqPath, Notifier* pNotifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it =
+ m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ if( ! it->second.notifier )
+ it->second.notifier = new NotifierList();
+
+ std::list< Notifier* >& nlist = *( it->second.notifier );
+
+ std::list<Notifier*>::iterator it1 = nlist.begin();
+ while( it1 != nlist.end() ) // Every "Notifier" only once
+ {
+ if( *it1 == pNotifier ) return;
+ ++it1;
+ }
+ nlist.push_back( pNotifier );
+}
+
+
+
+void SAL_CALL
+shell::deregisterNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.find( aUnqPath );
+ if( it == m_aContent.end() )
+ return;
+
+ it->second.notifier->remove( pNotifier );
+
+ if( ! it->second.notifier->size() )
+ m_aContent.erase( it );
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* de/associate-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Used to associate and deassociate a new property with
+// the content belonging to URL UnqPath.
+// The default value and the the attributes are input
+//
+
+void SAL_CALL
+shell::associate( const rtl::OUString& aUnqPath,
+ const rtl::OUString& PropertyName,
+ const uno::Any& DefaultValue,
+ const sal_Int16 Attributes )
+ throw( beans::PropertyExistException,
+ beans::IllegalTypeException,
+ uno::RuntimeException )
+{
+ MyProperty newProperty( false,
+ PropertyName,
+ -1,
+ DefaultValue.getValueType(),
+ DefaultValue,
+ beans::PropertyState_DEFAULT_VALUE,
+ Attributes );
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.find( newProperty );
+ if( it1 != m_aDefaultProperties.end() )
+ throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ // Load the XPersistentPropertySetInfo and create it, if it does not exist
+ load( it,true );
+
+ PropertySet& properties = *(it->second.properties);
+ it1 = properties.find( newProperty );
+ if( it1 != properties.end() )
+ throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Property does not exist
+ properties.insert( newProperty );
+ it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
+ }
+ notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
+}
+
+
+
+
+void SAL_CALL
+shell::deassociate( const rtl::OUString& aUnqPath,
+ const rtl::OUString& PropertyName )
+ throw( beans::UnknownPropertyException,
+ beans::NotRemoveableException,
+ uno::RuntimeException )
+{
+ MyProperty oldProperty( PropertyName );
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.find( oldProperty );
+ if( it1 != m_aDefaultProperties.end() )
+ throw beans::NotRemoveableException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ load( it,false );
+
+ PropertySet& properties = *(it->second.properties);
+
+ it1 = properties.find( oldProperty );
+ if( it1 == properties.end() )
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ properties.erase( it1 );
+
+ if( it->second.xC.is() )
+ it->second.xC->removeProperty( PropertyName );
+
+ if( properties.size() == 9 )
+ {
+ MyProperty ContentTProperty( ContentType );
+
+ if( properties.find( ContentTProperty )->getState() == beans::PropertyState_DEFAULT_VALUE )
+ {
+ it->second.xS = 0;
+ it->second.xC = 0;
+ it->second.xA = 0;
+ if(m_xFileRegistry.is())
+ m_xFileRegistry->removePropertySet( aUnqPath );
+ }
+ }
+ notifyPropertyRemoved( getPropertySetListeners( aUnqPath ), PropertyName );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* page-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given an xOutputStream, this method writes the content of the file belonging to
+// URL aUnqPath into the XOutputStream
+//
+
+
+void SAL_CALL shell::page( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const uno::Reference< io::XOutputStream >& xOutputStream )
+ throw()
+{
+ uno::Reference< XContentProvider > xProvider( m_pProvider );
+ osl::File aFile( aUnqPath );
+ osl::FileBase::RC err = aFile.open( OpenFlag_Read );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ installError( CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING,
+ err );
+ return;
+ }
+
+ const sal_uInt64 bfz = 4*1024;
+ sal_Int8 BFF[bfz];
+ sal_uInt64 nrc; // Retrieved number of Bytes;
+
+ do
+ {
+ err = aFile.read( (void*) BFF,bfz,nrc );
+ if( err == osl::FileBase::E_None )
+ {
+ uno::Sequence< sal_Int8 > seq( BFF, (sal_uInt32)nrc );
+ try
+ {
+ xOutputStream->writeBytes( seq );
+ }
+ catch( io::NotConnectedException )
+ {
+ installError( CommandId,
+ TASKHANDLING_NOTCONNECTED_FOR_PAGING );
+ break;
+ }
+ catch( io::BufferSizeExceededException )
+ {
+ installError( CommandId,
+ TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING );
+ break;
+ }
+ catch( io::IOException )
+ {
+ installError( CommandId,
+ TASKHANDLING_IOEXCEPTION_FOR_PAGING );
+ break;
+ }
+ }
+ else
+ {
+ installError( CommandId,
+ TASKHANDLING_READING_FILE_FOR_PAGING,
+ err );
+ break;
+ }
+ } while( nrc == bfz );
+
+
+ aFile.close();
+
+
+ try
+ {
+ xOutputStream->closeOutput();
+ }
+ catch( io::NotConnectedException )
+ {
+ }
+ catch( io::BufferSizeExceededException )
+ {
+ }
+ catch( io::IOException )
+ {
+ }
+}
+
+
+/*********************************************************************************/
+/* */
+/* open-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
+//
+
+
+uno::Reference< io::XInputStream > SAL_CALL
+shell::open( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw()
+{
+ XInputStream_impl* xInputStream = new XInputStream_impl( this, aUnqPath, bLock ); // from filinpstr.hxx
+
+ sal_Int32 ErrorCode = xInputStream->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ xInputStream->getMinorError() );
+
+ delete xInputStream;
+ xInputStream = 0;
+ }
+
+ return uno::Reference< io::XInputStream >( xInputStream );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* open for read/write access-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given a file URL aUnqPath, this methods returns a XStream which can be used
+// to read and write from/to the file.
+//
+
+
+uno::Reference< io::XStream > SAL_CALL
+shell::open_rw( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw()
+{
+ XStream_impl* xStream = new XStream_impl( this, aUnqPath, bLock ); // from filstr.hxx
+
+ sal_Int32 ErrorCode = xStream->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ xStream->getMinorError() );
+
+ delete xStream;
+ xStream = 0;
+ }
+ return uno::Reference< io::XStream >( xStream );
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* ls-Implementation */
+/* */
+/*********************************************************************************/
+//
+// This method returns the result set containing the the children of the directory belonging
+// to file URL aUnqPath
+//
+
+
+uno::Reference< XDynamicResultSet > SAL_CALL
+shell::ls( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const sal_Int32 OpenMode,
+ const uno::Sequence< beans::Property >& seq,
+ const uno::Sequence< NumberedSortingInfo >& seqSort )
+ throw()
+{
+ XResultSet_impl* p = new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort );
+
+ sal_Int32 ErrorCode = p->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ p->getMinorError() );
+
+ delete p;
+ p = 0;
+ }
+
+ return uno::Reference< XDynamicResultSet > ( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* info_c implementation */
+/* */
+/*********************************************************************************/
+// Info for commands
+
+uno::Reference< XCommandInfo > SAL_CALL
+shell::info_c()
+ throw()
+{
+ XCommandInfo_impl* p = new XCommandInfo_impl( this );
+ return uno::Reference< XCommandInfo >( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* info_p-Implementation */
+/* */
+/*********************************************************************************/
+// Info for the properties
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+shell::info_p( const rtl::OUString& aUnqPath )
+ throw()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ XPropertySetInfo_impl* p = new XPropertySetInfo_impl( this,aUnqPath );
+ return uno::Reference< beans::XPropertySetInfo >( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* setv-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Sets the values of the properties belonging to fileURL aUnqPath
+//
+
+
+uno::Sequence< uno::Any > SAL_CALL
+shell::setv( const rtl::OUString& aUnqPath,
+ const uno::Sequence< beans::PropertyValue >& values )
+ throw()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 propChanged = 0;
+ uno::Sequence< uno::Any > ret( values.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ PropertySet& properties = *( it->second.properties );
+ shell::PropertySet::iterator it1;
+ uno::Any aAny;
+
+ for( sal_Int32 i = 0; i < values.getLength(); ++i )
+ {
+ MyProperty toset( values[i].Name );
+ it1 = properties.find( toset );
+ if( it1 == properties.end() )
+ {
+ ret[i] <<= beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ continue;
+ }
+
+ aAny = it1->getValue();
+ if( aAny == values[i].Value )
+ continue; // nothing needs to be changed
+
+ if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
+ {
+ ret[i] <<= lang::IllegalAccessException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ continue;
+ }
+
+ seqChanged[ propChanged ].PropertyName = values[i].Name;
+ seqChanged[ propChanged ].PropertyHandle = -1;
+ seqChanged[ propChanged ].Further = false;
+ seqChanged[ propChanged ].OldValue <<= aAny;
+ seqChanged[ propChanged++ ].NewValue = values[i].Value;
+
+ it1->setValue( values[i].Value ); // Put the new value into the local cash
+
+ if( ! it1->IsNative() )
+ {
+ // Also put logical properties into storage
+ if( !it->second.xS.is() )
+ load( it,true );
+
+ if( ( values[i].Name == ContentType ) &&
+ it1->getState() == beans::PropertyState_DEFAULT_VALUE )
+ { // Special logic for ContentType
+ // 09.07.01: Not reached anymore, because ContentType is readonly
+ it1->setState( beans::PropertyState_DIRECT_VALUE );
+ it->second.xC->addProperty( values[i].Name,
+ beans::PropertyAttribute::MAYBEVOID,
+ values[i].Value );
+ }
+
+ try
+ {
+ it->second.xS->setPropertyValue( values[i].Name,values[i].Value );
+ }
+ catch( const uno::Exception& e )
+ {
+ --propChanged; // unsuccessful setting
+ ret[i] <<= e;
+ }
+ }
+ else
+ {
+ // native properties
+ // Setting of physical file properties
+ if( values[i].Name == Size )
+ {
+ sal_Int64 newSize = 0;
+ if( values[i].Value >>= newSize )
+ { // valid value for the size
+ osl::File aFile(aUnqPath);
+ bool err =
+ aFile.open(OpenFlag_Write) != osl::FileBase::E_None ||
+ aFile.setSize(sal_uInt64(newSize)) != osl::FileBase::E_None ||
+ aFile.close() != osl::FileBase::E_None;
+
+ if( err )
+ {
+ --propChanged; // unsuccessful setting
+ uno::Sequence< uno::Any > names( 1 );
+ ret[0] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(aUnqPath),
+ beans::PropertyState_DIRECT_VALUE);
+ IOErrorCode ioError(IOErrorCode_GENERAL);
+ ret[i] <<= InteractiveAugmentedIOException(
+ rtl::OUString(),
+ 0,
+ task::InteractionClassification_ERROR,
+ ioError,
+ names );
+ }
+ }
+ else
+ ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if(values[i].Name == IsReadOnly ||
+ values[i].Name == IsHidden)
+ {
+ sal_Bool value = sal_False;
+ if( values[i].Value >>= value )
+ {
+ osl::DirectoryItem aDirItem;
+ osl::FileBase::RC err =
+ osl::DirectoryItem::get(aUnqPath,aDirItem);
+ sal_uInt64 nAttributes(0);
+ if(err == osl::FileBase::E_None)
+ {
+ osl::FileStatus aFileStatus(FileStatusMask_Attributes);
+ err = aDirItem.getFileStatus(aFileStatus);
+ if(err == osl::FileBase::E_None &&
+ aFileStatus.isValid(FileStatusMask_Attributes))
+ nAttributes = aFileStatus.getAttributes();
+ }
+ // now we have the attributes provided all went well.
+ if(err == osl::FileBase::E_None) {
+ if(values[i].Name == IsReadOnly)
+ {
+ nAttributes &= ~(Attribute_OwnWrite |
+ Attribute_GrpWrite |
+ Attribute_OthWrite |
+ Attribute_ReadOnly);
+ if(value)
+ nAttributes |= Attribute_ReadOnly;
+ else
+ nAttributes |= (
+ Attribute_OwnWrite |
+ Attribute_GrpWrite |
+ Attribute_OthWrite);
+ }
+ else if(values[i].Name == IsHidden)
+ {
+ nAttributes &= ~(Attribute_Hidden);
+ if(value)
+ nAttributes |= Attribute_Hidden;
+ }
+ err = osl::File::setAttributes(
+ aUnqPath,nAttributes);
+ }
+
+ if( err != osl::FileBase::E_None )
+ {
+ --propChanged; // unsuccessful setting
+ uno::Sequence< uno::Any > names( 1 );
+ names[0] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(aUnqPath),
+ beans::PropertyState_DIRECT_VALUE);
+ IOErrorCode ioError;
+ switch( err )
+ {
+ case osl::FileBase::E_NOMEM:
+ // not enough memory for allocating structures <br>
+ ioError = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case osl::FileBase::E_INVAL:
+ // the format of the parameters was not valid<p>
+ ioError = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case osl::FileBase::E_NAMETOOLONG:
+ // File name too long<br>
+ ioError = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case osl::FileBase::E_NOENT:
+ // No such file or directory<br>
+ case osl::FileBase::E_NOLINK:
+ // Link has been severed<br>
+ ioError = IOErrorCode_NOT_EXISTING;
+ break;
+ case osl::FileBase::E_ROFS:
+ // #i4735# handle ROFS transparently
+ // as ACCESS_DENIED
+ case osl::FileBase::E_PERM:
+ case osl::FileBase::E_ACCES:
+ // permission denied<br>
+ ioError = IOErrorCode_ACCESS_DENIED;
+ break;
+ case osl::FileBase::E_LOOP:
+ // Too many symbolic links encountered<br>
+ case osl::FileBase::E_FAULT:
+ // Bad address<br>
+ case osl::FileBase::E_IO:
+ // I/O error<br>
+ case osl::FileBase::E_NOSYS:
+ // Function not implemented<br>
+ case osl::FileBase::E_MULTIHOP:
+ // Multihop attempted<br>
+ case osl::FileBase::E_INTR:
+ // function call was interrupted<p>
+ default:
+ ioError = IOErrorCode_GENERAL;
+ break;
+ }
+ ret[i] <<= InteractiveAugmentedIOException(
+ rtl::OUString(),
+ 0,
+ task::InteractionClassification_ERROR,
+ ioError,
+ names );
+ }
+ }
+ else
+ ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+ } // end for
+
+ if( propChanged )
+ {
+ seqChanged.realloc( propChanged );
+ notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath ),seqChanged );
+ }
+
+ return ret;
+}
+
+/*********************************************************************************/
+/* */
+/* getv-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Reads the values of the properties belonging to fileURL aUnqPath;
+// Returns an XRow object containing the values in the requested order.
+//
+
+
+uno::Reference< sdbc::XRow > SAL_CALL
+shell::getv( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const uno::Sequence< beans::Property >& properties )
+ throw()
+{
+ uno::Sequence< uno::Any > seq( properties.getLength() );
+
+ sal_Int32 n_Mask;
+ getMaskFromProperties( n_Mask,properties );
+ osl::FileStatus aFileStatus( n_Mask );
+
+ osl::DirectoryItem aDirItem;
+ osl::FileBase::RC nError1 = osl::DirectoryItem::get( aUnqPath,aDirItem );
+ if( nError1 != osl::FileBase::E_None )
+ installError(CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
+ nError1);
+
+ osl::FileBase::RC nError2 = aDirItem.getFileStatus( aFileStatus );
+ if( nError1 == osl::FileBase::E_None &&
+ nError2 != osl::FileBase::E_None )
+ installError(CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
+ nError2);
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ commit( it,aFileStatus );
+
+ shell::PropertySet::iterator it1;
+ PropertySet& propset = *(it->second.properties);
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( properties[i].Name );
+ it1 = propset.find( readProp );
+ if( it1 == propset.end() )
+ seq[i] = uno::Any();
+ else
+ seq[i] = it1->getValue();
+ }
+ }
+
+ XRow_impl* p = new XRow_impl( this,seq );
+ return uno::Reference< sdbc::XRow >( p );
+}
+
+
+/********************************************************************************/
+/* */
+/* transfer-commandos */
+/* */
+/********************************************************************************/
+
+
+/********************************************************************************/
+/* */
+/* move-implementation */
+/* */
+/********************************************************************************/
+//
+// Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
+//
+
+void SAL_CALL
+shell::move( sal_Int32 CommandId,
+ const rtl::OUString srcUnqPath,
+ const rtl::OUString dstUnqPathIn,
+ const sal_Int32 NameClash )
+ throw()
+{
+ // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
+ // srcUnqPath and dstUnqPathIn are equal
+ if( srcUnqPath == dstUnqPathIn )
+ return;
+ // <--
+ //
+ osl::FileBase::RC nError;
+ rtl::OUString dstUnqPath( dstUnqPathIn );
+
+ switch( NameClash )
+ {
+ case NameClash::KEEP:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_KEEPERROR_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::OVERWRITE:
+ {
+ // stat to determine whether we have a symlink
+ rtl::OUString targetPath(dstUnqPath);
+
+ osl::FileStatus aStatus(FileStatusMask_Type|FileStatusMask_LinkTargetURL);
+ osl::DirectoryItem aItem;
+ osl::DirectoryItem::get(dstUnqPath,aItem);
+ aItem.getFileStatus(aStatus);
+
+ if( aStatus.isValid(FileStatusMask_Type) &&
+ aStatus.isValid(FileStatusMask_LinkTargetURL) &&
+ aStatus.getFileType() == osl::FileStatus::Link )
+ targetPath = aStatus.getLinkTargetURL();
+
+ // Will do nothing if file does not exist.
+ osl::File::remove( targetPath );
+
+ nError = osl_File_move( srcUnqPath,targetPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_OVERWRITE_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::RENAME:
+ {
+ rtl::OUString newDstUnqPath;
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ // "invent" a new valid title.
+
+ sal_Int32 nPos = -1;
+ sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
+ sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
+ if( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
+ && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
+ nPos = nLastDot;
+ else
+ nPos = dstUnqPath.getLength();
+
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ newDstUnqPath = dstUnqPath;
+
+ rtl::OUString aPostFix( rtl::OUString::createFromAscii( "_" ) );
+ aPostFix += rtl::OUString::valueOf( ++nTry );
+
+ newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
+
+ nError = osl_File_move( srcUnqPath,newDstUnqPath,true );
+ }
+ while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
+ }
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAME_FOR_MOVE );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAMEMOVE_FOR_MOVE,
+ nError );
+ return;
+ }
+ else
+ dstUnqPath = newDstUnqPath;
+
+ break;
+ }
+ case NameClash::ERROR:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASH_FOR_MOVE );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHMOVE_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::ASK:
+ default:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE,
+ NameClash::ASK);
+ return;
+ }
+ }
+ break;
+ }
+
+ // Determine, whether we have moved a file or a folder
+ osl::DirectoryItem aItem;
+ nError = osl::DirectoryItem::get( dstUnqPath,aItem );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_TRANSFER_BY_MOVE_SOURCE,
+ nError );
+ return;
+ }
+ osl::FileStatus aStatus( FileStatusMask_Type );
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( FileStatusMask_Type ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT,
+ nError );
+ return;
+ }
+ sal_Bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );
+
+
+ copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );
+
+ rtl::OUString aDstParent = getParentName( dstUnqPath );
+ rtl::OUString aDstTitle = getTitle( dstUnqPath );
+
+ rtl::OUString aSrcParent = getParentName( srcUnqPath );
+ rtl::OUString aSrcTitle = getTitle( srcUnqPath );
+
+ notifyInsert( getContentEventListeners( aDstParent ),dstUnqPath );
+ if( aDstParent != aSrcParent )
+ notifyContentRemoved( getContentEventListeners( aSrcParent ),srcUnqPath );
+
+ notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) );
+ erasePersistentSet( srcUnqPath,!isDocument );
+}
+
+
+
+/********************************************************************************/
+/* */
+/* copy-implementation */
+/* */
+/********************************************************************************/
+//
+// Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
+//
+
+namespace {
+
+bool getType(
+ TaskManager & task, sal_Int32 id, rtl::OUString const & fileUrl,
+ osl::DirectoryItem * item, osl::FileStatus::Type * type)
+{
+ OSL_ASSERT(item != 0 && type != 0);
+ osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
+ if (err != osl::FileBase::E_None) {
+ task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCE, err);
+ return false;
+ }
+ osl::FileStatus stat(FileStatusMask_Type);
+ err = item->getFileStatus(stat);
+ if (err != osl::FileBase::E_None) {
+ task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, err);
+ return false;
+ }
+ *type = stat.getFileType();
+ return true;
+}
+
+}
+
+void SAL_CALL
+shell::copy(
+ sal_Int32 CommandId,
+ const rtl::OUString srcUnqPath,
+ const rtl::OUString dstUnqPathIn,
+ sal_Int32 NameClash )
+ throw()
+{
+ osl::FileBase::RC nError;
+ rtl::OUString dstUnqPath( dstUnqPathIn );
+
+ // Resolve symbolic links within the source path. If srcUnqPath denotes a
+ // symbolic link (targeting either a file or a folder), the contents of the
+ // target is copied (recursively, in the case of a folder). However, if
+ // recursively copying the contents of a folder causes a symbolic link to be
+ // copied, the symbolic link itself is copied.
+ osl::DirectoryItem item;
+ osl::FileStatus::Type type;
+ if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
+ return;
+ }
+ rtl::OUString rslvdSrcUnqPath;
+ if (type == osl::FileStatus::Link) {
+ osl::FileStatus stat(FileStatusMask_LinkTargetURL);
+ nError = item.getFileStatus(stat);
+ if (nError != osl::FileBase::E_None) {
+ installError(
+ CommandId, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, nError);
+ return;
+ }
+ rslvdSrcUnqPath = stat.getLinkTargetURL();
+ if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
+ return;
+ }
+ } else {
+ rslvdSrcUnqPath = srcUnqPath;
+ }
+
+ sal_Bool isDocument
+ = type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
+ sal_Int32 IsWhat = isDocument ? -1 : 1;
+
+ switch( NameClash )
+ {
+ case NameClash::KEEP:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+ if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_KEEPERROR_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::OVERWRITE:
+ {
+ // remove (..., MustExist = sal_False).
+ remove( CommandId, dstUnqPath, IsWhat, sal_False );
+
+ // copy.
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_OVERWRITE_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::RENAME:
+ {
+ rtl::OUString newDstUnqPath;
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ // "invent" a new valid title.
+
+ sal_Int32 nPos = -1;
+ sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
+ sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
+ if ( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
+ && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
+ nPos = nLastDot;
+ else
+ nPos = dstUnqPath.getLength();
+
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ newDstUnqPath = dstUnqPath;
+
+ rtl::OUString aPostFix( rtl::OUString::createFromAscii( "_" ) );
+ aPostFix += rtl::OUString::valueOf( ++nTry );
+
+ newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
+
+ nError = copy_recursive( rslvdSrcUnqPath,newDstUnqPath,IsWhat,true );
+ }
+ while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
+ }
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAME_FOR_COPY );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAMEMOVE_FOR_COPY,
+ nError );
+ return;
+ }
+ else
+ dstUnqPath = newDstUnqPath;
+
+ break;
+ }
+ case NameClash::ERROR:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASH_FOR_COPY );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHMOVE_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::ASK:
+ default:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY,
+ NameClash);
+ return;
+ }
+ break;
+ }
+ }
+
+ copyPersistentSet( srcUnqPath,dstUnqPath, !isDocument );
+ notifyInsert( getContentEventListeners( getParentName( dstUnqPath ) ),dstUnqPath );
+}
+
+
+
+/********************************************************************************/
+/* */
+/* remove-implementation */
+/* */
+/********************************************************************************/
+//
+// Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
+// Return: success of operation
+//
+
+
+sal_Bool SAL_CALL
+shell::remove( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Int32 IsWhat,
+ sal_Bool MustExist )
+ throw()
+{
+ sal_Int32 nMask = FileStatusMask_Type | FileStatusMask_FileURL;
+
+ osl::DirectoryItem aItem;
+ osl::FileStatus aStatus( nMask );
+ osl::FileBase::RC nError;
+
+ if( IsWhat == 0 ) // Determine whether we are removing a directory or a file
+ {
+ nError = osl::DirectoryItem::get( aUnqPath, aItem );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE,
+ nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
+ return sal_False;
+ }
+
+ if( aStatus.getFileType() == osl::FileStatus::Regular ||
+ aStatus.getFileType() == osl::FileStatus::Link )
+ IsWhat = -1; // RemoveFile
+ else if( aStatus.getFileType() == osl::FileStatus::Directory ||
+ aStatus.getFileType() == osl::FileStatus::Volume )
+ IsWhat = +1; // RemoveDirectory
+ }
+
+
+ if( IsWhat == -1 ) // Removing a file
+ {
+ nError = osl::File::remove( aUnqPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_DELETEFILE_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+ else
+ {
+ notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
+ erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
+ }
+ }
+ else if( IsWhat == +1 ) // Removing a directory
+ {
+ osl::Directory aDirectory( aUnqPath );
+
+ nError = aDirectory.open();
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_OPENDIRECTORY_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+
+ sal_Bool whileSuccess = sal_True;
+ sal_Int32 recurse = 0;
+ rtl::OUString name;
+
+ nError = aDirectory.getNextItem( aItem );
+ while( nError == osl::FileBase::E_None )
+ {
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE,
+ nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
+ whileSuccess = sal_False;
+ break;
+ }
+
+ if( aStatus.getFileType() == osl::FileStatus::Regular ||
+ aStatus.getFileType() == osl::FileStatus::Link )
+ recurse = -1;
+ else if( aStatus.getFileType() == osl::FileStatus::Directory ||
+ aStatus.getFileType() == osl::FileStatus::Volume )
+ recurse = +1;
+
+ name = aStatus.getFileURL();
+ whileSuccess = remove(
+ CommandId, name, recurse, MustExist );
+ if( !whileSuccess )
+ break;
+
+ nError = aDirectory.getNextItem( aItem );
+ }
+
+ aDirectory.close();
+
+ if( ! whileSuccess )
+ return sal_False; // error code is installed
+
+ if( nError != osl::FileBase::E_NOENT )
+ {
+ installError( CommandId,
+ TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE,
+ nError );
+ return sal_False;
+ }
+
+ nError = osl::Directory::remove( aUnqPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+ else
+ {
+ notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
+ erasePersistentSet( aUnqPath );
+ }
+ }
+ else // Don't know what to remove
+ {
+ installError( CommandId,
+ TASKHANDLING_FILETYPE_FOR_REMOVE );
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+
+/********************************************************************************/
+/* */
+/* mkdir-implementation */
+/* */
+/********************************************************************************/
+//
+// Creates new directory with given URL, recursively if necessary
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::mkdir( sal_Int32 CommandId,
+ const rtl::OUString& rUnqPath,
+ sal_Bool OverWrite )
+ throw()
+{
+ rtl::OUString aUnqPath;
+
+ // remove trailing slash
+ if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
+ aUnqPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
+ else
+ aUnqPath = rUnqPath;
+
+ osl::FileBase::RC nError = osl::Directory::create( aUnqPath );
+
+ switch ( nError )
+ {
+ case osl::FileBase::E_EXIST: // Directory cannot be overwritten
+ {
+ if( !OverWrite )
+ {
+ installError( CommandId,
+ TASKHANDLING_FOLDER_EXISTS_MKDIR );
+ return sal_False;
+ }
+ else
+ return sal_True;
+ }
+ case osl::FileBase::E_INVAL:
+ {
+ installError(CommandId,
+ TASKHANDLING_INVALID_NAME_MKDIR);
+ return sal_False;
+ }
+ case osl::FileBase::E_None:
+ {
+ rtl::OUString aPrtPath = getParentName( aUnqPath );
+ notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
+ return sal_True;
+ }
+ default:
+ return ensuredir(
+ CommandId,
+ aUnqPath,
+ TASKHANDLING_CREATEDIRECTORY_MKDIR );
+ }
+}
+
+
+/********************************************************************************/
+/* */
+/* mkfil-implementation */
+/* */
+/********************************************************************************/
+//
+// Creates new file with given URL.
+// The content of aInputStream becomes the content of the file
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::mkfil( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool Overwrite,
+ const uno::Reference< io::XInputStream >& aInputStream )
+ throw()
+{
+ // return value unimportant
+ sal_Bool bSuccess = write( CommandId,
+ aUnqPath,
+ Overwrite,
+ aInputStream );
+ if ( bSuccess )
+ {
+ rtl::OUString aPrtPath = getParentName( aUnqPath );
+ notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
+ }
+ return bSuccess;
+}
+
+
+/********************************************************************************/
+/* */
+/* write-implementation */
+/* */
+/********************************************************************************/
+//
+// writes to the file with given URL.
+// The content of aInputStream becomes the content of the file
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::write( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool OverWrite,
+ const uno::Reference< io::XInputStream >& aInputStream )
+ throw()
+{
+ if( ! aInputStream.is() )
+ {
+ installError( CommandId,
+ TASKHANDLING_INPUTSTREAM_FOR_WRITE );
+ return sal_False;
+ }
+
+ // Create parent path, if necessary.
+ if ( ! ensuredir( CommandId,
+ getParentName( aUnqPath ),
+ TASKHANDLING_ENSUREDIR_FOR_WRITE ) )
+ return sal_False;
+
+ osl::FileBase::RC err;
+ osl::File aFile( aUnqPath );
+
+ if( OverWrite )
+ {
+ err = aFile.open( OpenFlag_Write | OpenFlag_Create );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ err = aFile.open( OpenFlag_Write );
+ }
+
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE,
+ err );
+ return sal_False;
+ }
+ }
+ else
+ {
+ err = aFile.open( OpenFlag_Read | OpenFlag_NoLock );
+ if( err == osl::FileBase::E_None ) // The file exists and shall not be overwritten
+ {
+ installError( CommandId,
+ TASKHANDLING_NOREPLACE_FOR_WRITE, // Now an exception
+ err );
+
+ aFile.close();
+ return sal_False;
+ }
+
+ // as a temporary solution the creation does not lock the file at all
+ // in future it should be possible to create the file without lock explicitly
+ err = aFile.open( OpenFlag_Write | OpenFlag_Create | OpenFlag_NoLock );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ installError( CommandId,
+ TASKHANDLING_NO_OPEN_FILE_FOR_WRITE,
+ err );
+ return sal_False;
+ }
+ }
+
+ sal_Bool bSuccess = sal_True;
+
+ sal_uInt64 nTotalNumberOfBytes = 0;
+ sal_uInt64 nWrittenBytes;
+ sal_Int32 nReadBytes = 0, nRequestedBytes = 32768 /*32k*/;
+ uno::Sequence< sal_Int8 > seq( nRequestedBytes );
+
+ do
+ {
+ try
+ {
+ nReadBytes = aInputStream->readBytes( seq,
+ nRequestedBytes );
+ }
+ catch( const io::NotConnectedException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_NOTCONNECTED_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+ catch( const io::BufferSizeExceededException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+ catch( const io::IOException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_IOEXCEPTION_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+
+ if( nReadBytes )
+ {
+ const sal_Int8* p = seq.getConstArray();
+
+ err = aFile.write( ((void*)(p)),
+ sal_uInt64( nReadBytes ),
+ nWrittenBytes );
+
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ break;
+ }
+ else if( nWrittenBytes != sal_uInt64( nReadBytes ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_NO_SPACE );
+ bSuccess = sal_False;
+ break;
+ }
+
+ nTotalNumberOfBytes += nWrittenBytes;
+ }
+ } while( nReadBytes == nRequestedBytes );
+
+ err = aFile.setSize( nTotalNumberOfBytes );
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILESIZE_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ }
+
+ err = aFile.close();
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ }
+
+ return bSuccess;
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* insertDefaultProperties-Implementation */
+/* */
+/*********************************************************************************/
+
+
+void SAL_CALL shell::insertDefaultProperties( const rtl::OUString& aUnqPath )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it =
+ m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ load( it,false );
+
+ MyProperty ContentTProperty( ContentType );
+
+ PropertySet& properties = *(it->second.properties);
+ sal_Bool ContentNotDefau = properties.find( ContentTProperty ) != properties.end();
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.begin();
+ while( it1 != m_aDefaultProperties.end() )
+ {
+ if( ContentNotDefau && it1->getPropertyName() == ContentType )
+ {
+ // No insertion
+ }
+ else
+ properties.insert( *it1 );
+ ++it1;
+ }
+}
+
+
+
+
+/******************************************************************************/
+/* */
+/* mapping of file urls */
+/* to uncpath and vice versa */
+/* */
+/******************************************************************************/
+
+
+sal_Bool SAL_CALL shell::getUnqFromUrl( const rtl::OUString& Url,rtl::OUString& Unq )
+{
+ if( 0 == Url.compareToAscii( "file:///" ) ||
+ 0 == Url.compareToAscii( "file://localhost/" ) ||
+ 0 == Url.compareToAscii( "file://127.0.0.1/" ) )
+ {
+ Unq = rtl::OUString::createFromAscii( "file:///" );
+ return false;
+ }
+
+ sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Url,Unq );
+
+ Unq = Url;
+
+ sal_Int32 l = Unq.getLength()-1;
+ if( ! err && Unq.getStr()[ l ] == '/' &&
+ Unq.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) < l )
+ Unq = Unq.copy(0, Unq.getLength() - 1);
+
+ return err;
+}
+
+
+
+sal_Bool SAL_CALL shell::getUrlFromUnq( const rtl::OUString& Unq,rtl::OUString& Url )
+{
+ sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Unq,Url );
+
+ Url = Unq;
+
+ return err;
+}
+
+
+
+// Helper function for public copy
+
+osl::FileBase::RC SAL_CALL
+shell::copy_recursive( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Int32 TypeToCopy,
+ sal_Bool testExistBeforeCopy )
+ throw()
+{
+ osl::FileBase::RC err = osl::FileBase::E_None;
+
+ if( TypeToCopy == -1 ) // Document
+ {
+ err = osl_File_copy( srcUnqPath,dstUnqPath,testExistBeforeCopy );
+ }
+ else if( TypeToCopy == +1 ) // Folder
+ {
+ osl::Directory aDir( srcUnqPath );
+ aDir.open();
+
+ err = osl::Directory::create( dstUnqPath );
+ osl::FileBase::RC next = err;
+ if( err == osl::FileBase::E_None )
+ {
+ sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type;
+
+ osl::DirectoryItem aDirItem;
+
+ while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
+ {
+ sal_Bool IsDoc = false;
+ osl::FileStatus aFileStatus( n_Mask );
+ aDirItem.getFileStatus( aFileStatus );
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ // Getting the information for the next recursive copy
+ sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
+
+ rtl::OUString newSrcUnqPath;
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ newSrcUnqPath = aFileStatus.getFileURL();
+
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString tit;
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ tit = aFileStatus.getFileName();
+ if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
+ newDstUnqPath += rtl::OUString::createFromAscii( "/" );
+ newDstUnqPath += tit;
+
+ if ( newSrcUnqPath != dstUnqPath )
+ err = copy_recursive( newSrcUnqPath,newDstUnqPath,newTypeToCopy,false );
+ }
+
+ if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
+ err = next;
+ }
+ aDir.close();
+ }
+
+ return err;
+}
+
+
+
+// Helper function for mkfil,mkdir and write
+// Creates whole path
+// returns success of the operation
+
+
+sal_Bool SAL_CALL shell::ensuredir( sal_Int32 CommandId,
+ const rtl::OUString& rUnqPath,
+ sal_Int32 errorCode )
+ throw()
+{
+ rtl::OUString aPath;
+
+ if ( rUnqPath.getLength() < 1 )
+ return sal_False;
+
+ if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
+ aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
+ else
+ aPath = rUnqPath;
+
+
+ // HACK: create directory on a mount point with nobrowse option
+ // returns ENOSYS in any case !!
+ osl::Directory aDirectory( aPath );
+ osl::FileBase::RC nError = aDirectory.open();
+ aDirectory.close();
+
+ if( nError == osl::File::E_None )
+ return sal_True;
+
+ nError = osl::Directory::create( aPath );
+
+ if( nError == osl::File::E_None )
+ notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
+
+ sal_Bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+
+ if( ! bSuccess )
+ {
+ rtl::OUString aParentDir = getParentName( aPath );
+
+ if ( aParentDir != aPath )
+ { // Create first the parent directory
+ bSuccess = ensuredir( CommandId,
+ getParentName( aPath ),
+ errorCode );
+
+ // After parent directory structure exists try it one's more
+
+ if ( bSuccess )
+ { // Parent directory exists, retry creation of directory
+ nError = osl::Directory::create( aPath );
+
+ if( nError == osl::File::E_None )
+ notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
+
+ bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+ }
+ }
+ }
+
+ if( ! bSuccess )
+ installError( CommandId,
+ errorCode,
+ nError );
+
+ return bSuccess;
+}
+
+
+
+
+//
+// Given a sequence of properties seq, this method determines the mask
+// used to instantiate a osl::FileStatus, so that a call to
+// osl::DirectoryItem::getFileStatus fills the required fields.
+//
+
+
+void SAL_CALL
+shell::getMaskFromProperties(
+ sal_Int32& n_Mask,
+ const uno::Sequence< beans::Property >& seq )
+{
+ n_Mask = 0;
+ for(sal_Int32 j = 0; j < seq.getLength(); ++j) {
+ if(seq[j].Name == Title)
+ n_Mask |= FileStatusMask_FileName;
+ else if(seq[j].Name == CasePreservingURL)
+ n_Mask |= FileStatusMask_FileURL;
+ else if(seq[j].Name == IsDocument ||
+ seq[j].Name == IsFolder ||
+ seq[j].Name == IsVolume ||
+ seq[j].Name == IsRemoveable ||
+ seq[j].Name == IsRemote ||
+ seq[j].Name == IsCompactDisc ||
+ seq[j].Name == IsFloppy ||
+ seq[j].Name == ContentType)
+ n_Mask |= (FileStatusMask_Type | FileStatusMask_LinkTargetURL);
+ else if(seq[j].Name == Size)
+ n_Mask |= (FileStatusMask_FileSize |
+ FileStatusMask_Type |
+ FileStatusMask_LinkTargetURL);
+ else if(seq[j].Name == IsHidden ||
+ seq[j].Name == IsReadOnly)
+ n_Mask |= FileStatusMask_Attributes;
+ else if(seq[j].Name == DateModified)
+ n_Mask |= FileStatusMask_ModifyTime;
+// n_Mask = FileStatusMask_FileURL;
+// n_Mask |= FileStatusMask_LinkTargetURL;
+// n_Mask |= FileStatusMask_FileName;
+// n_Mask |= FileStatusMask_Type;
+// n_Mask |= FileStatusMask_ModifyTime;
+// n_Mask |= FileStatusMask_FileSize;
+// n_Mask |= FileStatusMask_Attributes;
+ }
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* load-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Load the properties from configuration, if create == true create them.
+// The Properties are stored under the url belonging to it->first.
+//
+
+void SAL_CALL
+shell::load( const ContentMap::iterator& it, sal_Bool create )
+{
+ if( ! it->second.properties )
+ it->second.properties = new PropertySet;
+
+ if( ( ! it->second.xS.is() ||
+ ! it->second.xC.is() ||
+ ! it->second.xA.is() )
+ && m_xFileRegistry.is() )
+ {
+
+ uno::Reference< ucb::XPersistentPropertySet > xS = m_xFileRegistry->openPropertySet( it->first,create );
+ if( xS.is() )
+ {
+ uno::Reference< beans::XPropertyContainer > xC( xS,uno::UNO_QUERY );
+ uno::Reference< beans::XPropertyAccess > xA( xS,uno::UNO_QUERY );
+
+ it->second.xS = xS;
+ it->second.xC = xC;
+ it->second.xA = xA;
+
+ // Now put in all values in the storage in the local hash;
+
+ PropertySet& properties = *(it->second.properties);
+ uno::Sequence< beans::Property > seq = xS->getPropertySetInfo()->getProperties();
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( false,
+ seq[i].Name,
+ seq[i].Handle,
+ seq[i].Type,
+ xS->getPropertyValue( seq[i].Name ),
+ beans::PropertyState_DIRECT_VALUE,
+ seq[i].Attributes );
+ if( properties.find( readProp ) == properties.end() )
+ properties.insert( readProp );
+ }
+ }
+ else if( create )
+ {
+ // Catastrophic error
+ }
+ }
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* commit-Implementation */
+/* */
+/*********************************************************************************/
+// Commit inserts the determined properties in the filestatus object into
+// the internal map, so that is possible to determine on a subsequent
+// setting of file properties which properties have changed without filestat
+
+
+void SAL_CALL
+shell::commit( const shell::ContentMap::iterator& it,
+ const osl::FileStatus& aFileStatus )
+{
+ uno::Any aAny;
+ uno::Any emptyAny;
+ shell::PropertySet::iterator it1;
+
+ if( it->second.properties == 0 )
+ {
+ rtl::OUString aPath = it->first;
+ insertDefaultProperties( aPath );
+ }
+
+ PropertySet& properties = *( it->second.properties );
+
+ it1 = properties.find( MyProperty( Title ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ {
+ aAny <<= aFileStatus.getFileName();
+ it1->setValue( aAny );
+ }
+ }
+
+ it1 = properties.find( MyProperty( CasePreservingURL ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ {
+ aAny <<= aFileStatus.getFileURL();
+ it1->setValue( aAny );
+ }
+ }
+
+
+ sal_Bool isDirectory,isFile,isVolume,isRemoveable,isRemote,isFloppy,isCompactDisc;
+
+ sal_Int64 dirSize = 0;
+
+ if( aFileStatus.isValid( FileStatusMask_FileSize ) )
+ dirSize = aFileStatus.getFileSize();
+
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ {
+ if( osl::FileStatus::Link == aFileStatus.getFileType() &&
+ aFileStatus.isValid( FileStatusMask_LinkTargetURL ) )
+ {
+ osl::DirectoryItem aDirItem;
+ osl::FileStatus aFileStatus2( FileStatusMask_Type );
+ if( osl::FileBase::E_None == osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(),aDirItem ) &&
+ osl::FileBase::E_None == aDirItem.getFileStatus( aFileStatus2 ) &&
+ aFileStatus2.isValid( FileStatusMask_Type ) )
+ {
+ isVolume = osl::FileStatus::Volume == aFileStatus2.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus2.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus2.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus2.getFileType();
+
+ if( aFileStatus2.isValid( FileStatusMask_FileSize ) )
+ dirSize = aFileStatus2.getFileSize();
+ }
+ else
+ {
+ // extremly ugly, but otherwise default construction
+ // of aDirItem and aFileStatus2
+ // before the preciding if
+ isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus.getFileType();
+ }
+ }
+ else
+ {
+ isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus.getFileType();
+ }
+
+ it1 = properties.find( MyProperty( IsVolume ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isVolume ) );
+
+ it1 = properties.find( MyProperty( IsFolder ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isDirectory ) );
+
+ it1 = properties.find( MyProperty( IsDocument ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isFile ) );
+
+ osl::VolumeInfo aVolumeInfo( VolumeInfoMask_Attributes );
+ if( isVolume &&
+ osl::FileBase::E_None == osl::Directory::getVolumeInfo( it->first,aVolumeInfo ) &&
+ aVolumeInfo.isValid( VolumeInfoMask_Attributes ) )
+ {
+ // Retrieve the flags;
+ isRemote = aVolumeInfo.getRemoteFlag();
+ isRemoveable = aVolumeInfo.getRemoveableFlag();
+ isCompactDisc = aVolumeInfo.getCompactDiscFlag();
+ isFloppy = aVolumeInfo.getFloppyDiskFlag();
+
+ it1 = properties.find( MyProperty( IsRemote ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isRemote ) );
+
+ it1 = properties.find( MyProperty( IsRemoveable ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isRemoveable ) );
+
+ it1 = properties.find( MyProperty( IsCompactDisc ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isCompactDisc ) );
+
+ it1 = properties.find( MyProperty( IsFloppy ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isFloppy ) );
+ }
+ else
+ {
+ sal_Bool dummy = false;
+ aAny <<= dummy;
+ it1 = properties.find( MyProperty( IsRemote ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsRemoveable ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsCompactDisc ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsFloppy ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+ }
+ }
+ else
+ {
+ isDirectory = sal_False;
+ }
+
+ it1 = properties.find( MyProperty( Size ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( dirSize ) );
+
+ it1 = properties.find( MyProperty( IsReadOnly ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_Attributes ) )
+ {
+ sal_uInt64 Attr = aFileStatus.getAttributes();
+ sal_Bool readonly = ( Attr & Attribute_ReadOnly ) != 0;
+ it1->setValue( uno::makeAny( readonly ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( IsHidden ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_Attributes ) )
+ {
+ sal_uInt64 Attr = aFileStatus.getAttributes();
+ sal_Bool ishidden = ( Attr & Attribute_Hidden ) != 0;
+ it1->setValue( uno::makeAny( ishidden ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( DateModified ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_ModifyTime ) )
+ {
+ TimeValue temp = aFileStatus.getModifyTime();
+
+ // Convert system time to local time (for EA)
+ TimeValue myLocalTime;
+ osl_getLocalTimeFromSystemTime( &temp, &myLocalTime );
+
+ oslDateTime myDateTime;
+ osl_getDateTimeFromTimeValue( &myLocalTime, &myDateTime );
+ util::DateTime aDateTime;
+
+ aDateTime.HundredthSeconds = (unsigned short)(myDateTime.NanoSeconds / 10000000);
+ aDateTime.Seconds = myDateTime.Seconds;
+ aDateTime.Minutes = myDateTime.Minutes;
+ aDateTime.Hours = myDateTime.Hours;
+ aDateTime.Day = myDateTime.Day;
+ aDateTime.Month = myDateTime.Month;
+ aDateTime.Year = myDateTime.Year;
+ it1->setValue( uno::makeAny( aDateTime ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( CreatableContentsInfo ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny(
+ isDirectory || !aFileStatus.isValid( FileStatusMask_Type )
+ ? queryCreatableContentsInfo()
+ : uno::Sequence< ucb::ContentInfo >() ) );
+}
+
+
+// Special optimized method for getting the properties of a
+// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
+
+
+uno::Reference< sdbc::XRow > SAL_CALL
+shell::getv(
+ Notifier* pNotifier,
+ const uno::Sequence< beans::Property >& properties,
+ osl::DirectoryItem& aDirItem,
+ rtl::OUString& aUnqPath,
+ sal_Bool& aIsRegular )
+{
+ uno::Sequence< uno::Any > seq( properties.getLength() );
+
+ sal_Int32 n_Mask;
+ getMaskFromProperties( n_Mask,properties );
+
+ // Always retrieve the type and the target URL because item might be a link
+ osl::FileStatus aFileStatus( n_Mask |
+ FileStatusMask_FileURL |
+ FileStatusMask_Type |
+ FileStatusMask_LinkTargetURL );
+ aDirItem.getFileStatus( aFileStatus );
+ aUnqPath = aFileStatus.getFileURL();
+
+ // If the directory item type is a link retrieve the type of the target
+
+ if ( aFileStatus.getFileType() == osl::FileStatus::Link )
+ {
+ // Assume failure
+ aIsRegular = false;
+ osl::FileBase::RC result = osl::FileBase::E_INVAL;
+ osl::DirectoryItem aTargetItem;
+ osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
+ if ( aTargetItem.is() )
+ {
+ osl::FileStatus aTargetStatus( FileStatusMask_Type );
+
+ if ( osl::FileBase::E_None ==
+ ( result = aTargetItem.getFileStatus( aTargetStatus ) ) )
+ aIsRegular =
+ aTargetStatus.getFileType() == osl::FileStatus::Regular;
+ }
+ }
+ else
+ aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ registerNotifier( aUnqPath,pNotifier );
+ insertDefaultProperties( aUnqPath );
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ commit( it,aFileStatus );
+
+ shell::PropertySet::iterator it1;
+ PropertySet& propset = *(it->second.properties);
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( properties[i].Name );
+ it1 = propset.find( readProp );
+ if( it1 == propset.end() )
+ seq[i] = uno::Any();
+ else
+ seq[i] = it1->getValue();
+ }
+ }
+ deregisterNotifier( aUnqPath,pNotifier );
+
+ XRow_impl* p = new XRow_impl( this,seq );
+ return uno::Reference< sdbc::XRow >( p );
+}
+
+
+
+
+
+
+// EventListener
+
+
+std::list< ContentEventNotifier* >* SAL_CALL
+shell::getContentEventListeners( const rtl::OUString& aName )
+{
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cCEL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+
+std::list< ContentEventNotifier* >* SAL_CALL
+shell::getContentDeletedEventListeners( const rtl::OUString& aName )
+{
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cDEL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL
+shell::notifyInsert( std::list< ContentEventNotifier* >* listeners,const rtl::OUString& aChildName )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyChildInserted( aChildName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyContentDeleted( std::list< ContentEventNotifier* >* listeners )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyDeleted();
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyContentRemoved( std::list< ContentEventNotifier* >* listeners,
+ const rtl::OUString& aChildName )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyRemoved( aChildName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+
+std::list< PropertySetInfoChangeNotifier* >* SAL_CALL
+shell::getPropertySetListeners( const rtl::OUString& aName )
+{
+ std::list< PropertySetInfoChangeNotifier* >* p = new std::list< PropertySetInfoChangeNotifier* >;
+ std::list< PropertySetInfoChangeNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ PropertySetInfoChangeNotifier* notifier = pointer->cPSL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL
+shell::notifyPropertyAdded( std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName )
+{
+ std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyAdded( aPropertyName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyPropertyRemoved( std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName )
+{
+ std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyRemoved( aPropertyName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+std::vector< std::list< ContentEventNotifier* >* >* SAL_CALL
+shell::getContentExchangedEventListeners( const rtl::OUString aOldPrefix,
+ const rtl::OUString aNewPrefix,
+ sal_Bool withChilds )
+{
+
+ std::vector< std::list< ContentEventNotifier* >* >* aVectorOnHeap =
+ new std::vector< std::list< ContentEventNotifier* >* >;
+ std::vector< std::list< ContentEventNotifier* >* >& aVector = *aVectorOnHeap;
+
+ sal_Int32 count;
+ rtl::OUString aOldName;
+ rtl::OUString aNewName;
+ std::vector< rtl::OUString > oldChildList;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( ! withChilds )
+ {
+ aOldName = aOldPrefix;
+ aNewName = aNewPrefix;
+ count = 1;
+ }
+ else
+ {
+ ContentMap::iterator itnames = m_aContent.begin();
+ while( itnames != m_aContent.end() )
+ {
+ if( isChild( aOldPrefix,itnames->first ) )
+ {
+ oldChildList.push_back( itnames->first );
+ }
+ ++itnames;
+ }
+ count = oldChildList.size();
+ }
+
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+
+ if( withChilds )
+ {
+ aOldName = oldChildList[j];
+ aNewName = newName( aNewPrefix,aOldPrefix,aOldName );
+ }
+
+ shell::ContentMap::iterator itold = m_aContent.find( aOldName );
+ if( itold != m_aContent.end() )
+ {
+ shell::ContentMap::iterator itnew = m_aContent.insert(
+ ContentMap::value_type( aNewName,UnqPathData() ) ).first;
+
+ // copy Ownership also
+ delete itnew->second.properties;
+ itnew->second.properties = itold->second.properties;
+ itold->second.properties = 0;
+
+ // copy existing list
+ std::list< Notifier* >* copyList = itnew->second.notifier;
+ itnew->second.notifier = itold->second.notifier;
+ itold->second.notifier = 0;
+
+ m_aContent.erase( itold );
+
+ if( itnew != m_aContent.end() && itnew->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( itnew->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cEXC( aNewName );
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+
+ // Merge with preexisting notifiers
+ // However, these may be in status BaseContent::Deleted
+ if( copyList != 0 )
+ {
+ std::list< Notifier* >::iterator copyIt = copyList->begin();
+ while( copyIt != copyList->end() )
+ {
+ itnew->second.notifier->push_back( *copyIt );
+ ++copyIt;
+ }
+ }
+ delete copyList;
+ }
+ aVector.push_back( p );
+ }
+ }
+
+ return aVectorOnHeap;
+}
+
+
+
+void SAL_CALL
+shell::notifyContentExchanged( std::vector< std::list< ContentEventNotifier* >* >* listeners_vec )
+{
+ std::list< ContentEventNotifier* >* listeners;
+ for( sal_uInt32 i = 0; i < listeners_vec->size(); ++i )
+ {
+ listeners = (*listeners_vec)[i];
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyExchanged();
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+ }
+ delete listeners_vec;
+}
+
+
+
+std::list< PropertyChangeNotifier* >* SAL_CALL
+shell::getPropertyChangeNotifier( const rtl::OUString& aName )
+{
+ std::list< PropertyChangeNotifier* >* p = new std::list< PropertyChangeNotifier* >;
+ std::list< PropertyChangeNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ PropertyChangeNotifier* notifier = pointer->cPCL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL shell::notifyPropertyChanges( std::list< PropertyChangeNotifier* >* listeners,
+ const uno::Sequence< beans::PropertyChangeEvent >& seqChanged )
+{
+ std::list< PropertyChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyChanged( seqChanged );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+
+/********************************************************************************/
+/* remove persistent propertyset */
+/********************************************************************************/
+
+void SAL_CALL
+shell::erasePersistentSet( const rtl::OUString& aUnqPath,
+ sal_Bool withChilds )
+{
+ if( ! m_xFileRegistry.is() )
+ {
+ OSL_ASSERT( m_xFileRegistry.is() );
+ return;
+ }
+
+ uno::Sequence< rtl::OUString > seqNames;
+
+ if( withChilds )
+ {
+ uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
+ seqNames = xName->getElementNames();
+ }
+
+ sal_Int32 count = withChilds ? seqNames.getLength() : 1;
+
+ rtl::OUString
+ old_Name = aUnqPath;
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ if( withChilds && ! ( isChild( old_Name,seqNames[j] ) ) )
+ continue;
+
+ if( withChilds )
+ {
+ old_Name = seqNames[j];
+ }
+
+ {
+ // Release possible references
+ osl::MutexGuard aGuard( m_aMutex );
+ ContentMap::iterator it = m_aContent.find( old_Name );
+ if( it != m_aContent.end() )
+ {
+ it->second.xS = 0;
+ it->second.xC = 0;
+ it->second.xA = 0;
+
+ delete it->second.properties;
+ it->second.properties = 0;
+ }
+ }
+
+ if( m_xFileRegistry.is() )
+ m_xFileRegistry->removePropertySet( old_Name );
+ }
+}
+
+
+
+
+/********************************************************************************/
+/* copy persistent propertyset */
+/* from srcUnqPath to dstUnqPath */
+/********************************************************************************/
+
+
+void SAL_CALL
+shell::copyPersistentSet( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Bool withChilds )
+{
+ if( ! m_xFileRegistry.is() )
+ {
+ OSL_ASSERT( m_xFileRegistry.is() );
+ return;
+ }
+
+ uno::Sequence< rtl::OUString > seqNames;
+
+ if( withChilds )
+ {
+ uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
+ seqNames = xName->getElementNames();
+ }
+
+ sal_Int32 count = withChilds ? seqNames.getLength() : 1;
+
+ rtl::OUString
+ old_Name = srcUnqPath,
+ new_Name = dstUnqPath;
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ if( withChilds && ! ( isChild( srcUnqPath,seqNames[j] ) ) )
+ continue;
+
+ if( withChilds )
+ {
+ old_Name = seqNames[j];
+ new_Name = newName( dstUnqPath,srcUnqPath,old_Name );
+ }
+
+ uno::Reference< XPersistentPropertySet > x_src;
+
+ if( m_xFileRegistry.is() )
+ {
+ x_src = m_xFileRegistry->openPropertySet( old_Name,false );
+ m_xFileRegistry->removePropertySet( new_Name );
+ }
+
+ if( x_src.is() )
+ {
+ uno::Sequence< beans::Property > seqProperty =
+ x_src->getPropertySetInfo()->getProperties();
+
+ if( seqProperty.getLength() )
+ {
+ uno::Reference< XPersistentPropertySet >
+ x_dstS = m_xFileRegistry->openPropertySet( new_Name,true );
+ uno::Reference< beans::XPropertyContainer >
+ x_dstC( x_dstS,uno::UNO_QUERY );
+
+ for( sal_Int32 i = 0; i < seqProperty.getLength(); ++i )
+ {
+ x_dstC->addProperty( seqProperty[i].Name,
+ seqProperty[i].Attributes,
+ x_src->getPropertyValue( seqProperty[i].Name ) );
+ }
+ }
+ }
+ } // end for( sal_Int...
+}
+
+uno::Sequence< ucb::ContentInfo > shell::queryCreatableContentsInfo()
+{
+ uno::Sequence< ucb::ContentInfo > seq(2);
+
+ // file
+ seq[0].Type = FileContentType;
+ seq[0].Attributes = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+
+ uno::Sequence< beans::Property > props( 1 );
+ props[0] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND );
+ seq[0].Properties = props;
+
+ // folder
+ seq[1].Type = FolderContentType;
+ seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
+ seq[1].Properties = props;
+ return seq;
+}
+
+/*******************************************************************************/
+/* */
+/* some misceancellous static functions */
+/* */
+/*******************************************************************************/
+
+void SAL_CALL
+shell::getScheme( rtl::OUString& Scheme )
+{
+ Scheme = rtl::OUString::createFromAscii( "file" );
+}
+
+rtl::OUString SAL_CALL
+shell::getImplementationName_static( void )
+{
+ return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileProvider" );
+}
+
+
+uno::Sequence< rtl::OUString > SAL_CALL
+shell::getSupportedServiceNames_static( void )
+{
+ rtl::OUString Supported = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ) ;
+ com::sun::star::uno::Sequence< rtl::OUString > Seq( &Supported,1 );
+ return Seq;
+}
diff --git a/ucb/source/ucp/file/shell.hxx b/ucb/source/ucp/file/shell.hxx
new file mode 100644
index 000000000000..14e332959a26
--- /dev/null
+++ b/ucb/source/ucp/file/shell.hxx
@@ -0,0 +1,607 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SHELL_HXX_
+#define _SHELL_HXX_
+
+
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vector>
+#include <hash_map>
+#include <hash_set>
+#include <list>
+#include <osl/file.hxx>
+
+#include "osl/mutex.hxx"
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include "filtask.hxx"
+#include "filnot.hxx"
+
+namespace fileaccess {
+
+ class FileProvider;
+ class XPropertySetInfo_impl;
+ class XCommandInfo_impl;
+ class XResultSet_impl;
+ class BaseContent;
+ class shell;
+
+ class shell
+ : public virtual TaskManager
+ {
+ friend class XPropertySetInfo_impl;
+ friend class XResultSet_impl;
+ friend class XCommandInfo_impl;
+ public:
+ // Type definitions
+
+ typedef rtl::OUString UniquePath;
+ typedef equalOUString eUniquePath;
+ typedef hashOUString hUniquePath;
+
+ class MyProperty
+ {
+ private:
+ rtl::OUString PropertyName;
+ sal_Int32 Handle;
+ sal_Bool isNative;
+ com::sun::star::uno::Type Typ; // Duplicates information in Value
+ com::sun::star::uno::Any Value;
+ com::sun::star::beans::PropertyState State;
+ sal_Int16 Attributes;
+ public:
+ MyProperty();
+ MyProperty( const rtl::OUString& __PropertyName );
+ MyProperty( const sal_Bool& __isNative,
+ const rtl::OUString& __PropertyName,
+ const sal_Int32& __Handle,
+ const com::sun::star::uno::Type& __Typ,
+ const com::sun::star::uno::Any& __Value,
+ const com::sun::star::beans::PropertyState& __State,
+ const sal_Int16& __Attributes );
+
+ ~MyProperty();
+ inline const sal_Bool& SAL_CALL IsNative() const;
+ inline const rtl::OUString& SAL_CALL getPropertyName() const { return PropertyName; }
+ inline const sal_Int32& SAL_CALL getHandle() const;
+ inline const com::sun::star::uno::Type& SAL_CALL getType() const;
+ inline const com::sun::star::uno::Any& SAL_CALL getValue() const;
+ inline const com::sun::star::beans::PropertyState& SAL_CALL getState() const;
+ inline const sal_Int16& SAL_CALL getAttributes() const;
+
+ // The set* functions are declared const, because the key of "this" stays intact
+ inline void SAL_CALL setHandle( const sal_Int32& __Handle ) const;
+ inline void SAL_CALL setType( const com::sun::star::uno::Type& __Type ) const;
+ inline void SAL_CALL setValue( const com::sun::star::uno::Any& __Value ) const;
+ inline void SAL_CALL setState( const com::sun::star::beans::PropertyState& __State ) const;
+ inline void SAL_CALL setAttributes( const sal_Int16& __Attributes ) const;
+ };
+
+ struct eMyProperty
+ {
+ bool operator()( const MyProperty& rKey1, const MyProperty& rKey2 ) const
+ {
+ return !!( rKey1.getPropertyName() == rKey2.getPropertyName() );
+ }
+ };
+
+ struct hMyProperty
+ {
+ size_t operator()( const MyProperty& rName ) const
+ {
+ return rName.getPropertyName().hashCode();
+ }
+ };
+
+ typedef std::hash_set< MyProperty,hMyProperty,eMyProperty > PropertySet;
+ typedef std::list< Notifier* > NotifierList;
+
+
+ class UnqPathData
+ {
+ public:
+ UnqPathData();
+ ~UnqPathData();
+ UnqPathData( const UnqPathData& );
+ UnqPathData& operator=( UnqPathData& );
+
+ PropertySet* properties;
+ NotifierList* notifier;
+
+ // Three views on the PersistentPropertySet
+ com::sun::star::uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xS;
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertyContainer > xC;
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xA;
+ };
+
+ typedef std::hash_map< UniquePath,UnqPathData,hUniquePath,eUniquePath > ContentMap;
+
+ public:
+
+ // MethodenDefinitionen
+ shell( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMultiServiceFactory,
+ FileProvider* pProvider,sal_Bool bWithConfig );
+
+ virtual ~shell();
+
+
+
+ /**
+ * This two methods register and deregister a change listener for the content belonging
+ * to URL aUnqPath
+ */
+
+ void SAL_CALL registerNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier );
+
+ void SAL_CALL deregisterNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier );
+
+
+
+ /**
+ * Used to associate and deassociate a new property with
+ * the content belonging to URL UnqPath.
+ * The default value and the the attributes are input
+ */
+
+ void SAL_CALL associate( const rtl::OUString& UnqPath,
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Any& DefaultValue,
+ const sal_Int16 Attributes )
+ throw( com::sun::star::beans::PropertyExistException,
+ com::sun::star::beans::IllegalTypeException,
+ com::sun::star::uno::RuntimeException);
+
+
+ void SAL_CALL deassociate( const rtl::OUString& UnqPath,
+ const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::NotRemoveableException,
+ com::sun::star::uno::RuntimeException);
+
+
+
+ //
+ // Every method having a command id is not allowed to throw anything,
+ // but instead must install every error code in the task handler
+ //
+
+
+ /**
+ * Given an xOutputStream, this method writes the content of the file belonging to
+ * URL aUnqPath into the XOutputStream
+ */
+
+ void SAL_CALL page( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
+ throw();
+
+
+ /**
+ * Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
+ */
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+ open( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw();
+
+
+ /**
+ * Given a file URL aUnqPath, this methods returns a XStream which can be used
+ * to read and write from/to the file.
+ */
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ open_rw( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw();
+
+
+ /**
+ * This method returns the result set containing the the children of the directory belonging
+ * to file URL aUnqPath
+ */
+
+ com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > SAL_CALL
+ ls( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const sal_Int32 OpenMode,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& sProperty,
+ const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > & sSortingInfo )
+ throw();
+
+
+ /**
+ * Info methods
+ */
+
+ // Info for commands
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo > SAL_CALL
+ info_c()
+ throw();
+
+ // Info for the properties
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ info_p( const rtl::OUString& aUnqPath )
+ throw();
+
+
+ /**
+ * Sets the values of the properties belonging to fileURL aUnqPath
+ */
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any > SAL_CALL
+ setv( const rtl::OUString& aUnqPath,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& values )
+ throw();
+
+
+ /**
+ * Reads the values of the properties belonging to fileURL aUnqPath;
+ * Returns an XRow object containing the values in the requested order.
+ */
+
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL
+ getv( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& properties )
+ throw();
+
+
+ /********************************************************************************/
+ /* transfer-commands */
+ /********************************************************************************/
+
+ /**
+ * Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories )
+ */
+
+ void SAL_CALL
+ move( sal_Int32 CommandId,
+ const rtl::OUString srcUnqPath, // Full file(folder)-path
+ const rtl::OUString dstUnqPath, // Path to the destination-directory
+ const sal_Int32 NameClash )
+ throw();
+
+ /**
+ * Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
+ */
+
+ void SAL_CALL
+ copy( sal_Int32 CommandId, // See "move"
+ const rtl::OUString srcUnqPath,
+ const rtl::OUString dstUnqPath,
+ sal_Int32 NameClash )
+ throw();
+
+#define RemoveFolder 1
+#define RemoveFile -1
+#define RemoveUnknown 0
+
+ /**
+ * Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
+ */
+
+ sal_Bool SAL_CALL
+ remove( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Int32 TypeToMove = RemoveUnknown,
+ sal_Bool MustExist = sal_True )
+ throw();
+
+#undef RemoveUnknown
+#undef RemoveFile
+#undef RemoveFolder
+
+
+ /********************************************************************************/
+ /* write and create - commandos */
+ /********************************************************************************/
+
+ /**
+ * Creates new directory with given URL, recursively if necessary
+ * Return:: success of operation
+ */
+
+ sal_Bool SAL_CALL
+ mkdir( sal_Int32 CommandId,
+ const rtl::OUString& aDirectoryName,
+ sal_Bool OverWrite )
+ throw();
+
+
+ /**
+ * Creates new file with given URL.
+ * The content of aInputStream becomes the content of the file
+ * Return:: success of operation
+ */
+
+ sal_Bool SAL_CALL
+ mkfil( sal_Int32 CommandId,
+ const rtl::OUString& aFileName,
+ sal_Bool OverWrite,
+ const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& aInputStream )
+ throw();
+
+
+ /**
+ * writes to the file with given URL.
+ * The content of aInputStream becomes the content of the file
+ * Return:: success of operation
+ */
+ sal_Bool SAL_CALL
+ write( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool OverWrite,
+ const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& aInputStream )
+ throw();
+
+
+
+ void SAL_CALL insertDefaultProperties( const rtl::OUString& aUnqPath );
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ queryCreatableContentsInfo();
+
+
+ /******************************************************************************/
+ /* */
+ /* mapping of file urls */
+ /* to uncpath and vice versa */
+ /* */
+ /******************************************************************************/
+
+ sal_Bool SAL_CALL getUnqFromUrl( const rtl::OUString& Url, rtl::OUString& Unq );
+
+ sal_Bool SAL_CALL getUrlFromUnq( const rtl::OUString& Unq, rtl::OUString& Url );
+
+
+ sal_Bool m_bWithConfig;
+ FileProvider* m_pProvider;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMultiServiceFactory;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XPropertySetRegistry > m_xFileRegistry;
+
+ private:
+
+ /********************************************************************************/
+ /* get eventListeners */
+ /********************************************************************************/
+
+ std::list< ContentEventNotifier* >* SAL_CALL
+ getContentEventListeners( const rtl::OUString& aName );
+
+ std::list< ContentEventNotifier* >* SAL_CALL
+ getContentDeletedEventListeners( const rtl::OUString& aName );
+
+ std::vector< std::list< ContentEventNotifier* >* >* SAL_CALL
+ getContentExchangedEventListeners( const rtl::OUString aOldPrefix,
+ const rtl::OUString aNewPrefix,
+ sal_Bool withChilds );
+
+ std::list< PropertyChangeNotifier* >* SAL_CALL
+ getPropertyChangeNotifier( const rtl::OUString& aName );
+
+ std::list< PropertySetInfoChangeNotifier* >* SAL_CALL
+ getPropertySetListeners( const rtl::OUString& aName );
+
+
+ /********************************************************************************/
+ /* notify eventListeners */
+ /********************************************************************************/
+
+ void SAL_CALL notifyPropertyChanges(
+ std::list< PropertyChangeNotifier* >* listeners,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyChangeEvent >& seqChanged );
+
+ void SAL_CALL notifyContentExchanged(
+ std::vector< std::list< ContentEventNotifier* >* >* listeners_vec );
+
+ void SAL_CALL notifyInsert(
+ std::list< ContentEventNotifier* >* listeners,const rtl::OUString& aChildName );
+
+ void SAL_CALL notifyContentDeleted(
+ std::list< ContentEventNotifier* >* listeners );
+
+ void SAL_CALL notifyContentRemoved(
+ std::list< ContentEventNotifier* >* listeners,
+ const rtl::OUString& aChildName );
+
+ void SAL_CALL notifyPropertyAdded(
+ std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName );
+
+ void SAL_CALL notifyPropertyRemoved(
+ std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName );
+
+
+ /********************************************************************************/
+ /* remove persistent propertyset */
+ /********************************************************************************/
+
+ void SAL_CALL erasePersistentSet( const rtl::OUString& aUnqPath,
+ sal_Bool withChilds = false );
+
+ /********************************************************************************/
+ /* copy persistent propertyset */
+ /* from srcUnqPath to dstUnqPath */
+ /********************************************************************************/
+
+ void SAL_CALL copyPersistentSet( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Bool withChilds = false );
+
+
+ // Special optimized method for getting the properties of a directoryitem, which
+ // is returned by osl::DirectoryItem::getNextItem()
+
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL
+ getv( Notifier* pNotifier,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& properties,
+ osl::DirectoryItem& DirItem,
+ rtl::OUString& aUnqPath,
+ sal_Bool& bIsRegular );
+
+
+ /**
+ * Load the properties from configuration, if create == true create them.
+ * The Properties are stored under the url belonging to it->first.
+ */
+
+ void SAL_CALL load( const shell::ContentMap::iterator& it,
+ sal_Bool create );
+
+ /**
+ * Commit inserts the determined properties in the filestatus object into
+ * the internal map, so that is possible to determine on a subsequent
+ * setting of file properties which properties have changed without filestat
+ */
+
+ void SAL_CALL
+ commit(
+ const shell::ContentMap::iterator& it,
+ const osl::FileStatus& aFileStatus );
+
+ /**
+ * Given a Sequence of properties seq, this method determines the mask
+ * used to instantiate a osl::FileStatus, so that a call to
+ * osl::DirectoryItem::getFileStatus fills the required fields.
+ */
+
+ void SAL_CALL
+ getMaskFromProperties(
+ sal_Int32& n_Mask,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq );
+
+
+ void SAL_CALL
+ setFileProperties(
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& values,
+ sal_Int32 numberOfValues )
+ throw();
+
+
+ // Helper function for public copy
+
+ osl::FileBase::RC SAL_CALL
+ copy_recursive(
+ const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Int32 TypeToCopy,
+ sal_Bool testExistence )
+ throw();
+
+
+ // Helper function for mkfil,mkdir and write
+ // Creates whole path
+ // returns success of the operation
+ // The calle determines the errorCode, which should be used to install
+ // any error
+
+ sal_Bool SAL_CALL
+ ensuredir( sal_Int32 CommandId,
+ const rtl::OUString& aDirectoryName,
+ sal_Int32 errorCode )
+ throw();
+
+ // General
+ osl::Mutex m_aMutex;
+ ContentMap m_aContent;
+
+ // Default properties
+
+ const rtl::OUString Title;
+ const rtl::OUString CasePreservingURL;
+ const rtl::OUString IsDocument;
+ const rtl::OUString IsFolder;
+ const rtl::OUString DateModified;
+ const rtl::OUString Size;
+ const rtl::OUString IsVolume;
+ const rtl::OUString IsRemoveable;
+ const rtl::OUString IsRemote;
+ const rtl::OUString IsCompactDisc;
+ const rtl::OUString IsFloppy;
+ const rtl::OUString IsHidden;
+ const rtl::OUString ContentType;
+ const rtl::OUString IsReadOnly;
+ const rtl::OUString CreatableContentsInfo;
+
+ public:
+
+ const rtl::OUString FolderContentType;
+ const rtl::OUString FileContentType;
+
+
+ private:
+
+ PropertySet m_aDefaultProperties;
+ com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > m_sCommandInfo;
+
+ public:
+ // Misceancellous:
+ // Methods for "writeComponentInfo" and "createComponentFactory"
+
+ static void SAL_CALL getScheme( rtl::OUString& Scheme );
+
+ static rtl::OUString SAL_CALL getImplementationName_static( void );
+
+ static com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames_static( void );
+
+ }; // end class shell
+
+} // end namespace fileaccess
+
+#endif
+
diff --git a/ucb/source/ucp/file/ucpfile.xml b/ucb/source/ucp/file/ucpfile.xml
new file mode 100644
index 000000000000..bd205639f476
--- /dev/null
+++ b/ucb/source/ucp/file/ucpfile.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpfile
+ </module-name>
+
+ <component-description>
+ <author>
+ Andreas Bille
+ </author>
+ <name>
+ com.sun.star.comp.ucb.FileProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to file system contents.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.FileContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.config.SpecialConfigManager
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationAccess
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.script.Converter
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.ucb.CachedDynamicResultSetStubFactory
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.ucb.Store
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.Property </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertySetInfoChange </type>
+ <type> com.sun.star.beans.PropertyState </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfo </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.frame.ConfigManager </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XActiveDataStreamer </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.io.XStream </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com/sun/star/sdbc/ColumnValue </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentAction </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.FileSystemNotation </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.ListAction </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NumberedSortingInfo </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentIdentifier </type>
+ <type> com.sun.star.ucb.XContentIdentifierFactory </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XFileIdentifierConverter </type>
+ <type> com.sun.star.ucb.XPropertySetRegistryFactory </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.uno.XWeak </type>
+</module-description>
diff --git a/ucb/source/ucp/ftp/curl.hxx b/ucb/source/ucp/ftp/curl.hxx
new file mode 100644
index 000000000000..70ace6e9fd76
--- /dev/null
+++ b/ucb/source/ucp/ftp/curl.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_UCB_SOURCE_UCP_FTP_CURL_HXX
+#define INCLUDED_UCB_SOURCE_UCP_FTP_CURL_HXX
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+
+#include "curl/curl.h"
+
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpcfunc.cxx b/ucb/source/ucp/ftp/ftpcfunc.cxx
new file mode 100644
index 000000000000..24eafec542dd
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcfunc.cxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <string.h>
+
+#include "ftpcontentidentifier.hxx"
+#include "ftpinpstr.hxx"
+#include <stdio.h>
+
+using namespace ftp;
+using namespace com::sun::star::uno;
+
+extern "C" {
+
+ int file_write(void *buffer,size_t size,size_t nmemb,void *stream)
+ {
+ FILE* file =
+ reinterpret_cast<FILE*>(stream);
+ if(!file)
+ return 0;
+ return fwrite(buffer,size,nmemb,file);
+ }
+
+}
diff --git a/ucb/source/ucp/ftp/ftpcfunc.hxx b/ucb/source/ucp/ftp/ftpcfunc.hxx
new file mode 100644
index 000000000000..3b0f63dd8a8d
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcfunc.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _FTP_FTPCFUNC_HXX_
+#define _FTP_FTPCFUNC_HXX_
+
+#include <rtl/ustring.hxx>
+
+
+namespace ftp {
+
+ class FTPStreamContainer
+ {
+ public:
+
+ virtual size_t write(void *buffer,size_t size,size_t nmemb) = 0;
+ };
+
+}
+
+
+extern "C" {
+
+ /** callback for curl_easy_perform(),
+ * forwarding the written content to the stream.
+ * stream has to be of type 'FTPStreamContainer'.
+ */
+
+
+ int file_write(void *buffer,size_t size,size_t nmemb,void *stream);
+
+}
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpcontainer.hxx b/ucb/source/ucp/ftp/ftpcontainer.hxx
new file mode 100644
index 000000000000..6c57bdf1e43f
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontainer.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <sal/types.h>
+
+namespace ftp {
+
+class MemoryContainer {
+
+public:
+
+ MemoryContainer();
+
+ ~MemoryContainer();
+
+ int append(
+ const void* pBuffer,
+ size_t size,
+ size_t nmemb
+ ) throw();
+
+
+ sal_uInt32 m_nLen,m_nWritePos;
+ void *m_pBuffer;
+};
+
+}
+
+
+extern "C" int memory_write(
+ void *buffer,size_t size,size_t nmemb,void *stream);
+
diff --git a/ucb/source/ucp/ftp/ftpcontent.cxx b/ucb/source/ucp/ftp/ftpcontent.cxx
new file mode 100644
index 000000000000..4659197b81b5
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontent.cxx
@@ -0,0 +1,957 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include "ftpdynresultset.hxx"
+#include "ftpresultsetfactory.hxx"
+#include "ftpresultsetI.hxx"
+#include "ftpcontent.hxx"
+#include "ftpcontentprovider.hxx"
+#include "ftpinpstr.hxx"
+#include "ftpdirp.hxx"
+#include "ftpcontentidentifier.hxx"
+#include "ftpcfunc.hxx"
+#include "ftpstrcont.hxx"
+#include "ftpintreq.hxx"
+
+#include <memory>
+#include <vector>
+#include <rtl/memory.h>
+#include "curl.hxx"
+#include <curl/easy.h>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <ucbhelper/simpleauthenticationrequest.hxx>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+//#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/IOErrorCode.hpp>
+
+using namespace ftp;
+using namespace com::sun::star::task;
+using namespace com::sun::star::container;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::io;
+using namespace com::sun::star::sdbc;
+
+
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+FTPContent::FTPContent( const Reference< XMultiServiceFactory >& rxSMgr,
+ FTPContentProvider* pProvider,
+ const Reference< XContentIdentifier >& Identifier,
+ const FTPURL& aFTPURL)
+ : ContentImplHelper(rxSMgr,pProvider,Identifier),
+ m_pFCP(pProvider),
+ m_aFTPURL(aFTPURL),
+ m_bInserted(false),
+ m_bTitleSet(false)
+{
+}
+
+
+
+FTPContent::FTPContent( const Reference< XMultiServiceFactory >& rxSMgr,
+ FTPContentProvider* pProvider,
+ const Reference< XContentIdentifier >& Identifier,
+ const ContentInfo& Info)
+ : ContentImplHelper(rxSMgr,pProvider,Identifier),
+ m_pFCP(pProvider),
+ m_aFTPURL(Identifier->getContentIdentifier(),
+ pProvider),
+ m_bInserted(true),
+ m_bTitleSet(false),
+ m_aInfo(Info)
+{
+}
+
+
+
+//=========================================================================
+
+FTPContent::~FTPContent()
+{
+}
+
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_6( FTPContent,
+ XTypeProvider,
+ XServiceInfo,
+ XContent,
+ XCommandProcessor,
+ XContentCreator,
+ XChild);
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_6( FTPContent,
+ XTypeProvider,
+ XServiceInfo,
+ XContent,
+ XCommandProcessor,
+ XContentCreator,
+ XChild);
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// needed, because the service shall not be creatable!!
+#undef XSERVICEINFO_CREATE_INSTANCE_IMPL
+#define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
+
+XSERVICEINFO_IMPL_1( FTPContent,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.FTPContent"),
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.FTPContent"));
+
+
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL FTPContent::getContentType()
+ throw( RuntimeException )
+{
+ return rtl::OUString::createFromAscii(FTP_CONTENT_TYPE);
+}
+
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+
+//virtual
+void SAL_CALL FTPContent::abort( sal_Int32 /*CommandId*/ )
+ throw( RuntimeException )
+{
+}
+
+
+
+/***************************************************************************/
+/* */
+/* Internal implementation class. */
+/* */
+/***************************************************************************/
+
+
+class ResultSetFactoryI
+ : public ResultSetFactory
+{
+public:
+
+ ResultSetFactoryI(const Reference<XMultiServiceFactory >& xSMgr,
+ const Reference<XContentProvider >& xProvider,
+ sal_Int32 nOpenMode,
+ const Sequence<Property>& seq,
+ const Sequence<NumberedSortingInfo>& seqSort,
+ const std::vector<FTPDirentry>& dirvec)
+ : m_xSMgr(xSMgr),
+ m_xProvider(xProvider),
+ m_nOpenMode(nOpenMode),
+ m_seq(seq),
+ m_seqSort(seqSort),
+ m_dirvec(dirvec)
+ {
+ }
+
+ virtual ResultSetBase* createResultSet()
+ {
+ return new ResultSetI(m_xSMgr,
+ m_xProvider,
+ m_nOpenMode,
+ m_seq,
+ m_seqSort,
+ m_dirvec);
+ }
+
+public:
+
+ Reference< XMultiServiceFactory > m_xSMgr;
+ Reference< XContentProvider > m_xProvider;
+ sal_Int32 m_nOpenMode;
+ Sequence< Property > m_seq;
+ Sequence< NumberedSortingInfo > m_seqSort;
+ std::vector<FTPDirentry> m_dirvec;
+};
+
+
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+enum ACTION { NOACTION,
+ THROWAUTHENTICATIONREQUEST,
+ THROWACCESSDENIED,
+ THROWINTERACTIVECONNECT,
+ THROWRESOLVENAME,
+ THROWQUOTE,
+ THROWNOFILE,
+ THROWGENERAL };
+
+
+// virtual
+Any SAL_CALL FTPContent::execute(
+ const Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const Reference<
+ XCommandEnvironment >& Environment
+)
+ throw(
+ Exception,
+ CommandAbortedException,
+ RuntimeException
+ )
+{
+ ACTION action(NOACTION);
+ Any aRet;
+
+ while(true)
+ try {
+ if(action == THROWAUTHENTICATIONREQUEST) {
+ // try to get a continuation first
+ rtl::OUString aRealm,aPassword,aAccount;
+ m_pFCP->forHost(m_aFTPURL.host(),
+ m_aFTPURL.port(),
+ m_aFTPURL.username(),
+ aPassword,
+ aAccount);
+ rtl::Reference<ucbhelper::SimpleAuthenticationRequest>
+ p( new ucbhelper::SimpleAuthenticationRequest(
+ m_aFTPURL.ident(false, false),
+ m_aFTPURL.host(), // ServerName
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_NA,
+ aRealm,
+ ucbhelper::SimpleAuthenticationRequest
+ ::ENTITY_FIXED,
+ m_aFTPURL.username(),
+ ucbhelper::SimpleAuthenticationRequest
+ ::ENTITY_MODIFY,
+ aPassword));
+
+ Reference<XInteractionHandler> xInteractionHandler;
+ if(Environment.is())
+ xInteractionHandler =
+ Environment->getInteractionHandler();
+
+ if( xInteractionHandler.is()) {
+ xInteractionHandler->handle(p.get());
+
+ Reference<XInterface> xSelection(
+ p->getSelection().get());
+
+ if(Reference<XInteractionRetry>(
+ xSelection,UNO_QUERY).is())
+ action = NOACTION;
+ else if(Reference<XInteractionSupplyAuthentication>(
+ xSelection,UNO_QUERY).is()) {
+ m_pFCP->setHost(
+ m_aFTPURL.host(),
+ m_aFTPURL.port(),
+ m_aFTPURL.username(),
+ p->getAuthenticationSupplier()->getPassword(),
+ aAccount);
+ action = NOACTION;
+ }
+ }
+ aRet = p->getRequest();
+ }
+
+// if(aCommand.Name.compareToAscii(
+// "getPropertyValues") == 0 &&
+// action != NOACTION) {
+// // It is not allowed to throw if
+// // command is getPropertyValues
+// rtl::Reference<ucbhelper::PropertyValueSet> xRow =
+// new ucbhelper::PropertyValueSet(m_xSMgr);
+// Sequence<Property> Properties;
+// aCommand.Argument >>= Properties;
+// for(int i = 0; i < Properties.getLength(); ++i)
+// xRow->appendVoid(Properties[i]);
+// aRet <<= Reference<XRow>(xRow.get());
+// return aRet;
+// }
+
+ switch (action)
+ {
+ case NOACTION:
+ break;
+
+ case THROWAUTHENTICATIONREQUEST:
+ ucbhelper::cancelCommandExecution(
+ aRet,
+ Reference<XCommandEnvironment>(0));
+ break;
+
+ case THROWACCESSDENIED:
+ {
+ Sequence<Any> seq(1);
+ PropertyValue value;
+ value.Name = rtl::OUString::createFromAscii("Uri");
+ value.Handle = -1;
+ value.Value <<= m_aFTPURL.ident(false,false);
+ value.State = PropertyState_DIRECT_VALUE;
+ seq[0] <<= value;
+ ucbhelper::cancelCommandExecution(
+ IOErrorCode_ACCESS_DENIED,
+ seq,
+ Environment);
+ break;
+ }
+ case THROWINTERACTIVECONNECT:
+ {
+ InteractiveNetworkConnectException excep;
+ excep.Server = m_aFTPURL.host();
+ aRet <<= excep;
+ ucbhelper::cancelCommandExecution(
+ aRet,
+ Environment);
+ break;
+ }
+ case THROWRESOLVENAME:
+ {
+ InteractiveNetworkResolveNameException excep;
+ excep.Server = m_aFTPURL.host();
+ aRet <<= excep;
+ ucbhelper::cancelCommandExecution(
+ aRet,
+ Environment);
+ break;
+ }
+ case THROWNOFILE:
+ {
+ Sequence<Any> seq(1);
+ PropertyValue value;
+ value.Name = rtl::OUString::createFromAscii("Uri");
+ value.Handle = -1;
+ value.Value <<= m_aFTPURL.ident(false,false);
+ value.State = PropertyState_DIRECT_VALUE;
+ seq[0] <<= value;
+ ucbhelper::cancelCommandExecution(
+ IOErrorCode_NO_FILE,
+ seq,
+ Environment);
+ break;
+ }
+ case THROWQUOTE:
+ case THROWGENERAL:
+ ucbhelper::cancelCommandExecution(
+ IOErrorCode_GENERAL,
+ Sequence<Any>(0),
+ Environment);
+ break;
+ }
+
+ if(aCommand.Name.compareToAscii("getPropertyValues") == 0) {
+ Sequence<Property> Properties;
+ if(!(aCommand.Argument >>= Properties))
+ {
+ aRet <<= IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1);
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+
+ aRet <<= getPropertyValues(Properties,Environment);
+ }
+ else if(aCommand.Name.compareToAscii("setPropertyValues") == 0)
+ {
+ Sequence<PropertyValue> propertyValues;
+
+ if( ! ( aCommand.Argument >>= propertyValues ) ) {
+ aRet <<= IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1);
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+
+ aRet <<= setPropertyValues(propertyValues);
+ }
+ else if(aCommand.Name.compareToAscii("getCommandInfo") == 0) {
+ // Note: Implemented by base class.
+ aRet <<= getCommandInfo(Environment);
+ }
+ else if(aCommand.Name.compareToAscii("getPropertySetInfo") == 0) {
+ // Note: Implemented by base class.
+ aRet <<= getPropertySetInfo(Environment);
+ }
+ else if(aCommand.Name.compareToAscii( "insert" ) == 0)
+ {
+ InsertCommandArgument aInsertArgument;
+ if ( ! ( aCommand.Argument >>= aInsertArgument ) ) {
+ aRet <<= IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1);
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+ insert(aInsertArgument,Environment);
+ }
+ else if(aCommand.Name.compareToAscii("delete") == 0) {
+ m_aFTPURL.del();
+ deleted();
+ }
+ else if(aCommand.Name.compareToAscii( "open" ) == 0) {
+ OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) ) {
+ aRet <<= IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1);
+
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+
+ if(aOpenCommand.Mode == OpenMode::DOCUMENT) {
+ // Open as a document
+ Reference<XActiveDataSink>
+ xActiveDataSink(aOpenCommand.Sink,UNO_QUERY);
+ Reference< XOutputStream >
+ xOutputStream(aOpenCommand.Sink,UNO_QUERY);
+
+ if(xActiveDataSink.is()) {
+ xActiveDataSink->setInputStream(
+ new FTPInputStream(m_aFTPURL.open()));
+ }
+ else if(xOutputStream.is()) {
+ Reference<XInputStream> xStream(
+ new FTPInputStream(m_aFTPURL.open()));
+ Sequence<sal_Int8> byte_seq(4096);
+ sal_Int32 n = 1000; // value does not matter here
+ for (;;) {
+ n = xStream->readBytes(byte_seq,4096);
+ if (n == 0) {
+ break;
+ }
+ try {
+ if(byte_seq.getLength() != n)
+ byte_seq.realloc(n);
+ xOutputStream->writeBytes(byte_seq);
+ } catch(const NotConnectedException&) {
+
+ } catch(const BufferSizeExceededException&) {
+
+ } catch(const IOException&) {
+
+ }
+ }
+ if(n) {
+ Sequence<Any> seq(1);
+ PropertyValue value;
+ value.Name =
+ rtl::OUString::createFromAscii("Uri");
+ value.Handle = -1;
+ value.Value <<= m_aFTPURL.ident(false,false);
+ value.State = PropertyState_DIRECT_VALUE;
+ seq[0] <<= value;
+ ucbhelper::cancelCommandExecution(
+ IOErrorCode_UNKNOWN,
+ seq,
+ Environment);
+ }
+ }
+ else {
+ aRet <<= UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >(this),
+ aOpenCommand.Sink);
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+ }
+ else if(aOpenCommand.Mode == OpenMode::ALL ||
+ aOpenCommand.Mode == OpenMode::DOCUMENTS ||
+ aOpenCommand.Mode == OpenMode::FOLDERS ) {
+ std::vector<FTPDirentry> resvec =
+ m_aFTPURL.list(sal_Int16(aOpenCommand.Mode));
+ Reference< XDynamicResultSet > xSet
+ = new DynamicResultSet(
+ m_xSMgr,
+ this,
+ aOpenCommand,
+ Environment,
+ new ResultSetFactoryI(m_xSMgr,
+ m_xProvider.get(),
+ aOpenCommand.Mode,
+ aOpenCommand.Properties,
+ aOpenCommand.SortingInfo,
+ resvec));
+ aRet <<= xSet;
+ }
+ else if(aOpenCommand.Mode ==
+ OpenMode::DOCUMENT_SHARE_DENY_NONE ||
+ aOpenCommand.Mode ==
+ OpenMode::DOCUMENT_SHARE_DENY_WRITE) {
+ // Unsupported OpenMode
+ aRet <<= UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >(this),
+ static_cast< sal_Int16 >(aOpenCommand.Mode));
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+ else {
+ aRet <<= IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Unexpected OpenMode!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1);
+
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+ } else if(aCommand.Name.compareToAscii("createNewContent") == 0) {
+ ContentInfo aArg;
+ if (!(aCommand.Argument >>= aArg)) {
+ ucbhelper::cancelCommandExecution(
+ makeAny(
+ IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >(this),
+ -1)),
+ Environment);
+ // Unreachable
+ }
+ aRet <<= createNewContent(aArg);
+ } else {
+ aRet <<= UnsupportedCommandException(
+ aCommand.Name,
+ static_cast< cppu::OWeakObject * >(this));
+ ucbhelper::cancelCommandExecution(aRet,Environment);
+ }
+
+ return aRet;
+ } catch(const curl_exception& e) {
+ if(e.code() == CURLE_COULDNT_CONNECT)
+ action = THROWINTERACTIVECONNECT;
+ else if(e.code() == CURLE_COULDNT_RESOLVE_HOST )
+ action = THROWRESOLVENAME;
+ else if(e.code() == CURLE_FTP_USER_PASSWORD_INCORRECT ||
+ e.code() == CURLE_LOGIN_DENIED ||
+ e.code() == CURLE_BAD_PASSWORD_ENTERED ||
+ e.code() == CURLE_FTP_WEIRD_PASS_REPLY)
+ action = THROWAUTHENTICATIONREQUEST;
+ else if(e.code() == CURLE_FTP_ACCESS_DENIED)
+ action = THROWACCESSDENIED;
+ else if(e.code() == CURLE_FTP_QUOTE_ERROR)
+ action = THROWQUOTE;
+ else if(e.code() == CURLE_FTP_COULDNT_RETR_FILE)
+ action = THROWNOFILE;
+ else
+ // nothing known about the cause of the error
+ action = THROWGENERAL;
+ }
+}
+
+#define FTP_FILE rtl::OUString::createFromAscii( \
+ "application/" \
+ "vnd.sun.staroffice.ftp-file")
+
+#define FTP_FOLDER rtl::OUString::createFromAscii( \
+ "application/" \
+ "vnd.sun.staroffice.ftp-folder")
+
+Sequence<ContentInfo > SAL_CALL
+FTPContent::queryCreatableContentsInfo( )
+ throw (RuntimeException)
+{
+ return queryCreatableContentsInfo_Static();
+}
+
+// static
+Sequence<ContentInfo >
+FTPContent::queryCreatableContentsInfo_Static( )
+ throw (RuntimeException)
+{
+ Sequence< ContentInfo > seq(2);
+
+ seq[0].Type = FTP_FILE;
+ seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ContentInfoAttribute::KIND_DOCUMENT;
+ Sequence< Property > props( 1 );
+ props[0] = Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ PropertyAttribute::MAYBEVOID
+ | PropertyAttribute::BOUND );
+ seq[0].Properties = props;
+
+ // folder
+ seq[1].Type = FTP_FOLDER;
+ seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
+ seq[1].Properties = props;
+
+ return seq;
+}
+
+Reference<XContent > SAL_CALL
+FTPContent::createNewContent( const ContentInfo& Info )
+ throw (RuntimeException)
+{
+ if(Info.Type.equalsAscii("application/"
+ "vnd.sun.staroffice.ftp-file") ||
+ Info.Type.equalsAscii("application/"
+ "vnd.sun.staroffice.ftp-folder"))
+ return new FTPContent(m_xSMgr,
+ m_pFCP,
+ m_xIdentifier,Info);
+ else
+ return Reference<XContent>(0);
+}
+
+
+
+
+Reference<XInterface > SAL_CALL
+FTPContent::getParent( )
+ throw (RuntimeException)
+{
+ Reference<XContentIdentifier>
+ xIdent(new FTPContentIdentifier(m_aFTPURL.parent(false)));
+ Reference<XContent> xContent(m_xProvider->queryContent(xIdent));
+ return Reference<XInterface>(xContent,UNO_QUERY);
+}
+
+
+void SAL_CALL
+FTPContent::setParent(const Reference<XInterface >& /*Parent*/ )
+ throw (NoSupportException,
+ RuntimeException)
+{
+ throw NoSupportException();
+}
+
+
+
+rtl::OUString FTPContent::getParentURL()
+{
+ return m_aFTPURL.parent();
+}
+
+
+class InsertData
+ : public CurlInput {
+
+public:
+
+ InsertData(const Reference<XInputStream>& xInputStream)
+ : m_xInputStream(xInputStream) { }
+ virtual ~InsertData() {}
+
+ // returns the number of bytes actually read
+ virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested);
+
+private:
+
+ Reference<XInputStream> m_xInputStream;
+};
+
+
+
+sal_Int32 InsertData::read(sal_Int8 *dest,sal_Int32 nBytesRequested)
+{
+ sal_Int32 m = 0;
+
+ if(m_xInputStream.is()) {
+ Sequence<sal_Int8> seq(nBytesRequested);
+ m = m_xInputStream->readBytes(seq,nBytesRequested);
+ rtl_copyMemory(dest,seq.getConstArray(),m);
+ }
+ return m;
+}
+
+
+void FTPContent::insert(const InsertCommandArgument& aInsertCommand,
+ const Reference<XCommandEnvironment>& Env)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ if(m_bInserted && !m_bTitleSet) {
+ MissingPropertiesException excep;
+ excep.Properties.realloc(1);
+ excep.Properties[0] = rtl::OUString::createFromAscii("Title");
+ Any aAny; aAny <<= excep;
+ ucbhelper::cancelCommandExecution(aAny,Env);
+ }
+
+ if(m_bInserted &&
+ m_aInfo.Type == FTP_FILE &&
+ !aInsertCommand.Data.is())
+ {
+ MissingInputStreamException excep;
+ Any aAny; aAny <<= excep;
+ ucbhelper::cancelCommandExecution(aAny,Env);
+ }
+
+ bool bReplace(aInsertCommand.ReplaceExisting);
+
+ retry:
+ try {
+ if(m_aInfo.Type == FTP_FILE) {
+ InsertData data(aInsertCommand.Data);
+ m_aFTPURL.insert(bReplace,&data);
+ } else if(m_aInfo.Type == FTP_FOLDER)
+ m_aFTPURL.mkdir(bReplace);
+ } catch(const curl_exception& e) {
+ if(e.code() == FILE_EXIST_DURING_INSERT ||
+ e.code() == FOLDER_EXIST_DURING_INSERT) {
+ // Deprecated, not used anymore:
+ NameClashException excep;
+ excep.Name = m_aFTPURL.child();
+ Any aAny;
+ aAny <<= excep;
+ ucbhelper::cancelCommandExecution(aAny,Env);
+ } else if(e.code() == FOLDER_MIGHT_EXIST_DURING_INSERT ||
+ e.code() == FILE_MIGHT_EXIST_DURING_INSERT) {
+ // Interact
+ Reference<XInteractionHandler> xInt;
+ if(Env.is())
+ xInt = Env->getInteractionHandler();
+
+ UnsupportedNameClashException excep;
+ excep.NameClash = 0; //NameClash::ERROR;
+
+ if(!xInt.is()) {
+ Any aAny;
+ aAny <<= excep;
+ ucbhelper::cancelCommandExecution(aAny,Env);
+ }
+
+ XInteractionRequestImpl* p =
+ new XInteractionRequestImpl(m_aFTPURL.child());
+ Reference<XInteractionRequest> req(p);
+ xInt->handle(req);
+ if(p->approved()) {
+ bReplace = true;
+ goto retry;
+ }
+ else
+ throw excep;
+ }
+ else
+ throw;
+ }
+
+ // May not be reached, because both mkdir and insert can throw curl-
+ // exceptions
+ m_bInserted = false;
+ inserted();
+}
+
+
+
+Reference< XRow > FTPContent::getPropertyValues(
+ const Sequence< Property >& seqProp,
+ const Reference<XCommandEnvironment>& /*environment*/
+)
+{
+ rtl::Reference<ucbhelper::PropertyValueSet> xRow =
+ new ucbhelper::PropertyValueSet(m_xSMgr);
+
+ FTPDirentry aDirEntry = m_aFTPURL.direntry();
+
+ for(sal_Int32 i = 0; i < seqProp.getLength(); ++i) {
+ const rtl::OUString& Name = seqProp[i].Name;
+ if(Name.compareToAscii("Title") == 0)
+ xRow->appendString(seqProp[i],aDirEntry.m_aName);
+ else if(Name.compareToAscii("CreatableContentsInfo") == 0)
+ xRow->appendObject(seqProp[i],
+ makeAny(queryCreatableContentsInfo()));
+ else if(aDirEntry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN) {
+ if(Name.compareToAscii("ContentType") == 0)
+ xRow->appendString(seqProp[i],
+ aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR
+ ? FTP_FOLDER
+ : FTP_FILE );
+ else if(Name.compareToAscii("IsReadOnly") == 0)
+ xRow->appendBoolean(seqProp[i],
+ aDirEntry.m_nMode
+ & INETCOREFTP_FILEMODE_WRITE
+ ? 0
+ : 1 );
+ else if(Name.compareToAscii("IsDocument") == 0)
+ xRow->appendBoolean(seqProp[i],
+ ! sal_Bool(aDirEntry.m_nMode &
+ INETCOREFTP_FILEMODE_ISDIR));
+ else if(Name.compareToAscii("IsFolder") == 0)
+ xRow->appendBoolean(seqProp[i],
+ sal_Bool(aDirEntry.m_nMode &
+ INETCOREFTP_FILEMODE_ISDIR));
+ else if(Name.compareToAscii("Size") == 0)
+ xRow->appendLong(seqProp[i],
+ aDirEntry.m_nSize);
+ else if(Name.compareToAscii("DateCreated") == 0)
+ xRow->appendTimestamp(seqProp[i],
+ aDirEntry.m_aDate);
+ else
+ xRow->appendVoid(seqProp[i]);
+ } else
+ xRow->appendVoid(seqProp[i]);
+ }
+
+ return Reference<XRow>(xRow.get());
+}
+
+
+
+Sequence<Any> FTPContent::setPropertyValues(
+ const Sequence<PropertyValue>& seqPropVal)
+{
+ Sequence<Any> ret(seqPropVal.getLength());
+ Sequence<PropertyChangeEvent > evt;
+
+ osl::MutexGuard aGuard(m_aMutex);
+ for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
+ if(seqPropVal[i].Name.equalsAscii("Title")) {
+ rtl::OUString Title;
+ if(!(seqPropVal[i].Value >>= Title)) {
+ ret[i] <<= IllegalTypeException();
+ continue;
+ } else if(!Title.getLength()) {
+ ret[i] <<= IllegalArgumentException();
+ continue;
+ }
+
+ if(m_bInserted) {
+ m_aFTPURL.child(Title);
+ m_xIdentifier =
+ new FTPContentIdentifier(m_aFTPURL.ident(false,false));
+ m_bTitleSet = true;
+ } else
+ try {
+ rtl::OUString OldTitle = m_aFTPURL.ren(Title);
+ evt.realloc(1);
+ evt[0].PropertyName =
+ rtl::OUString::createFromAscii("Title");
+ evt[0].Further = false;
+ evt[0].PropertyHandle = -1;
+ evt[0].OldValue <<= OldTitle;
+ evt[0].NewValue <<= Title;
+ } catch(const curl_exception&) {
+ InteractiveIOException excep;
+ // any better possibility here?
+ // ( the error code is always CURLE_FTP_QUOTE_ERROR )
+ excep.Code = IOErrorCode_ACCESS_DENIED;
+ ret[i] <<= excep;
+ }
+ } else {
+ Sequence<Property> props =
+ getProperties(Reference<XCommandEnvironment>(0));
+
+ // either unknown or read-only
+ ret[i] <<= UnknownPropertyException();
+ for(sal_Int32 j = 0; j < props.getLength(); ++j)
+ if(props[j].Name == seqPropVal[i].Name) {
+ ret[i] <<= IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!"),
+ //props[j].Attributes & PropertyAttribute::READONLY
+ // ? "Property is read-only!"
+ // : "Access denied!"),
+ static_cast< cppu::OWeakObject * >( this ));
+ break;
+ }
+ }
+ }
+
+ if(evt.getLength()) {
+ // title has changed
+ notifyPropertiesChange(evt);
+ exchange(new FTPContentIdentifier(m_aFTPURL.ident(false,false)));
+ }
+
+ return ret;
+}
diff --git a/ucb/source/ucp/ftp/ftpcontent.hxx b/ucb/source/ucp/ftp/ftpcontent.hxx
new file mode 100644
index 000000000000..234810bd1eb9
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontent.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FTP_FTPCONTENT_HXX
+#define _FTP_FTPCONTENT_HXX
+
+#include <ucbhelper/contenthelper.hxx>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include "ftpurl.hxx"
+
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+ struct PropertyValue;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class XRow;
+} } } }
+
+
+namespace ftp
+{
+
+//=========================================================================
+
+// UNO service name for the content.
+#define FTP_CONTENT_SERVICE_NAME "com.sun.star.ucb.FTPContent"
+
+//=========================================================================
+
+ class FTPContentProvider;
+
+//=========================================================================
+
+ class FTPContent
+ : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+ {
+ public:
+
+ FTPContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ FTPContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const FTPURL& FtpUrl);
+
+ FTPContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ FTPContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& aInfo);
+
+
+ virtual ~FTPContent();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ abort(sal_Int32 CommandId)
+ throw( com::sun::star::uno::RuntimeException);
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo( )
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw (com::sun::star::uno::RuntimeException);
+
+ // XChild
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface > SAL_CALL
+ getParent( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setParent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >& Parent )
+ throw (::com::sun::star::lang::NoSupportException,
+ ::com::sun::star::uno::RuntimeException);
+
+
+ static com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo >
+ queryCreatableContentsInfo_Static( )
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+
+ FTPContentProvider *m_pFCP;
+ FTPURL m_aFTPURL;
+ bool m_bInserted;
+ bool m_bTitleSet;
+ com::sun::star::ucb::ContentInfo m_aInfo;
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+
+
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::CommandInfo>
+ getCommands(const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv);
+
+
+ virtual ::rtl::OUString getParentURL();
+
+ com::sun::star::uno::Reference<com::sun::star::sdbc::XRow>
+ getPropertyValues(
+ const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property>& seqProp,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment
+ );
+
+ com::sun::star::uno::Sequence<com::sun::star::uno::Any>
+ setPropertyValues(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue>& seqPropVal);
+
+ void insert(const com::sun::star::ucb::InsertCommandArgument&,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment>&);
+ };
+
+}
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpcontentcaps.cxx b/ucb/source/ucp/ftp/ftpcontentcaps.cxx
new file mode 100644
index 000000000000..421d44401f6d
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontentcaps.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "ftpcontent.hxx"
+
+using namespace com::sun::star;
+using namespace ftp;
+
+// virtual
+uno::Sequence< beans::Property > FTPContent::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/)
+{
+ #define PROPS_COUNT 8
+
+ static const beans::Property aPropsInfoTable[] =
+ {
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ // | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
+ -1,
+ getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
+ -1,
+ getCppuType( static_cast< util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType(
+ static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+
+ return uno::Sequence< beans::Property >( aPropsInfoTable, PROPS_COUNT );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > FTPContent::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+// osl::MutexGuard aGuard( m_aMutex );
+
+ //=================================================================
+ //
+ // Supported commands
+ //
+ //=================================================================
+
+ #define COMMAND_COUNT 8
+
+ static const ucb::CommandInfo aCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::InsertCommandArgument * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ };
+
+ return uno::Sequence< ucb::CommandInfo >( aCommandInfoTable, COMMAND_COUNT );
+}
+
diff --git a/ucb/source/ucp/ftp/ftpcontentidentifier.cxx b/ucb/source/ucp/ftp/ftpcontentidentifier.cxx
new file mode 100644
index 000000000000..0d65c06a9281
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontentidentifier.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include "ftpcontentidentifier.hxx"
+#include "ftpcontentprovider.hxx"
+
+using namespace ftp;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::lang;
+
+
+FTPContentIdentifier::FTPContentIdentifier(
+ const rtl::OUString& ident
+)
+ : m_ident(ident)
+{
+}
+
+
+FTPContentIdentifier::~FTPContentIdentifier()
+{
+}
+
+
+Any SAL_CALL
+FTPContentIdentifier::queryInterface(
+ const Type& rType
+)
+ throw(
+ RuntimeException
+ )
+{
+ Any aRet =
+ ::cppu::queryInterface(rType,
+ SAL_STATIC_CAST(XTypeProvider*,this),
+ SAL_STATIC_CAST(XContentIdentifier*,this));
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+void SAL_CALL FTPContentIdentifier::acquire( void ) throw() {
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL FTPContentIdentifier::release( void ) throw() {
+ OWeakObject::release();
+}
+
+
+Sequence<sal_Int8> SAL_CALL
+FTPContentIdentifier::getImplementationId()
+ throw(RuntimeException)
+{
+ static cppu::OImplementationId* pId = NULL;
+ if(!pId)
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pId )
+ {
+ static cppu::OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return (*pId).getImplementationId();
+}
+
+
+Sequence<Type> SAL_CALL
+FTPContentIdentifier::getTypes(
+ void )
+ throw(RuntimeException)
+{
+ static cppu::OTypeCollection* pCollection = NULL;
+ if ( !pCollection ) {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection collection(
+ getCppuType(
+ static_cast<Reference<XTypeProvider>*>(0)),
+ getCppuType(
+ static_cast<Reference<XContentIdentifier>*>(0)));
+ pCollection = &collection;
+ }
+ }
+ return (*pCollection).getTypes();
+}
+
+
+rtl::OUString SAL_CALL
+FTPContentIdentifier::getContentIdentifier(
+)
+ throw (
+ com::sun::star::uno::RuntimeException
+ )
+{
+ return m_ident;
+}
+
+
+rtl::OUString SAL_CALL
+FTPContentIdentifier::getContentProviderScheme(
+)
+ throw (
+ com::sun::star::uno::RuntimeException
+ )
+{
+ return rtl::OUString::createFromAscii("ftp");
+}
+
+
+
+
+
+
diff --git a/ucb/source/ucp/ftp/ftpcontentidentifier.hxx b/ucb/source/ucp/ftp/ftpcontentidentifier.hxx
new file mode 100644
index 000000000000..7827fc7148eb
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontentidentifier.hxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _FTP_FTPCONTENTIDENTIFIER_HXX_
+#define _FTP_FTPCONTENTIDENTIFIER_HXX_
+
+#include <vector>
+#include "curl.hxx"
+#include <curl/easy.h>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+
+#include "ftpdirp.hxx"
+#include "ftpurl.hxx"
+
+
+namespace ftp {
+
+
+ class FTPContentProvider;
+
+
+ class FTPContentIdentifier
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::ucb::XContentIdentifier
+ {
+ public:
+
+ FTPContentIdentifier(const rtl::OUString& ident);
+
+ ~FTPContentIdentifier();
+
+ // XInterface
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL acquire( void ) throw();
+
+ virtual void SAL_CALL release( void ) throw();
+
+ // XTypeProvider
+
+ virtual
+ com::sun::star::uno::Sequence<com::sun::star::uno::Type> SAL_CALL
+ getTypes(
+ )
+ throw(
+ com::sun::star::uno::RuntimeException
+ );
+
+ virtual com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId(
+ )
+ throw(
+ com::sun::star::uno::RuntimeException
+ );
+
+
+ // XContentIdentifier
+
+ virtual ::rtl::OUString SAL_CALL
+ getContentIdentifier(
+ )
+ throw (
+ com::sun::star::uno::RuntimeException
+ );
+
+ virtual ::rtl::OUString SAL_CALL
+ getContentProviderScheme(
+ )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+
+
+ private:
+
+ rtl::OUString m_ident;
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpcontentprovider.cxx b/ucb/source/ucp/ftp/ftpcontentprovider.cxx
new file mode 100644
index 000000000000..2cfc62afe440
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontentprovider.cxx
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <ucbhelper/contentbroker.hxx>
+#include <osl/socket.hxx>
+#include "ftpcontentprovider.hxx"
+#include "ftpcontent.hxx"
+#include "ftploaderthread.hxx"
+
+
+using namespace ftp;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::beans;
+
+
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+FTPContentProvider::FTPContentProvider(
+ const Reference< XMultiServiceFactory >& rSMgr)
+: ::ucbhelper::ContentProviderImplHelper(rSMgr),
+ m_ftpLoaderThread(0),
+ m_pProxyDecider(0)
+{
+}
+
+//=========================================================================
+// virtual
+FTPContentProvider::~FTPContentProvider()
+{
+ delete m_ftpLoaderThread;
+ delete m_pProxyDecider;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3(FTPContentProvider,
+ XTypeProvider,
+ XServiceInfo,
+ XContentProvider)
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3(FTPContentProvider,
+ XTypeProvider,
+ XServiceInfo,
+ XContentProvider)
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1(
+ FTPContentProvider,
+ rtl::OUString::createFromAscii("com.sun.star.comp.FTPContentProvider"),
+ rtl::OUString::createFromAscii(FTP_CONTENT_PROVIDER_SERVICE_NAME));
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL(FTPContentProvider);
+
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+Reference<XContent> SAL_CALL
+FTPContentProvider::queryContent(
+ const Reference< XContentIdentifier >& xCanonicId
+)
+ throw(
+ IllegalIdentifierException,
+ RuntimeException
+ )
+{
+ // Check, if a content with given id already exists...
+ Reference<XContent> xContent = queryExistingContent(xCanonicId).get();
+ if(xContent.is())
+ return xContent;
+
+ // A new content has to be returned:
+ {
+ // Initialize
+ osl::MutexGuard aGuard( m_aMutex );
+ if(!m_ftpLoaderThread || !m_pProxyDecider)
+ {
+ try {
+ init();
+ } catch( ... ) {
+ throw RuntimeException();
+ }
+
+ if(!m_ftpLoaderThread || !m_pProxyDecider)
+ throw RuntimeException();
+ }
+ }
+
+ try {
+ FTPURL aURL(xCanonicId->getContentIdentifier(),
+ this);
+
+ if(!m_pProxyDecider->shouldUseProxy(
+ rtl::OUString::createFromAscii("ftp"),
+ aURL.host(),
+ aURL.port().toInt32()))
+ {
+ xContent = new FTPContent(m_xSMgr,this,xCanonicId,aURL);
+ registerNewContent(xContent);
+ }
+ else {
+ Reference<XContentProvider>
+ xProvider(getHttpProvider());
+ if(xProvider.is())
+ return xProvider->queryContent(xCanonicId);
+ else
+ throw RuntimeException();
+ }
+ } catch(const malformed_exception&) {
+ throw IllegalIdentifierException();
+ }
+
+ // may throw IllegalIdentifierException
+ return xContent;
+}
+
+
+
+
+void FTPContentProvider::init() {
+ m_ftpLoaderThread = new FTPLoaderThread();
+ m_pProxyDecider = new ucbhelper::InternetProxyDecider(m_xSMgr);
+}
+
+
+
+CURL* FTPContentProvider::handle() {
+ // Cannot be zero if called from here;
+ return m_ftpLoaderThread->handle();
+}
+
+
+bool FTPContentProvider::forHost(
+ const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ rtl::OUString& password,
+ rtl::OUString& account)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ for(unsigned int i = 0; i < m_ServerInfo.size(); ++i)
+ if(host == m_ServerInfo[i].host &&
+ port == m_ServerInfo[i].port &&
+ username == m_ServerInfo[i].username )
+ {
+ password = m_ServerInfo[i].password;
+ account = m_ServerInfo[i].account;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool FTPContentProvider::setHost(
+ const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ const rtl::OUString& password,
+ const rtl::OUString& account)
+{
+ ServerInfo inf;
+ inf.host = host;
+ inf.port = port;
+ inf.username = username;
+ inf.password = password;
+ inf.account = account;
+
+ bool present(false);
+ osl::MutexGuard aGuard(m_aMutex);
+ for(unsigned int i = 0; i < m_ServerInfo.size(); ++i)
+ if(host == m_ServerInfo[i].host &&
+ port == m_ServerInfo[i].port &&
+ username == m_ServerInfo[i].username)
+ {
+ present = true;
+ m_ServerInfo[i].password = password;
+ m_ServerInfo[i].account = account;
+ }
+
+ if(!present)
+ m_ServerInfo.push_back(inf);
+
+ return !present;
+}
+
+
+
+Reference<XContentProvider>
+FTPContentProvider::getHttpProvider()
+ throw(RuntimeException)
+{
+ // used for access to ftp-proxy
+ ucbhelper::ContentBroker *pBroker = ucbhelper::ContentBroker::get();
+
+ if(pBroker) {
+ Reference<XContentProviderManager > xManager(
+ pBroker->getContentProviderManagerInterface());
+
+ if(xManager.is())
+ return
+ xManager->queryContentProvider(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http:")));
+ else
+ throw RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "bad ucbhelper::ContentBroker")),
+ *this);
+ } else
+ return 0;
+
+}
diff --git a/ucb/source/ucp/ftp/ftpcontentprovider.hxx b/ucb/source/ucp/ftp/ftpcontentprovider.hxx
new file mode 100644
index 000000000000..30b74a5f44c8
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpcontentprovider.hxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FTP_FTPCONTENTPROVIDER_HXX_
+#define _FTP_FTPCONTENTPROVIDER_HXX_
+
+#include <vector>
+#include <osl/mutex.hxx>
+#include <ucbhelper/macros.hxx>
+#include <ucbhelper/proxydecider.hxx>
+#include <ucbhelper/providerhelper.hxx>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include "ftphandleprovider.hxx"
+#include "ftpurl.hxx"
+
+// UNO service name for the provider. This name will be used by the UCB to
+// create instances of the provider.
+
+#define FTP_CONTENT_PROVIDER_SERVICE_NAME "com.sun.star.ucb.FTPContentProvider"
+#define FTP_CONTENT_TYPE "application/ftp-content"
+
+
+/**
+ * Definition of ftpcontentprovider
+ */
+
+
+
+namespace ftp {
+
+
+ class FTPLoaderThread;
+
+
+ class FTPContentProvider:
+ public ::ucbhelper::ContentProviderImplHelper,
+ public FTPHandleProvider
+ {
+ public:
+
+ FTPContentProvider(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory>& xMSF );
+
+ ~FTPContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ queryContent(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+
+ // FTPHandleProvider.
+
+ virtual CURL* handle();
+
+ virtual bool forHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ rtl::OUString& password,
+ rtl::OUString& account);
+
+ virtual bool setHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ const rtl::OUString& password,
+ const rtl::OUString& account);
+
+
+ struct ServerInfo {
+ rtl::OUString host;
+ rtl::OUString port;
+ rtl::OUString username;
+ rtl::OUString password;
+ rtl::OUString account;
+ };
+
+ private:
+
+ osl::Mutex m_aMutex;
+ FTPLoaderThread *m_ftpLoaderThread;
+ ucbhelper::InternetProxyDecider *m_pProxyDecider;
+ std::vector<ServerInfo> m_ServerInfo;
+
+ void init();
+
+ com::sun::star::uno::Reference<com::sun::star::ucb::XContentProvider>
+ getHttpProvider()
+ throw(com::sun::star::uno::RuntimeException);
+
+ }; // end class FTPContentProvider
+
+} // end namespace ftp
+
+#endif
+
diff --git a/ucb/source/ucp/ftp/ftpdirp.cxx b/ucb/source/ucp/ftp/ftpdirp.cxx
new file mode 100644
index 000000000000..10f6fa88a6c0
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpdirp.cxx
@@ -0,0 +1,1292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include "ftpdirp.hxx"
+#include <osl/time.h>
+
+
+using namespace rtl;
+using namespace ftp;
+
+
+typedef sal_uInt32 ULONG;
+
+
+inline sal_Bool ascii_isLetter( sal_Unicode ch )
+{
+ return (( (ch >= 0x0041) && (ch <= 0x005A)) ||
+ (( ch >= 0x0061) && (ch <= 0x007A)));
+}
+
+inline sal_Bool ascii_isWhitespace( sal_Unicode ch )
+{
+ return ((ch <= 0x20) && ch);
+}
+
+
+
+/*========================================================================
+ *
+ * FTPDirectoryParser implementation.
+ *
+ *======================================================================*/
+/*
+ * parseDOS.
+ * Accepts one of two styles:
+ *
+ * 1 *WSP 1*2DIGIT ("." / "-") 1*2DIGIT ("." / "-") 1*4DIGIT 1*WSP
+ * 1*2DIGIT ":" 1*2DIGIT [*WSP ("A" / "P") "M"] 1*WSP
+ * ((DIGIT *(DIGIT / "." / ",")) / "<DIR>") 1*WSP 1*OCTET
+ *
+ * interpreted as: mm.dd.yy hh:mm (size / <DIR>) name
+ *
+ * 2 *WSP 1*DIGIT 1*WSP *(1*CHAR *WSP) *1("DIR" 1*WSP) 1*2DIGIT "-" 1*2DIGIT
+ * "-" 1*4DIGIT 1*WSP 1*2DIGIT ":" 1*2DIGIT 1*WSP 1*OCTET
+ *
+ * interpreted as: size attribs DIR mm-dd-yy hh:mm name
+ */
+
+sal_Bool FTPDirectoryParser::parseDOS (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer)
+{
+ sal_Bool bDirectory = false;
+ sal_uInt32 nSize = 0;
+ sal_uInt16 nYear = 0;
+ sal_uInt16 nMonth = 0;
+ sal_uInt16 nDay = 0;
+ sal_uInt16 nHour = 0;
+ sal_uInt16 nMinute = 0;
+
+ enum StateType
+ {
+ STATE_INIT_LWS,
+ STATE_MONTH_OR_SIZE,
+ STATE_1_DAY, STATE_1_YEAR, STATE_1_YEAR_LWS, STATE_1_HOUR,
+ STATE_1_MINUTE, STATE_1_MINUTE_LWS, STATE_1_AP,
+ STATE_1_APM, STATE_1_LESS, STATE_1_D, STATE_1_DI,
+ STATE_1_DIR, STATE_1_SIZE,
+ STATE_2_SIZE, STATE_2_SIZE_LWS, STATE_2_ATTRIB,
+ STATE_2_D, STATE_2_DI, STATE_2_DIR_LWS,
+ STATE_2_MONTH, STATE_2_DAY, STATE_2_YEAR, STATE_2_YEAR_LWS,
+ STATE_2_HOUR, STATE_2_MINUTE,
+ STATE_LWS_NAME,
+ STATE_ERROR
+ };
+
+ int nDigits = 0;
+ enum StateType eState = STATE_INIT_LWS;
+ for (const sal_Char *p = pBuffer;
+ eState != STATE_ERROR && *p;
+ ++p)
+ {
+ switch (eState)
+ {
+ case STATE_INIT_LWS:
+ if (*p >= '0' && *p <= '9')
+ {
+ nMonth = *p - '0';
+ nDigits = 1;
+ eState = STATE_MONTH_OR_SIZE;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_MONTH_OR_SIZE:
+ if (*p >= '0' && *p <= '9')
+ {
+ nMonth = 10 * nMonth + (*p - '0');
+ if (nDigits < 2)
+ ++nDigits;
+ else
+ {
+ nSize = nMonth;
+ nMonth = 0;
+ eState = STATE_2_SIZE;
+ }
+ }
+ else if (ascii_isWhitespace(*p))
+ {
+ nSize = nMonth;
+ nMonth = 0;
+ eState = STATE_2_SIZE_LWS;
+ }
+ else if ((*p == '.' || *p == '-') && nMonth && nMonth <= 12)
+ {
+ nDigits = 0;
+ eState = STATE_1_DAY;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_DAY:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nDay = 10 * nDay + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if ((*p == '.' || *p == '-') && nDay && nDay <= 31)
+ {
+ nDigits = 0;
+ eState = STATE_1_YEAR;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_YEAR:
+ if (*p >= '0' && *p <= '9')
+ {
+ if (nDigits < 4)
+ {
+ nYear = 10 * nYear + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ }
+ else
+ {
+ if (ascii_isWhitespace(*p))
+ eState = STATE_1_YEAR_LWS;
+ else
+ eState = STATE_ERROR;
+ }
+ break;
+
+ case STATE_1_YEAR_LWS:
+ if (*p >= '0' && *p <= '9')
+ {
+ nHour = *p - '0';
+ nDigits = 1;
+ eState = STATE_1_HOUR;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_HOUR:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nHour = 10 * nHour + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if (*p == ':' && nHour < 24)
+ {
+ nDigits = 0;
+ eState = STATE_1_MINUTE;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_MINUTE:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nMinute = 10 * nMinute + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if ((*p == 'a' || *p == 'A') && nMinute < 60)
+ if (nHour >= 1 && nHour <= 11)
+ eState = STATE_1_AP;
+ else if (nHour == 12)
+ {
+ nHour = 0;
+ eState = STATE_1_AP;
+ }
+ else
+ eState = STATE_ERROR;
+ else if ((*p == 'p' || *p == 'P') && nMinute < 60)
+ if (nHour >= 1 && nHour <= 11)
+ {
+ nHour += 12;
+ eState = STATE_1_AP;
+ }
+ else if (nHour == 12)
+ eState = STATE_1_AP;
+ else
+ eState = STATE_ERROR;
+ else if (ascii_isWhitespace(*p) && (nMinute < 60))
+ eState = STATE_1_MINUTE_LWS;
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_MINUTE_LWS:
+ if (*p == 'a' || *p == 'A')
+ if (nHour >= 1 && nHour <= 11)
+ eState = STATE_1_AP;
+ else if (nHour == 12)
+ {
+ nHour = 0;
+ eState = STATE_1_AP;
+ }
+ else
+ eState = STATE_ERROR;
+ else if (*p == 'p' || *p == 'P')
+ if (nHour >= 1 && nHour <= 11)
+ {
+ nHour += 12;
+ eState = STATE_1_AP;
+ }
+ else if (nHour == 12)
+ eState = STATE_1_AP;
+ else
+ eState = STATE_ERROR;
+ else if (*p == '<')
+ eState = STATE_1_LESS;
+ else if (*p >= '0' && *p <= '9')
+ {
+ nSize = *p - '0';
+ eState = STATE_1_SIZE;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_AP:
+ eState = *p == 'm' || *p == 'M' ? STATE_1_APM : STATE_ERROR;
+ break;
+
+ case STATE_1_APM:
+ if (*p == '<')
+ eState = STATE_1_LESS;
+ else if (*p >= '0' && *p <= '9')
+ {
+ nSize = *p - '0';
+ eState = STATE_1_SIZE;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_LESS:
+ eState = *p == 'd' || *p == 'D' ? STATE_1_D : STATE_ERROR;
+ break;
+
+ case STATE_1_D:
+ eState = *p == 'i' || *p == 'I' ? STATE_1_DI : STATE_ERROR;
+ break;
+
+ case STATE_1_DI:
+ eState = *p == 'r' || *p == 'R' ? STATE_1_DIR : STATE_ERROR;
+ break;
+
+ case STATE_1_DIR:
+ if (*p == '>')
+ {
+ bDirectory = true;
+ eState = STATE_LWS_NAME;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_1_SIZE:
+ if (*p >= '0' && *p <= '9')
+ nSize = 10 * nSize + (*p - '0');
+ else if (ascii_isWhitespace(*p))
+ eState = STATE_LWS_NAME;
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_SIZE:
+ if (*p >= '0' && *p <= '9')
+ nSize = 10 * nSize + (*p - '0');
+ else if (ascii_isWhitespace(*p))
+ eState = STATE_2_SIZE_LWS;
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_SIZE_LWS:
+ if (*p == 'd' || *p == 'D')
+ eState = STATE_2_D;
+ else if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
+ eState = STATE_2_ATTRIB;
+ else if (*p >= '0' && *p <= '9')
+ {
+ nMonth = *p - '0';
+ nDigits = 1;
+ eState = STATE_2_MONTH;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_ATTRIB:
+ if (ascii_isWhitespace(*p))
+ eState = STATE_2_SIZE_LWS;
+ else if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z'))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_D:
+ if (*p == 'i' || *p == 'I')
+ eState = STATE_2_DI;
+ else if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
+ eState = STATE_2_ATTRIB;
+ else if (ascii_isWhitespace(*p))
+ eState = STATE_2_SIZE_LWS;
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_DI:
+ if (*p == 'r' || *p == 'R')
+ {
+ bDirectory = true;
+ eState = STATE_2_DIR_LWS;
+ }
+ else
+ {
+ if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
+ eState = STATE_2_ATTRIB;
+ else if (ascii_isWhitespace(*p))
+ eState = STATE_2_SIZE_LWS;
+ else
+ eState = STATE_ERROR;
+ }
+ break;
+
+ case STATE_2_DIR_LWS:
+ if (*p >= '0' && *p <= '9')
+ {
+ nMonth = *p - '0';
+ nDigits = 1;
+ eState = STATE_2_MONTH;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_MONTH:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nMonth = 10 * nMonth + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if (*p == '-' && nMonth && nMonth <= 12)
+ {
+ nDigits = 0;
+ eState = STATE_2_DAY;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_DAY:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nDay = 10 * nDay + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if (*p == '-' && nDay && nDay <= 31)
+ {
+ nDigits = 0;
+ eState = STATE_2_YEAR;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_YEAR:
+ if (*p >= '0' && *p <= '9')
+ {
+ if (nDigits < 4)
+ {
+ nYear = 10 * nYear + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ }
+ else
+ {
+ if (ascii_isWhitespace(*p))
+ eState = STATE_2_YEAR_LWS;
+ else
+ eState = STATE_ERROR;
+ }
+ break;
+
+ case STATE_2_YEAR_LWS:
+ if (*p >= '0' && *p <= '9')
+ {
+ nHour = *p - '0';
+ nDigits = 1;
+ eState = STATE_2_HOUR;
+ }
+ else if (!ascii_isWhitespace(*p))
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_HOUR:
+ if (*p >= '0' && *p <= '9')
+ if (nDigits < 2)
+ {
+ nHour = 10 * nHour + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ else if (*p == ':' && nHour < 24)
+ {
+ nDigits = 0;
+ eState = STATE_2_MINUTE;
+ }
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_2_MINUTE:
+ if (*p >= '0' && *p <= '9')
+ {
+ if (nDigits < 2)
+ {
+ nMinute = 10 * nMinute + (*p - '0');
+ ++nDigits;
+ }
+ else
+ eState = STATE_ERROR;
+ }
+ else
+ {
+ if (ascii_isWhitespace(*p) && (nMinute < 60))
+ eState = STATE_LWS_NAME;
+ else
+ eState = STATE_ERROR;
+ }
+ break;
+
+ case STATE_LWS_NAME:
+ if (!ascii_isWhitespace(*p))
+ {
+ setPath (rEntry.m_aName, p);
+ if (bDirectory)
+ rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISDIR;
+ rEntry.m_nSize = nSize;
+
+ setYear (rEntry.m_aDate, nYear);
+
+ rEntry.m_aDate.SetMonth(nMonth);
+ rEntry.m_aDate.SetDay(nDay);
+ rEntry.m_aDate.SetHour(nHour);
+ rEntry.m_aDate.SetMin(nMinute);
+
+ return sal_True;
+ }
+ break;
+ case STATE_ERROR:
+ break;
+ }
+ }
+
+ return sal_False;
+}
+
+/*
+ * parseVMS.
+ * Directory entries may span one or two lines:
+ *
+ * entry: *lws name *1(*lws <NEWLINE>) 1*lws size 1*lws datetime rest
+ *
+ * name: filename "." filetype ";" version
+ * filename: 1*39fchar
+ * filetype: 1*39fchar
+ * version: non0digit *digit
+ *
+ * size: "0" / non0digit *digit
+ *
+ * datetime: date 1*lwsp time
+ * date: day "-" month "-" year
+ * day: (*1"0" non0digit) / ("1"-"2" digit) / ("3" "0"-"1")
+ * month: "JAN" / "FEB" / "MAR" / "APR" / "MAY" / "JUN" / "JUL" / "AUG"
+ * / "SEP" / "OCT" / "NOV" / "DEC" ; all case insensitive
+ * year: 2digit / 4digit
+ * time: hour ":" minute
+ * hour: ((*1"0" / "1") digit) / ("2" "0"-"3")
+ * minute: "0"-"5" digit
+ *
+ * rest: *1(lws *<ANY>)
+ *
+ * lws: <TAB> / <SPACE>
+ * non0digit: "1"-"9"
+ * digit: "0" / non0digit
+ * fchar: "A"-"Z" / "a"-"z" / digit / "-" / "_" / "$"
+ *
+ * For directories, the returned name is the <filename> part; for non-
+ * directory files, the returned name is the <filename "." filetype> part.
+ * An entry is a directory iff its filetype is "DIR" (ignoring case).
+ *
+ * The READ, WRITE, and ISLINK mode bits are not supported.
+ *
+ * The returned size is the <size> part, multiplied by 512, and with the high
+ * order bits truncated to fit into a ULONG.
+ *
+ */
+sal_Bool FTPDirectoryParser::parseVMS (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer)
+{
+ static OUString aFirstLineName;
+ static sal_Bool bFirstLineDir = sal_False;
+
+ for (sal_Bool bFirstLine = sal_True;; bFirstLine = sal_False)
+ {
+ const sal_Char *p = pBuffer;
+ if (bFirstLine)
+ {
+ // Skip <*lws> part:
+ while (*p == '\t' || *p == ' ')
+ ++p;
+
+ // Parse <filename "."> part:
+ const sal_Char *pFileName = p;
+ while ((*p >= 'A' && *p <= 'Z') ||
+ (*p >= 'a' && *p <= 'z') ||
+ (*p >= '0' && *p <= '9') ||
+ *p == '-' || *p == '_' || *p == '$')
+ ++p;
+
+ if (*p != '.' || p == pFileName || p - pFileName > 39)
+ {
+ if (aFirstLineName.getLength())
+ continue;
+ else
+ return sal_False;
+ }
+
+ // Parse <filetype ";"> part:
+ const sal_Char *pFileType = ++p;
+ while ((*p >= 'A' && *p <= 'Z') ||
+ (*p >= 'a' && *p <= 'z') ||
+ (*p >= '0' && *p <= '9') ||
+ *p == '-' || *p == '_' || *p == '$')
+ ++p;
+
+ if (*p != ';' || p == pFileName || p - pFileName > 39)
+ {
+ if (aFirstLineName.getLength())
+ continue;
+ else
+ return sal_False;
+ }
+ ++p;
+
+ // Set entry's name and mode (ISDIR flag):
+ if ((p - pFileType == 4) &&
+ (pFileType[0] == 'D' || pFileType[0] == 'd') &&
+ (pFileType[1] == 'I' || pFileType[1] == 'i') &&
+ (pFileType[2] == 'R' || pFileType[2] == 'r') )
+ {
+ setPath (rEntry.m_aName, pFileName, (pFileType - pFileName));
+ rEntry.m_nMode = INETCOREFTP_FILEMODE_ISDIR;
+ }
+ else
+ {
+ setPath (rEntry.m_aName, pFileName, (p - pFileName));
+ rEntry.m_nMode = 0;
+ }
+
+ // Skip <version> part:
+ if (*p < '1' || *p > '9')
+ {
+ if (aFirstLineName.getLength())
+ continue;
+ else
+ return sal_False;
+ }
+ ++p;
+ while (*p >= '0' && *p <= '9')
+ ++p;
+
+ // Parse <1*lws> or <*lws <NEWLINE>> part:
+ sal_Bool bLWS = false;
+ while (*p == '\t' || *p == ' ')
+ {
+ bLWS = true;
+ ++p;
+ }
+ if (*p)
+ {
+ if (!bLWS)
+ {
+ if (aFirstLineName.getLength())
+ continue;
+ else
+ return sal_False;
+ }
+ }
+ else
+ {
+ /*
+ * First line of entry spanning two lines,
+ * wait for second line.
+ */
+ aFirstLineName = rEntry.m_aName;
+ bFirstLineDir =
+ ((rEntry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) != 0);
+ return sal_False;
+ }
+ }
+ else
+ {
+ /*
+ * Second line of entry spanning two lines,
+ * restore entry's name and mode (ISDIR flag).
+ */
+ rEntry.m_aName = aFirstLineName;
+ rEntry.m_nMode = (bFirstLineDir ? INETCOREFTP_FILEMODE_ISDIR : 0);
+
+ // Skip <1*lws> part:
+ if (*p != '\t' && *p != ' ')
+ return sal_False;
+ ++p;
+ while (*p == '\t' || *p == ' ')
+ ++p;
+ }
+
+ // Parse <size> part and set entry's size:
+ if (*p < '0' || *p > '9')
+ return sal_False;
+ ULONG nSize = *p - '0';
+ if (*p++ != '0')
+ while (*p >= '0' && *p <= '9')
+ nSize = 10 * rEntry.m_nSize + (*p++ - '0');
+ rEntry.m_nSize = 512 * nSize;
+
+ // Skip <1*lws> part:
+ if (*p != '\t' && *p != ' ')
+ return sal_False;
+ ++p;
+ while (*p == '\t' || *p == ' ')
+ ++p;
+
+ // Parse <day "-"> part and set entry date's day:
+ sal_uInt16 nDay;
+ if (*p == '0')
+ {
+ ++p;
+ if (*p < '1' || *p > '9')
+ return sal_False;
+ nDay = *p++ - '0';
+ }
+ else if (*p == '1' || *p == '2')
+ {
+ nDay = *p++ - '0';
+ if (*p >= '0' && *p <= '9')
+ nDay = 10 * nDay + (*p++ - '0');
+ }
+ else if (*p == '3')
+ {
+ ++p;
+ nDay = (*p == '0' || *p == '1') ? 30 + (*p++ - '0') : 3;
+ }
+ else if (*p >= '4' && *p <= '9')
+ nDay = *p++ - '0';
+ else
+ return sal_False;
+
+ rEntry.m_aDate.SetDay(nDay);
+ if (*p++ != '-')
+ return sal_False;
+
+ // Parse <month "-"> part and set entry date's month:
+ sal_Char const * pMonth = p;
+ sal_Int32 const monthLen = 3;
+ for (int i = 0; i < monthLen; ++i)
+ {
+ if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')))
+ return sal_False;
+ ++p;
+ }
+ if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JAN")) == 0)
+ rEntry.m_aDate.SetMonth(1);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("FEB")) == 0)
+ rEntry.m_aDate.SetMonth(2);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("MAR")) == 0)
+ rEntry.m_aDate.SetMonth(3);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("APR")) == 0)
+ rEntry.m_aDate.SetMonth(4);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("MAY")) == 0)
+ rEntry.m_aDate.SetMonth(5);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JUN")) == 0)
+ rEntry.m_aDate.SetMonth(6);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JUL")) == 0)
+ rEntry.m_aDate.SetMonth(7);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("AUG")) == 0)
+ rEntry.m_aDate.SetMonth(8);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("SEP")) == 0)
+ rEntry.m_aDate.SetMonth(9);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("OCT")) == 0)
+ rEntry.m_aDate.SetMonth(10);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("NOV")) == 0)
+ rEntry.m_aDate.SetMonth(11);
+ else if (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("DEC")) == 0)
+ rEntry.m_aDate.SetMonth(12);
+ else
+ return sal_False;
+ if (*p++ != '-')
+ return sal_False;
+
+ // Parse <year> part and set entry date's year:
+ sal_uInt16 nYear = 0;
+ {for (int i = 0; i < 2; ++i)
+ {
+ if (*p < '0' || *p > '9')
+ return sal_False;
+ nYear = 10 * nYear + (*p++ - '0');
+ }}
+ if (*p >= '0' && *p <= '9')
+ {
+ nYear = 10 * nYear + (*p++ - '0');
+ if (*p < '0' || *p > '9')
+ return sal_False;
+ nYear = 10 * nYear + (*p++ - '0');
+ }
+ setYear (rEntry.m_aDate, nYear);
+
+ // Skip <1*lws> part:
+ if (*p != '\t' && *p != ' ')
+ return sal_False;
+ ++p;
+ while (*p == '\t' || *p == ' ')
+ ++p;
+
+ // Parse <hour ":"> part and set entry time's hour:
+ sal_uInt16 nHour;
+ if (*p == '0' || *p == '1')
+ {
+ nHour = *p++ - '0';
+ if (*p >= '0' && *p <= '9')
+ nHour = 10 * nHour + (*p++ - '0');
+ }
+ else if (*p == '2')
+ {
+ ++p;
+ nHour = (*p >= '0' && *p <= '3') ? 20 + (*p++ - '0') : 2;
+ }
+ else if (*p >= '3' && *p <= '9')
+ nHour = *p++ - '0';
+ else
+ return sal_False;
+
+ rEntry.m_aDate.SetHour(nHour);
+ if (*p++ != ':')
+ return sal_False;
+
+ /*
+ * Parse <minute> part and set entry time's minutes,
+ * seconds (0), and 1/100 seconds (0).
+ */
+ if (*p < '0' || *p > '5')
+ return sal_False;
+
+ sal_uInt16 nMinute = *p++ - '0';
+ if (*p < '0' || *p > '9')
+ return sal_False;
+
+ nMinute = 10 * nMinute + (*p++ - '0');
+ rEntry.m_aDate.SetMin(nMinute);
+ rEntry.m_aDate.SetSec(0);
+ rEntry.m_aDate.Set100Sec(0);
+
+ // Skip <rest> part:
+ if (*p && (*p != '\t' && *p != ' '))
+ return sal_False;
+
+ return sal_True;
+ }
+}
+
+/*
+ * parseUNIX
+ */
+sal_Bool FTPDirectoryParser::parseUNIX (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer)
+{
+ const sal_Char *p1, *p2;
+ p1 = p2 = pBuffer;
+
+ if (!((*p1 == '-') || (*p1 == 'd') || (*p1 == 'l')))
+ return sal_False;
+
+ // 1st column: FileMode.
+ if (*p1 == 'd')
+ rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISDIR;
+
+ if (*p1 == 'l')
+ rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISLINK;
+
+ // Skip to end of column and set rights by the way
+ while (*p1 && !ascii_isWhitespace(*p1)) {
+ if(*p1 == 'r')
+ rEntry.m_nMode |= INETCOREFTP_FILEMODE_READ;
+ else if(*p1 == 'w')
+ rEntry.m_nMode |= INETCOREFTP_FILEMODE_WRITE;
+ p1++;
+ }
+
+ /*
+ * Scan for the sequence of size and date fields:
+ * *LWS 1*DIGIT 1*LWS 3CHAR 1*LWS 1*2DIGIT 1*LWS
+ * (4DIGIT / (1*2DIGIT ":" 2DIGIT)) 1*LWS
+ */
+ enum Mode
+ {
+ FOUND_NONE, FOUND_SIZE, FOUND_MONTH, FOUND_DAY, FOUND_YEAR_TIME
+ };
+
+ const sal_Char *pDayStart = 0;
+ const sal_Char *pDayEnd = 0;
+ Mode eMode;
+ for (eMode = FOUND_NONE; *p1 && eMode != FOUND_YEAR_TIME; p1 = p2 + 1)
+ {
+ while (*p1 && ascii_isWhitespace(*p1))
+ ++p1;
+ p2 = p1;
+ while (*p2 && !ascii_isWhitespace(*p2))
+ ++p2;
+
+ switch (eMode)
+ {
+ case FOUND_NONE:
+ if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
+ eMode = FOUND_SIZE;
+ break;
+
+ case FOUND_SIZE:
+ if (parseUNIX_isMonthField (p1, p2, rEntry.m_aDate))
+ eMode = FOUND_MONTH;
+ else if (!parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
+ eMode = FOUND_NONE;
+ break;
+
+ case FOUND_MONTH:
+ if (parseUNIX_isDayField (p1, p2, rEntry.m_aDate))
+ {
+ pDayStart = p1;
+ pDayEnd = p2;
+ eMode = FOUND_DAY;
+ }
+ else if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
+ eMode = FOUND_SIZE;
+ else
+ eMode = FOUND_NONE;
+ break;
+
+ case FOUND_DAY:
+ if (parseUNIX_isYearTimeField (p1, p2, rEntry.m_aDate))
+ eMode = FOUND_YEAR_TIME;
+ else if (
+ parseUNIX_isSizeField (
+ pDayStart, pDayEnd, rEntry.m_nSize) &&
+ parseUNIX_isMonthField (
+ p1, p2, rEntry.m_aDate))
+ eMode = FOUND_MONTH;
+ else if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
+ eMode = FOUND_SIZE;
+ else
+ eMode = FOUND_NONE;
+ break;
+ case FOUND_YEAR_TIME:
+ break;
+ }
+ }
+
+ if (eMode == FOUND_YEAR_TIME)
+ {
+ // 9th column: FileName (rest of line).
+ while (*p1 && ascii_isWhitespace(*p1)) p1++;
+ setPath (rEntry.m_aName, p1);
+
+ // Done.
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*
+ * parseUNIX_isSizeField.
+ */
+sal_Bool FTPDirectoryParser::parseUNIX_isSizeField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ sal_uInt32 &rSize)
+{
+ if (!*pStart || !*pEnd || pStart == pEnd)
+ return sal_False;
+
+ rSize = 0;
+ if (*pStart >= '0' && *pStart <= '9')
+ {
+ for (; pStart < pEnd; ++pStart)
+ if ((*pStart >= '0') && (*pStart <= '9'))
+ rSize = 10 * rSize + (*pStart - '0');
+ else
+ return sal_False;
+ return sal_True;
+ }
+ else
+ {
+ /*
+ * For a combination of long group name and large file size,
+ * some FTPDs omit LWS between those two columns.
+ */
+ int nNonDigits = 0;
+ int nDigits = 0;
+
+ for (; pStart < pEnd; ++pStart)
+ if ((*pStart >= '1') && (*pStart <= '9'))
+ {
+ ++nDigits;
+ rSize = 10 * rSize + (*pStart - '0');
+ }
+ else if ((*pStart == '0') && nDigits)
+ {
+ ++nDigits;
+ rSize *= 10;
+ }
+ else if ((*pStart > ' ') && (sal::static_int_cast<sal_uInt8>(*pStart) <= '\x7F'))
+ {
+ nNonDigits += nDigits + 1;
+ nDigits = 0;
+ rSize = 0;
+ }
+ else
+ return sal_False;
+ return ((nNonDigits >= 9) && (nDigits >= 7));
+ }
+}
+
+/*
+ * parseUNIX_isMonthField.
+ */
+sal_Bool FTPDirectoryParser::parseUNIX_isMonthField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime &rDateTime)
+{
+ if (!*pStart || !*pEnd || pStart + 3 != pEnd)
+ return sal_False;
+
+ if ((pStart[0] == 'j' || pStart[0] == 'J') &&
+ (pStart[1] == 'a' || pStart[1] == 'A') &&
+ (pStart[2] == 'n' || pStart[2] == 'N') )
+ {
+ rDateTime.SetMonth(1);
+ return sal_True;
+ }
+ if ((pStart[0] == 'f' || pStart[0] == 'F') &&
+ (pStart[1] == 'e' || pStart[1] == 'E') &&
+ (pStart[2] == 'b' || pStart[2] == 'B') )
+ {
+ rDateTime.SetMonth(2);
+ return sal_True;
+ }
+ if ((pStart[0] == 'm' || pStart[0] == 'M') &&
+ (pStart[1] == 'a' || pStart[1] == 'A') &&
+ (pStart[2] == 'r' || pStart[2] == 'R') )
+ {
+ rDateTime.SetMonth(3);
+ return sal_True;
+ }
+ if ((pStart[0] == 'a' || pStart[0] == 'A') &&
+ (pStart[1] == 'p' || pStart[1] == 'P') &&
+ (pStart[2] == 'r' || pStart[2] == 'R') )
+ {
+ rDateTime.SetMonth(4);
+ return sal_True;
+ }
+ if ((pStart[0] == 'm' || pStart[0] == 'M') &&
+ (pStart[1] == 'a' || pStart[1] == 'A') &&
+ (pStart[2] == 'y' || pStart[2] == 'Y') )
+ {
+ rDateTime.SetMonth(5);
+ return sal_True;
+ }
+ if ((pStart[0] == 'j' || pStart[0] == 'J') &&
+ (pStart[1] == 'u' || pStart[1] == 'U') &&
+ (pStart[2] == 'n' || pStart[2] == 'N') )
+ {
+ rDateTime.SetMonth(6);
+ return sal_True;
+ }
+ if ((pStart[0] == 'j' || pStart[0] == 'J') &&
+ (pStart[1] == 'u' || pStart[1] == 'U') &&
+ (pStart[2] == 'l' || pStart[2] == 'L') )
+ {
+ rDateTime.SetMonth(7);
+ return sal_True;
+ }
+ if ((pStart[0] == 'a' || pStart[0] == 'A') &&
+ (pStart[1] == 'u' || pStart[1] == 'U') &&
+ (pStart[2] == 'g' || pStart[2] == 'G') )
+ {
+ rDateTime.SetMonth(8);
+ return sal_True;
+ }
+ if ((pStart[0] == 's' || pStart[0] == 'S') &&
+ (pStart[1] == 'e' || pStart[1] == 'E') &&
+ (pStart[2] == 'p' || pStart[2] == 'P') )
+ {
+ rDateTime.SetMonth(9);
+ return sal_True;
+ }
+ if ((pStart[0] == 'o' || pStart[0] == 'O') &&
+ (pStart[1] == 'c' || pStart[1] == 'C') &&
+ (pStart[2] == 't' || pStart[2] == 'T') )
+ {
+ rDateTime.SetMonth(10);
+ return sal_True;
+ }
+ if ((pStart[0] == 'n' || pStart[0] == 'N') &&
+ (pStart[1] == 'o' || pStart[1] == 'O') &&
+ (pStart[2] == 'v' || pStart[2] == 'V') )
+ {
+ rDateTime.SetMonth(11);
+ return sal_True;
+ }
+ if ((pStart[0] == 'd' || pStart[0] == 'D') &&
+ (pStart[1] == 'e' || pStart[1] == 'E') &&
+ (pStart[2] == 'c' || pStart[2] == 'C') )
+ {
+ rDateTime.SetMonth(12);
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*
+ * parseUNIX_isDayField.
+ */
+sal_Bool FTPDirectoryParser::parseUNIX_isDayField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime &rDateTime)
+{
+ if (!*pStart || !*pEnd || pStart == pEnd)
+ return sal_False;
+ if (*pStart < '0' || *pStart > '9')
+ return sal_False;
+
+ sal_uInt16 nDay = *pStart - '0';
+ if (pStart + 1 < pEnd)
+ {
+ if (pStart + 2 != pEnd || pStart[1] < '0' || pStart[1] > '9')
+ return sal_False;
+ nDay = 10 * nDay + (pStart[1] - '0');
+ }
+ if (!nDay || nDay > 31)
+ return sal_False;
+
+ rDateTime.SetDay(nDay);
+ return sal_True;
+}
+
+/*
+ * parseUNIX_isYearTimeField.
+ */
+sal_Bool FTPDirectoryParser::parseUNIX_isYearTimeField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime &rDateTime)
+{
+ if (!*pStart || !*pEnd || pStart == pEnd ||
+ *pStart < '0' || *pStart > '9')
+ return sal_False;
+
+ sal_uInt16 nNumber = *pStart - '0';
+ ++pStart;
+
+ if (pStart == pEnd)
+ return sal_False;
+ if (*pStart == ':')
+ return parseUNIX_isTime (pStart, pEnd, nNumber, rDateTime);
+ if (*pStart < '0' || *pStart > '9')
+ return sal_False;
+
+ nNumber = 10 * nNumber + (*pStart - '0');
+ ++pStart;
+
+ if (pStart == pEnd)
+ return sal_False;
+ if (*pStart == ':')
+ return parseUNIX_isTime (pStart, pEnd, nNumber, rDateTime);
+ if (*pStart < '0' || *pStart > '9')
+ return sal_False;
+
+ nNumber = 10 * nNumber + (*pStart - '0');
+ ++pStart;
+
+ if (pStart == pEnd || *pStart < '0' || *pStart > '9')
+ return sal_False;
+
+ nNumber = 10 * nNumber + (*pStart - '0');
+ if (pStart + 1 != pEnd || nNumber < 1970)
+ return sal_False;
+
+ rDateTime.SetYear(nNumber);
+ rDateTime.SetTime(0);
+ return sal_True;
+}
+
+/*
+ * parseUNIX_isTime.
+ */
+sal_Bool FTPDirectoryParser::parseUNIX_isTime (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ sal_uInt16 nHour,
+ DateTime &rDateTime)
+{
+ if ((nHour > 23 ) || (pStart + 3 != pEnd) ||
+ (pStart[1] < '0') || (pStart[1] > '5') ||
+ (pStart[2] < '0') || (pStart[2] > '9') )
+ return sal_False;
+
+ sal_uInt16 nMin = 10 * (pStart[1] - '0') + (pStart[2] - '0');
+
+ rDateTime.SetHour (nHour);
+ rDateTime.SetMin (nMin);
+ rDateTime.SetSec (0);
+ rDateTime.Set100Sec (0);
+
+// Date aCurDate;
+// if (rDateTime.GetMonth() > aCurDate.GetMonth())
+// rDateTime.SetYear(aCurDate.GetYear() - 1);
+// else
+// rDateTime.SetYear(aCurDate.GetYear());
+// return sal_True;
+
+ TimeValue aTimeVal;
+ osl_getSystemTime(&aTimeVal);
+ oslDateTime aCurrDateTime;
+ osl_getDateTimeFromTimeValue(&aTimeVal,&aCurrDateTime);
+
+ if (rDateTime.GetMonth() > aCurrDateTime.Month)
+ rDateTime.SetYear(aCurrDateTime.Year - 1);
+ else
+ rDateTime.SetYear(aCurrDateTime.Year);
+ return sal_True;
+}
+
+/*
+ * setYear.
+ *
+ * Two-digit years are taken as within 50 years back and 49 years forward
+ * (both ends inclusive) from the current year. The returned date is not
+ * checked for validity of the given day in the given month and year.
+ *
+ */
+sal_Bool FTPDirectoryParser::setYear (
+ DateTime &rDateTime, sal_uInt16 nYear)
+{
+ if (nYear < 100)
+ {
+ TimeValue aTimeVal;
+ osl_getSystemTime(&aTimeVal);
+ oslDateTime aCurrDateTime;
+ osl_getDateTimeFromTimeValue(&aTimeVal,&aCurrDateTime);
+ sal_uInt16 nCurrentYear = aCurrDateTime.Year;
+// sal_uInt16 nCurrentYear = Date().GetYear();
+ sal_uInt16 nCurrentCentury = nCurrentYear / 100;
+ nCurrentYear %= 100;
+ if (nCurrentYear < 50)
+ if (nYear <= nCurrentYear)
+ nYear += nCurrentCentury * 100;
+ else if (nYear < nCurrentYear + 50)
+ nYear += nCurrentCentury * 100;
+ else
+ nYear += (nCurrentCentury - 1) * 100;
+ else
+ if (nYear >= nCurrentYear)
+ nYear += nCurrentCentury * 100;
+ else if (nYear >= nCurrentYear - 50)
+ nYear += nCurrentCentury * 100;
+ else
+ nYear += (nCurrentCentury + 1) * 100;
+ }
+
+ rDateTime.SetYear(nYear);
+ return sal_True;
+}
+
+/*
+ * setPath.
+ */
+sal_Bool FTPDirectoryParser::setPath (
+ OUString &rPath, const sal_Char *value, sal_Int32 length)
+{
+ if (value)
+ {
+ if (length < 0)
+ length = rtl_str_getLength (value);
+ rPath = OUString (value, length, RTL_TEXTENCODING_UTF8);
+ }
+ return (!!value);
+}
diff --git a/ucb/source/ucp/ftp/ftpdirp.hxx b/ucb/source/ucp/ftp/ftpdirp.hxx
new file mode 100644
index 000000000000..aeb265dbf286
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpdirp.hxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _FTP_FTPDIRP_HXX_
+#define _FTP_FTPDIRP_HXX_
+
+#include <osl/time.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+
+
+namespace ftp {
+
+ /*========================================================================
+ *
+ * the DateTime structure
+ *
+ *======================================================================*/
+
+ struct DateTime
+ : public com::sun::star::util::DateTime
+ {
+ DateTime(const sal_uInt16& hundredthSeconds,
+ const sal_uInt16& seconds,
+ const sal_uInt16& minutes,
+ const sal_uInt16& hours,
+ const sal_uInt16& day,
+ const sal_uInt16& month,
+ const sal_uInt16& year) SAL_THROW( () )
+ : com::sun::star::util::DateTime(hundredthSeconds,
+ seconds,
+ minutes,
+ hours,
+ day,
+ month,
+ year) { }
+
+ void SetYear(sal_uInt16 year) { Year = year; }
+ void SetMonth(sal_uInt16 month) { Month = month; }
+ void SetDay(sal_uInt16 day) { Day = day; }
+ // Only zero allowed and used for time-argument
+ void SetTime(sal_uInt16) { Hours = Minutes = Seconds = HundredthSeconds = 0; }
+ void SetHour(sal_uInt16 hours) { Hours = hours; }
+ void SetMin(sal_uInt16 minutes) { Minutes = minutes; }
+ void SetSec(sal_uInt16 seconds) { Seconds = seconds; }
+ void Set100Sec(sal_uInt16 hundredthSec) { HundredthSeconds = hundredthSec; }
+
+ sal_uInt16 GetMonth(void) { return Month; }
+ };
+
+
+
+/*========================================================================
+ *
+ * the directory information structure
+ *
+ *======================================================================*/
+
+ enum FTPDirentryMode { INETCOREFTP_FILEMODE_UNKNOWN = 0x00,
+ INETCOREFTP_FILEMODE_READ = 0x01,
+ INETCOREFTP_FILEMODE_WRITE = 0x02,
+ INETCOREFTP_FILEMODE_ISDIR = 0x04,
+ INETCOREFTP_FILEMODE_ISLINK = 0x08 };
+
+ struct FTPDirentry
+ {
+ rtl::OUString m_aURL;
+ rtl::OUString m_aName;
+ DateTime m_aDate;
+ sal_uInt32 m_nMode;
+ sal_uInt32 m_nSize;
+
+ FTPDirentry(void)
+ : m_aDate(0,0,0,0,0,0,0),
+ m_nMode(INETCOREFTP_FILEMODE_UNKNOWN),
+ m_nSize((sal_uInt32)(-1)) { }
+
+ void clear() {
+ m_aURL = m_aName = rtl::OUString();
+ m_aDate = DateTime(0,0,0,0,0,0,0);
+ m_nMode = INETCOREFTP_FILEMODE_UNKNOWN;
+ m_nSize = sal_uInt32(-1);
+ }
+
+ bool isDir() const {
+ return bool(m_nMode && INETCOREFTP_FILEMODE_ISDIR);
+ }
+
+ bool isFile() const {
+ return ! bool(m_nMode && INETCOREFTP_FILEMODE_ISDIR);
+ }
+ };
+
+
+/*========================================================================
+ *
+ * the directory parser
+ *
+ *======================================================================*/
+
+
+ class FTPDirectoryParser
+ {
+ public:
+ static sal_Bool parseDOS (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer );
+
+ static sal_Bool parseVMS (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer );
+
+ static sal_Bool parseUNIX (
+ FTPDirentry &rEntry,
+ const sal_Char *pBuffer );
+
+
+ private:
+
+ static sal_Bool parseUNIX_isSizeField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ sal_uInt32 &rSize);
+
+ static sal_Bool parseUNIX_isMonthField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime& rDateTime);
+
+ static sal_Bool parseUNIX_isDayField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime& rDateTime);
+
+ static sal_Bool parseUNIX_isYearTimeField (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ DateTime& rDateTime);
+
+ static sal_Bool parseUNIX_isTime (
+ const sal_Char *pStart,
+ const sal_Char *pEnd,
+ sal_uInt16 nHour,
+ DateTime& rDateTime);
+
+ static sal_Bool setYear (
+ DateTime& rDateTime,
+ sal_uInt16 nYear);
+
+ static sal_Bool setPath (
+ rtl::OUString& rPath,
+ const sal_Char *value,
+ sal_Int32 length = -1);
+ };
+
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpdynresultset.cxx b/ucb/source/ucp/ftp/ftpdynresultset.cxx
new file mode 100644
index 000000000000..93f274f1ac5f
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpdynresultset.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#ifndef _FTP_FTPDYNRESULTSET_HXX_
+#include "ftpdynresultset.hxx"
+#endif
+#include "ftpresultsetfactory.hxx"
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+
+using namespace ftp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< FTPContent >& rxContent,
+ const OpenCommandArgument2& rCommand,
+ const Reference< XCommandEnvironment >& rxEnv,
+ ResultSetFactory* pFactory )
+ : ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv ),
+ m_pFactory( pFactory )
+{
+}
+
+DynamicResultSet::~DynamicResultSet()
+{
+ delete m_pFactory;
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() );
+
+ m_xResultSet2 = m_xResultSet1;
+}
+
+
+
+
diff --git a/ucb/source/ucp/ftp/ftpdynresultset.hxx b/ucb/source/ucp/ftp/ftpdynresultset.hxx
new file mode 100644
index 000000000000..b1e92c15750a
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpdynresultset.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FTP_FTPDYNRESULTSET_HXX
+#define _FTP_FTPDYNRESULTSET_HXX
+
+#include "rtl/ref.hxx"
+#include "ucbhelper/resultsethelper.hxx"
+
+#include "ftpcontent.hxx"
+
+namespace ftp {
+
+ class ResultSetFactory;
+
+ class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+ {
+ rtl::Reference< FTPContent > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+ ResultSetFactory* m_pFactory;
+
+ private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+ public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< FTPContent >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv,
+ ResultSetFactory* pFactory );
+
+ ~DynamicResultSet();
+ };
+
+}
+
+#endif
+
diff --git a/ucb/source/ucp/ftp/ftphandleprovider.hxx b/ucb/source/ucp/ftp/ftphandleprovider.hxx
new file mode 100755
index 000000000000..1510f48e41a6
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftphandleprovider.hxx
@@ -0,0 +1,29 @@
+#include <rtl/ustring.hxx>
+#include "curl.hxx"
+
+namespace ftp {
+
+ class FTPHandleProvider {
+ public:
+
+ virtual CURL* handle() = 0;
+
+
+ /** host is in the form host:port.
+ */
+
+ virtual bool forHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ rtl::OUString& password,
+ rtl::OUString& account) = 0;
+
+ virtual bool setHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ const rtl::OUString& password,
+ const rtl::OUString& account) = 0;
+ };
+
+
+}
diff --git a/ucb/source/ucp/ftp/ftpinpstr.cxx b/ucb/source/ucp/ftp/ftpinpstr.cxx
new file mode 100644
index 000000000000..5fe5c829f976
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpinpstr.cxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include "ftpinpstr.hxx"
+#ifndef _RTL_ALLOC_H
+#include <rtl/alloc.h>
+#endif
+#ifndef STD_ALGORITHM
+#include <algorithm>
+#define STD_ALGORITHM
+#endif
+#include <stdio.h>
+
+using namespace ftp;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::io;
+
+
+FTPInputStream::FTPInputStream(FILE* tmpfl)
+ : m_tmpfl(tmpfl ? tmpfl : tmpfile())
+{
+ fseek(m_tmpfl,0,SEEK_END);
+// fpos_t pos;
+// fgetpos(m_tmpfl,&pos);
+ long pos = ftell(m_tmpfl);
+ rewind(m_tmpfl);
+ m_nLength = sal_Int64(pos);
+}
+
+
+
+FTPInputStream::~FTPInputStream()
+{
+ if ( 0 != m_tmpfl)
+ fclose(m_tmpfl);
+}
+
+
+Any SAL_CALL FTPInputStream::queryInterface(
+ const Type& rType
+)
+ throw(
+ RuntimeException
+ )
+{
+ Any aRet = ::cppu::queryInterface(rType,
+ SAL_STATIC_CAST( XInputStream*,this ),
+ SAL_STATIC_CAST( XSeekable*,this ) );
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+
+void SAL_CALL FTPInputStream::acquire( void ) throw() {
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL FTPInputStream::release( void ) throw() {
+ OWeakObject::release();
+}
+
+
+sal_Int32 SAL_CALL FTPInputStream::readBytes(Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead)
+ throw(NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ if(0 <= nBytesToRead && aData.getLength() < nBytesToRead)
+ aData.realloc(nBytesToRead);
+
+// fpos_t bpos,epos;
+
+// fgetpos(m_tmpfl,&bpos);
+// fread(aData.getArray(),nBytesToRead,1,m_tmpfl);
+// fgetpos(m_tmpfl,&epos);
+ long bpos,epos;
+
+ bpos = ftell(m_tmpfl);
+ if (fread(aData.getArray(),nBytesToRead,1,m_tmpfl) != 1)
+ throw IOException();
+
+ epos = ftell(m_tmpfl);
+
+ return sal_Int32(epos-bpos);
+}
+
+
+sal_Int32 SAL_CALL FTPInputStream::readSomeBytes( Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException)
+{
+ return readBytes(aData,nMaxBytesToRead);
+}
+
+
+
+void SAL_CALL FTPInputStream::skipBytes(sal_Int32 nBytesToSkip)
+ throw(NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_tmpfl)
+ throw IOException();
+
+ fseek(m_tmpfl,long(nBytesToSkip),SEEK_CUR);
+}
+
+
+
+sal_Int32 SAL_CALL FTPInputStream::available(void)
+ throw(NotConnectedException,
+ IOException,
+ RuntimeException)
+{
+ return sal::static_int_cast<sal_Int32>(m_nLength - getPosition());
+}
+
+
+
+void SAL_CALL FTPInputStream::closeInput(void)
+ throw(NotConnectedException,
+ IOException,
+ RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ if(m_tmpfl)
+ fclose(m_tmpfl),m_tmpfl = 0;
+}
+
+
+
+void SAL_CALL FTPInputStream::seek(sal_Int64 location)
+ throw( IllegalArgumentException,
+ IOException,
+ RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_tmpfl)
+ throw IOException();
+
+ fseek(m_tmpfl,long(location),SEEK_SET);
+}
+
+
+
+sal_Int64 SAL_CALL
+FTPInputStream::getPosition(
+ void )
+ throw( IOException,
+ RuntimeException )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ if(!m_tmpfl)
+ throw IOException();
+
+// fpos_t pos;
+// fgetpos(m_tmpfl,&pos);
+ long pos;
+ pos = ftell(m_tmpfl);
+ return sal_Int64(pos);
+}
+
+
+
+sal_Int64 SAL_CALL FTPInputStream::getLength(
+ void
+) throw(
+ IOException,RuntimeException
+)
+{
+ return m_nLength;
+}
diff --git a/ucb/source/ucp/ftp/ftpinpstr.hxx b/ucb/source/ucp/ftp/ftpinpstr.hxx
new file mode 100644
index 000000000000..0d235be36e35
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpinpstr.hxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#ifndef _FTP_FTPINPSTR_HXX_
+#define _FTP_FTPINPSTR_HXX_
+
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <stdio.h>
+
+
+namespace ftp {
+
+
+ /** Implements a seekable InputStream
+ * working on a buffer.
+ */
+
+
+ namespace css = com::sun::star;
+
+
+ class FTPInputStream
+ : public cppu::OWeakObject,
+ public com::sun::star::io::XInputStream,
+ public com::sun::star::io::XSeekable
+ {
+ public:
+
+ /** Defines the storage kind found
+ * on which the inputstream acts.
+ */
+
+ FTPInputStream(FILE* tmpfl = 0);
+
+ ~FTPInputStream();
+
+ virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& rType)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire(void) throw();
+
+ virtual void SAL_CALL release(void) throw();
+
+ virtual sal_Int32 SAL_CALL
+ readBytes(css::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead)
+ throw( css::io::NotConnectedException,
+ css::io::BufferSizeExceededException,
+ css::io::IOException,
+ css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ readSomeBytes(css::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( css::io::NotConnectedException,
+ css::io::BufferSizeExceededException,
+ css::io::IOException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ skipBytes(sal_Int32 nBytesToSkip)
+ throw(css::io::NotConnectedException,
+ css::io::BufferSizeExceededException,
+ css::io::IOException,
+ css::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ available(void)
+ throw(css::io::NotConnectedException,
+ css::io::IOException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeInput(void)
+ throw(css::io::NotConnectedException,
+ css::io::IOException,
+ css::uno::RuntimeException);
+
+
+ /** XSeekable
+ */
+
+ virtual void SAL_CALL
+ seek(sal_Int64 location)
+ throw(css::lang::IllegalArgumentException,
+ css::io::IOException,
+ css::uno::RuntimeException);
+
+
+ virtual sal_Int64 SAL_CALL
+ getPosition(void)
+ throw(css::io::IOException,
+ css::uno::RuntimeException);
+
+
+ virtual sal_Int64 SAL_CALL
+ getLength(void)
+ throw(css::io::IOException,
+ css::uno::RuntimeException);
+
+ // additional
+
+// void append(const void* pBuffer,size_t size,size_t nmemb);
+
+ private:
+
+ osl::Mutex m_aMutex;
+ FILE* m_tmpfl;
+ sal_Int64 m_nLength;
+ };
+
+
+}
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpintreq.cxx b/ucb/source/ucp/ftp/ftpintreq.cxx
new file mode 100644
index 000000000000..2ee076d1e246
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpintreq.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include "ftpintreq.hxx"
+
+using namespace cppu;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::task;
+using namespace ftp;
+
+
+XInteractionApproveImpl::XInteractionApproveImpl()
+ : m_bSelected(false)
+{
+}
+
+
+void SAL_CALL
+XInteractionApproveImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XInteractionApproveImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionApproveImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionApprove*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionApproveImpl,
+ XTypeProvider,
+ XInteractionApprove )
+
+
+void SAL_CALL XInteractionApproveImpl::select()
+ throw (RuntimeException)
+{
+ m_bSelected = true;
+}
+
+
+bool XInteractionApproveImpl::isSelected() const
+{
+ return m_bSelected;
+}
+
+
+// XInteractionDisapproveImpl
+
+XInteractionDisapproveImpl::XInteractionDisapproveImpl()
+ : m_bSelected(false)
+{
+}
+
+
+void SAL_CALL
+XInteractionDisapproveImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+XInteractionDisapproveImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionDisapproveImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionDisapprove*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+//////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionDisapproveImpl,
+ XTypeProvider,
+ XInteractionDisapprove )
+
+
+void SAL_CALL XInteractionDisapproveImpl::select()
+ throw (RuntimeException)
+
+{
+ m_bSelected = true;
+}
+
+
+// XInteractionRequestImpl
+
+XInteractionRequestImpl::XInteractionRequestImpl(const rtl::OUString& aName)
+ : p1( new XInteractionApproveImpl ),
+ p2( new XInteractionDisapproveImpl ),
+ m_aName(aName),
+ m_aSeq( 2 )
+{
+ m_aSeq[0] = Reference<XInteractionContinuation>(p1);
+ m_aSeq[1] = Reference<XInteractionContinuation>(p2);
+}
+
+
+void SAL_CALL
+XInteractionRequestImpl::acquire( void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL
+XInteractionRequestImpl::release( void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+Any SAL_CALL
+XInteractionRequestImpl::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XTypeProvider*, this ),
+ SAL_STATIC_CAST( XInteractionRequest*,this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// XTypeProvider
+/////////////////////////////////////////////////////////////////////////////
+
+XTYPEPROVIDER_IMPL_2( XInteractionRequestImpl,
+ XTypeProvider,
+ XInteractionRequest )
+
+
+Any SAL_CALL XInteractionRequestImpl::getRequest( )
+ throw (RuntimeException)
+{
+ Any aAny;
+ UnsupportedNameClashException excep;
+ excep.NameClash = NameClash::ERROR;
+ aAny <<= excep;
+ return aAny;
+}
+
+
+Sequence<Reference<XInteractionContinuation > > SAL_CALL
+XInteractionRequestImpl::getContinuations( )
+ throw (RuntimeException)
+{
+ return m_aSeq;
+}
+
+
+bool XInteractionRequestImpl::approved() const
+{
+ return p1->isSelected();
+}
+
diff --git a/ucb/source/ucp/ftp/ftpintreq.hxx b/ucb/source/ucp/ftp/ftpintreq.hxx
new file mode 100644
index 000000000000..1a772dc356e1
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpintreq.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FTP_FTPINTREQ_HXX
+#define _FTP_FTPINTREQ_HXX
+
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/task/XInteractionDisapprove.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+
+
+namespace ftp {
+
+
+ class XInteractionApproveImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::task::XInteractionApprove
+ {
+ public:
+
+ XInteractionApproveImpl();
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ virtual void SAL_CALL select()
+ throw (com::sun::star::uno::RuntimeException);
+
+ bool isSelected() const;
+
+ private:
+
+ bool m_bSelected;
+ };
+
+
+
+
+ class XInteractionDisapproveImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::task::XInteractionDisapprove
+ {
+ public:
+
+ XInteractionDisapproveImpl();
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ virtual void SAL_CALL select()
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+
+ bool m_bSelected;
+ };
+
+
+
+ class XInteractionRequestImpl
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::task::XInteractionRequest
+ {
+ public:
+
+ XInteractionRequestImpl(const rtl::OUString& aName);
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+
+ // XTypeProvider
+
+ XTYPEPROVIDER_DECL()
+
+ com::sun::star::uno::Any SAL_CALL
+ getRequest( )
+ throw (com::sun::star::uno::RuntimeException);
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > SAL_CALL
+ getContinuations( )
+ throw (com::sun::star::uno::RuntimeException);
+
+ bool approved() const;
+
+ private:
+
+ XInteractionApproveImpl* p1;
+ XInteractionDisapproveImpl* p2;
+
+ rtl::OUString m_aName;
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > m_aSeq;
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftploaderthread.cxx b/ucb/source/ucp/ftp/ftploaderthread.cxx
new file mode 100644
index 000000000000..727d056f7fe8
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftploaderthread.cxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include "ftploaderthread.hxx"
+#include "curl.hxx"
+
+using namespace ftp;
+
+
+/********************************************************************************/
+/* */
+/* cleanup function for thread specific data */
+/* */
+/********************************************************************************/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ int memory_write_dummy(void *,size_t,size_t,void *)
+ {
+ return 0;
+ }
+
+ void delete_CURL(void *pData)
+ {
+ // Otherwise response for QUIT will be sent to already destroyed
+ // MemoryContainer via non-dummy memory_write function.
+ curl_easy_setopt(static_cast<CURL*>(pData),
+ CURLOPT_HEADERFUNCTION,
+ memory_write_dummy);
+ curl_easy_cleanup(static_cast<CURL*>(pData));
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/********************************************************************************/
+/* */
+/* Member part of FTPLoaderThread */
+/* */
+/********************************************************************************/
+
+
+FTPLoaderThread::FTPLoaderThread()
+ : m_threadKey(osl_createThreadKey(delete_CURL)) {
+}
+
+
+
+FTPLoaderThread::~FTPLoaderThread() {
+ osl_destroyThreadKey(m_threadKey);
+}
+
+
+
+CURL* FTPLoaderThread::handle() {
+ CURL* ret = osl_getThreadKeyData(m_threadKey);
+ if(!ret) {
+ ret = curl_easy_init();
+ if (ret != 0) {
+ // Make sure curl is not internally using environment variables like
+ // "ftp_proxy":
+ if (curl_easy_setopt(ret, CURLOPT_PROXY, "") != CURLE_OK) {
+ curl_easy_cleanup(ret);
+ ret = 0;
+ }
+ }
+ osl_setThreadKeyData(m_threadKey,static_cast<void*>(ret));
+ }
+
+ return ret;
+}
+
+
diff --git a/ucb/source/ucp/ftp/ftploaderthread.hxx b/ucb/source/ucp/ftp/ftploaderthread.hxx
new file mode 100644
index 000000000000..1b91a0885048
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftploaderthread.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#ifndef _FTP_FTPLOADERTHREAD_HXX_
+#define _FTP_FTPLOADERTHREAD_HXX_
+
+#include <osl/thread.h>
+#include "curl.hxx"
+
+namespace ftp {
+
+ /** A loaderthread acts as factory for CURL-handles,
+ * the key being ( implicit ) the threadid.
+ * Owner is a FTPContentProvider-instance
+ */
+
+ class FTPLoaderThread
+ {
+ public:
+
+ FTPLoaderThread();
+ ~FTPLoaderThread();
+
+ CURL* handle();
+
+
+ private:
+
+ /** Don't enable assignment and copy construction.
+ * Not defined:
+ */
+
+ FTPLoaderThread(const FTPLoaderThread&);
+ FTPLoaderThread& operator=(const FTPLoaderThread&);
+
+ oslThreadKey m_threadKey;
+
+ }; // end class FTPLoaderThread
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpresultsetI.cxx b/ucb/source/ucp/ftp/ftpresultsetI.cxx
new file mode 100644
index 000000000000..49976755f60c
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpresultsetI.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "ucbhelper/propertyvalueset.hxx"
+#include "rtl/ref.hxx"
+#include "com/sun/star/ucb/Command.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/ucb/XCommandProcessor.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "ftpresultsetI.hxx"
+#include "ftpcontent.hxx"
+
+
+using namespace std;
+using namespace ftp;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::sdbc;
+
+
+ResultSetI::ResultSetI(const Reference<XMultiServiceFactory>& xMSF,
+ const Reference<XContentProvider>& xProvider,
+ sal_Int32 nOpenMode,
+ const Sequence<Property>& seqProp,
+ const Sequence< NumberedSortingInfo >& seqSort,
+ const std::vector<FTPDirentry>& dirvec)
+ : ResultSetBase(xMSF,xProvider,nOpenMode,seqProp,seqSort)
+{
+ for( unsigned int i = 0; i < dirvec.size(); ++i)
+ m_aPath.push_back(dirvec[i].m_aURL);
+
+ // m_aIdents holds the contentidentifiers
+
+ m_aItems.resize( m_aPath.size() );
+ m_aIdents.resize( m_aPath.size() );
+
+ for(unsigned n = 0; n < m_aItems.size(); ++n) {
+ rtl::Reference<ucbhelper::PropertyValueSet> xRow =
+ new ucbhelper::PropertyValueSet(xMSF);
+
+ for( int i = 0; i < seqProp.getLength(); ++i) {
+ const rtl::OUString& Name = seqProp[i].Name;
+ if(Name.compareToAscii("ContentType") == 0 )
+ xRow->appendString(seqProp[i],
+ rtl::OUString::createFromAscii(
+ "application/ftp" ));
+ else if(Name.compareToAscii("Title") == 0)
+ xRow->appendString(seqProp[i],dirvec[n].m_aName);
+ else if(Name.compareToAscii("IsReadOnly") == 0)
+ xRow->appendBoolean(seqProp[i],
+ sal_Bool(dirvec[n].m_nMode &
+ INETCOREFTP_FILEMODE_WRITE));
+ else if(Name.compareToAscii("IsDocument") == 0)
+ xRow->appendBoolean(seqProp[i],
+ ! sal_Bool(dirvec[n].m_nMode &
+ INETCOREFTP_FILEMODE_ISDIR));
+ else if(Name.compareToAscii("IsFolder") == 0)
+ xRow->appendBoolean(seqProp[i],
+ sal_Bool(dirvec[n].m_nMode &
+ INETCOREFTP_FILEMODE_ISDIR));
+ else if(Name.compareToAscii("Size") == 0)
+ xRow->appendLong(seqProp[i],
+ dirvec[n].m_nSize);
+ else if(Name.compareToAscii("DateCreated") == 0)
+ xRow->appendTimestamp(seqProp[i],
+ dirvec[n].m_aDate);
+ else if(Name.compareToAscii("CreatableContentsInfo") == 0)
+ xRow->appendObject(
+ seqProp[i],
+ makeAny(FTPContent::queryCreatableContentsInfo_Static()));
+ else
+ xRow->appendVoid(seqProp[i]);
+ }
+ m_aItems[n] = Reference<XRow>(xRow.get());
+ }
+}
diff --git a/ucb/source/ucp/ftp/ftpresultsetI.hxx b/ucb/source/ucp/ftp/ftpresultsetI.hxx
new file mode 100644
index 000000000000..ded6613abdcc
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpresultsetI.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FTP_FTPRESULTSETI_HXX_
+#define _FTP_FTPRESULTSETI_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include "ftpresultsetbase.hxx"
+#include "ftpdirp.hxx"
+
+
+namespace ftp {
+
+ class ResultSetI
+ : public ResultSetBase
+ {
+ public:
+
+ ResultSetI(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory>& xMSF,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider>& xProvider,
+ sal_Int32 nOpenMode,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property >& seq,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::ucb::NumberedSortingInfo >& seqSort,
+ const std::vector<FTPDirentry>& dirvec);
+
+ private:
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpresultsetbase.cxx b/ucb/source/ucp/ftp/ftpresultsetbase.cxx
new file mode 100644
index 000000000000..c83a34e251e8
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpresultsetbase.cxx
@@ -0,0 +1,662 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <ucbhelper/contentidentifier.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/uno/Reference.h>
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/XSourceInitialization.hpp>
+#include <ucbhelper/resultsetmetadata.hxx>
+#include "ftpresultsetbase.hxx"
+
+using namespace ftp;
+using namespace com::sun::star;
+
+ResultSetBase::ResultSetBase(
+ const uno::Reference< lang::XMultiServiceFactory >& xMSF,
+ const uno::Reference< ucb::XContentProvider >& xProvider,
+ sal_Int32 nOpenMode,
+ const uno::Sequence< beans::Property >& seq,
+ const uno::Sequence< ucb::NumberedSortingInfo >& seqSort )
+ : m_xMSF( xMSF ),
+ m_xProvider( xProvider ),
+ m_nRow( -1 ),
+ m_nWasNull( true ),
+ m_nOpenMode( nOpenMode ),
+ m_bRowCountFinal( true ),
+ m_sProperty( seq ),
+ m_sSortingInfo( seqSort ),
+ m_pDisposeEventListeners( 0 ),
+ m_pRowCountListeners( 0 ),
+ m_pIsFinalListeners( 0 )
+{
+}
+
+ResultSetBase::~ResultSetBase()
+{
+ delete m_pIsFinalListeners;
+ delete m_pRowCountListeners;
+ delete m_pDisposeEventListeners;
+}
+
+
+// XInterface
+
+void SAL_CALL
+ResultSetBase::acquire(
+ void )
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL
+ResultSetBase::release(
+ void )
+ throw()
+{
+ OWeakObject::release();
+}
+
+
+
+uno::Any SAL_CALL
+ResultSetBase::queryInterface(
+ const uno::Type& rType )
+ throw( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( lang::XComponent*, this),
+ SAL_STATIC_CAST( sdbc::XRow*, this),
+ SAL_STATIC_CAST( sdbc::XResultSet*, this),
+ SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this),
+ SAL_STATIC_CAST( beans::XPropertySet*, this ),
+ SAL_STATIC_CAST( ucb::XContentAccess*, this) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+
+// XComponent
+
+
+void SAL_CALL
+ResultSetBase::addEventListener(
+ const uno::Reference< lang::XEventListener >& Listener )
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ! m_pDisposeEventListeners )
+ m_pDisposeEventListeners =
+ new cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+
+void SAL_CALL
+ResultSetBase::removeEventListener(
+ const uno::Reference< lang::XEventListener >& Listener )
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+
+
+void SAL_CALL
+ResultSetBase::dispose()
+ throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ lang::EventObject aEvt;
+ aEvt.Source = static_cast< lang::XComponent * >( this );
+
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+ if( m_pRowCountListeners && m_pRowCountListeners->getLength() )
+ {
+ m_pRowCountListeners->disposeAndClear( aEvt );
+ }
+ if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() )
+ {
+ m_pIsFinalListeners->disposeAndClear( aEvt );
+ }
+}
+
+
+
+// XResultSet
+
+sal_Bool SAL_CALL
+ResultSetBase::next(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ sal_Bool test;
+ if( ++m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ test = true;
+ else
+ test = false;
+ return test;
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::isBeforeFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow == -1;
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::isAfterLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()); // Cannot happen, if m_aFolder.isOpen()
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::isFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return m_nRow == 0;
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::isLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( m_nRow == sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1 )
+ return true;
+ else
+ return false;
+}
+
+
+void SAL_CALL
+ResultSetBase::beforeFirst(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ m_nRow = -1;
+}
+
+
+void SAL_CALL
+ResultSetBase::afterLast(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ m_nRow = m_aItems.size();
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::first(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ m_nRow = -1;
+ return next();
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::last(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ m_nRow = m_aItems.size() - 1;
+ return true;
+}
+
+
+sal_Int32 SAL_CALL
+ResultSetBase::getRow(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ // Test, whether behind last row
+ if( -1 == m_nRow || m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return 0;
+ else
+ return m_nRow+1;
+}
+
+
+sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row )
+ throw( sdbc::SQLException, uno::RuntimeException)
+{
+ if( row >= 0 )
+ m_nRow = row - 1;
+ else
+ {
+ last();
+ m_nRow += ( row + 1 );
+ if( m_nRow < -1 )
+ m_nRow = -1;
+ }
+
+ return 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+
+
+sal_Bool SAL_CALL
+ResultSetBase::relative(
+ sal_Int32 row )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( isAfterLast() || isBeforeFirst() )
+ throw sdbc::SQLException();
+
+ if( row > 0 )
+ while( row-- )
+ next();
+ else if( row < 0 )
+ while( row++ && m_nRow > - 1 )
+ previous();
+
+ return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+
+sal_Bool SAL_CALL
+ResultSetBase::previous(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+ if( m_nRow > sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ m_nRow = m_aItems.size(); // Correct Handling of afterLast
+ if( 0 <= m_nRow ) -- m_nRow;
+
+ return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
+}
+
+
+void SAL_CALL
+ResultSetBase::refreshRow(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+}
+
+
+sal_Bool SAL_CALL
+ResultSetBase::rowUpdated(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+sal_Bool SAL_CALL
+ResultSetBase::rowInserted(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+sal_Bool SAL_CALL
+ResultSetBase::rowDeleted(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ return false;
+}
+
+
+uno::Reference< uno::XInterface > SAL_CALL
+ResultSetBase::getStatement(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ uno::Reference< uno::XInterface > test( 0 );
+ return test;
+}
+
+
+// XCloseable
+
+void SAL_CALL
+ResultSetBase::close(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException)
+{
+}
+
+
+rtl::OUString SAL_CALL
+ResultSetBase::queryContentIdentifierString(
+ void )
+ throw( uno::RuntimeException )
+{
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aPath[m_nRow];
+ else
+ return rtl::OUString();
+}
+
+
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+ResultSetBase::queryContentIdentifier(
+ void
+)
+ throw(
+ uno::RuntimeException
+ )
+{
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ {
+ if(!m_aIdents[m_nRow].is()) {
+ rtl::OUString url = queryContentIdentifierString();
+ if(url.getLength() )
+ m_aIdents[m_nRow] =
+ uno::Reference< ucb::XContentIdentifier >(
+ new ::ucbhelper::ContentIdentifier(m_xMSF,url) );
+ }
+ return m_aIdents[m_nRow];
+ }
+
+ return uno::Reference<ucb::XContentIdentifier>();
+}
+
+
+uno::Reference< ucb::XContent > SAL_CALL
+ResultSetBase::queryContent(
+ void )
+ throw( uno::RuntimeException )
+{
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_xProvider->queryContent(queryContentIdentifier());
+ else
+ return uno::Reference< ucb::XContent >();
+}
+
+
+
+class XPropertySetInfoImpl
+ : public cppu::OWeakObject,
+ public beans::XPropertySetInfo
+{
+public:
+
+ XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq )
+ : m_aSeq( aSeq )
+ {
+ }
+
+ void SAL_CALL acquire( void )
+ throw()
+ {
+ OWeakObject::acquire();
+ }
+
+
+ void SAL_CALL release( void )
+ throw()
+ {
+ OWeakObject::release();
+ }
+
+ uno::Any SAL_CALL queryInterface( const uno::Type& rType )
+ throw( uno::RuntimeException )
+ {
+ uno::Any aRet = cppu::queryInterface(
+ rType,
+ SAL_STATIC_CAST( beans::XPropertySetInfo*, this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+ }
+
+ uno::Sequence< beans::Property > SAL_CALL getProperties()
+ throw( uno::RuntimeException )
+ {
+ return m_aSeq;
+ }
+
+ beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName )
+ throw( beans::UnknownPropertyException,
+ uno::RuntimeException)
+ {
+ for( int i = 0; i < m_aSeq.getLength(); ++i )
+ if( aName == m_aSeq[i].Name )
+ return m_aSeq[i];
+ throw beans::UnknownPropertyException();
+ }
+
+ sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name )
+ throw( uno::RuntimeException )
+ {
+ for( int i = 0; i < m_aSeq.getLength(); ++i )
+ if( Name == m_aSeq[i].Name )
+ return true;
+ return false;
+ }
+
+private:
+
+ uno::Sequence< beans::Property > m_aSeq;
+};
+
+
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ResultSetBase::getPropertySetInfo()
+ throw( uno::RuntimeException)
+{
+ uno::Sequence< beans::Property > seq(2);
+ seq[0].Name = rtl::OUString::createFromAscii( "RowCount" );
+ seq[0].Handle = -1;
+ seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) );
+ seq[0].Attributes = beans::PropertyAttribute::READONLY;
+
+ seq[1].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" );
+ seq[1].Handle = -1;
+ seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) );
+ seq[1].Attributes = beans::PropertyAttribute::READONLY;
+
+ //t
+ return uno::Reference< beans::XPropertySetInfo > (
+ new XPropertySetInfoImpl( seq ) );
+}
+
+
+
+void SAL_CALL ResultSetBase::setPropertyValue(
+ const rtl::OUString& aPropertyName, const uno::Any& /*aValue*/ )
+ throw( beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ||
+ aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ return;
+
+ throw beans::UnknownPropertyException();
+}
+
+
+uno::Any SAL_CALL ResultSetBase::getPropertyValue(
+ const rtl::OUString& PropertyName )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
+ {
+ uno::Any aAny;
+ aAny <<= m_bRowCountFinal;
+ return aAny;
+ }
+ else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ {
+ uno::Any aAny;
+ sal_Int32 count = m_aItems.size();
+ aAny <<= count;
+ return aAny;
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+
+void SAL_CALL ResultSetBase::addPropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( ! m_pIsFinalListeners )
+ m_pIsFinalListeners =
+ new cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pIsFinalListeners->addInterface( xListener );
+ }
+ else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( ! m_pRowCountListeners )
+ m_pRowCountListeners =
+ new cppu::OInterfaceContainerHelper( m_aMutex );
+ m_pRowCountListeners->addInterface( xListener );
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+
+void SAL_CALL ResultSetBase::removePropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& aListener )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) &&
+ m_pIsFinalListeners )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_pIsFinalListeners->removeInterface( aListener );
+ }
+ else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) &&
+ m_pRowCountListeners )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_pRowCountListeners->removeInterface( aListener );
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+
+void SAL_CALL ResultSetBase::addVetoableChangeListener(
+ const rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
+
+
+void SAL_CALL ResultSetBase::removeVetoableChangeListener(
+ const rtl::OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+ throw( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+}
+
+
+
+// XResultSetMetaDataSupplier
+uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
+ResultSetBase::getMetaData(
+ void )
+ throw( sdbc::SQLException,
+ uno::RuntimeException )
+{
+ ::ucbhelper::ResultSetMetaData* p =
+ new ::ucbhelper::ResultSetMetaData(
+ m_xMSF, m_sProperty );
+ return uno::Reference< sdbc::XResultSetMetaData >( p );
+}
+
+
+
+
diff --git a/ucb/source/ucp/ftp/ftpresultsetbase.hxx b/ucb/source/ucp/ftp/ftpresultsetbase.hxx
new file mode 100644
index 000000000000..d82e38c14e03
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpresultsetbase.hxx
@@ -0,0 +1,608 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _FTP_FTPRESULTSETBASE_HXX_
+#define _FTP_FTPRESULTSETBASE_HXX_
+
+#include <vector>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/Property.hpp>
+
+
+namespace ftp {
+
+ class ResultSetBase
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::sdbc::XRow,
+ public com::sun::star::sdbc::XResultSet,
+ public com::sun::star::sdbc::XCloseable,
+ public com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ public com::sun::star::beans::XPropertySet,
+ public com::sun::star::ucb::XContentAccess
+ {
+ public:
+
+ ResultSetBase(const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& xMSF,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider >& xProvider,
+ sal_Int32 nOpenMode,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property >& seq,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::ucb::NumberedSortingInfo >& seqSort);
+
+ virtual ~ResultSetBase();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ acquire(
+ void )
+ throw();
+
+ virtual void SAL_CALL
+ release(
+ void )
+ throw();
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ addEventListener(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& xListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ // XRow
+ virtual sal_Bool SAL_CALL
+ wasNull(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ m_nWasNull = m_aItems[m_nRow]->wasNull();
+ else
+ m_nWasNull = true;
+ return m_nWasNull;
+ }
+
+ virtual rtl::OUString SAL_CALL
+ getString(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ rtl::OUString ret;
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ ret = m_aItems[m_nRow]->getString( columnIndex );
+
+ return ret;
+ }
+
+ virtual sal_Bool SAL_CALL
+ getBoolean(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBoolean( columnIndex );
+ else
+ return false;
+ }
+
+ virtual sal_Int8 SAL_CALL
+ getByte(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getByte( columnIndex );
+ else
+ return sal_Int8( 0 );
+ }
+
+ virtual sal_Int16 SAL_CALL
+ getShort(
+ sal_Int32 columnIndex )
+ throw(
+ com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getShort( columnIndex );
+ else
+ return sal_Int16( 0 );
+ }
+
+ virtual sal_Int32 SAL_CALL
+ getInt(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getInt( columnIndex );
+ else
+ return sal_Int32( 0 );
+ }
+
+ virtual sal_Int64 SAL_CALL
+ getLong(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getLong( columnIndex );
+ else
+ return sal_Int64( 0 );
+ }
+
+ virtual float SAL_CALL
+ getFloat(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getFloat( columnIndex );
+ else
+ return float( 0 );
+ }
+
+ virtual double SAL_CALL
+ getDouble(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getDouble( columnIndex );
+ else
+ return double( 0 );
+ }
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException )
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBytes( columnIndex );
+ else
+ return com::sun::star::uno::Sequence< sal_Int8 >();
+ }
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getDate( columnIndex );
+ else
+ return com::sun::star::util::Date();
+ }
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getTime( columnIndex );
+ else
+ return com::sun::star::util::Time();
+ }
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getTimestamp( columnIndex );
+ else
+ return com::sun::star::util::DateTime();
+ }
+
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBinaryStream( columnIndex );
+ else
+ return com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >();
+ }
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getCharacterStream( columnIndex );
+ else
+ return com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >();
+ }
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject(
+ sal_Int32 columnIndex,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getObject( columnIndex,typeMap );
+ else
+ return com::sun::star::uno::Any();
+ }
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XRef > SAL_CALL
+ getRef(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getRef( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XRef >();
+ }
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getBlob( columnIndex );
+ else
+ return com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob >();
+ }
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XClob > SAL_CALL
+ getClob(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getClob( columnIndex );
+ else
+ return com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XClob >();
+ }
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XArray > SAL_CALL
+ getArray(
+ sal_Int32 columnIndex )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException)
+ {
+ if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
+ return m_aItems[m_nRow]->getArray( columnIndex );
+ else
+ return com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XArray >();
+ }
+
+
+ // XResultSet
+
+ virtual sal_Bool SAL_CALL
+ next(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isAfterLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ beforeFirst(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ afterLast(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ first(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ last(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ getRow(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ absolute(
+ sal_Int32 row )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ relative(
+ sal_Int32 rows )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ previous(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ refreshRow(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowUpdated(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowInserted(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ rowDeleted(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ getStatement(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ // XCloseable
+
+ virtual void SAL_CALL
+ close(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+ // XContentAccess
+
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent(
+ void )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XResultSetMetaDataSupplier
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XResultSetMetaData > SAL_CALL
+ getMetaData(
+ void )
+ throw( com::sun::star::sdbc::SQLException,
+ com::sun::star::uno::RuntimeException);
+
+
+ // XPropertySet
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL setPropertyValue(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Any& aValue )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue(
+ const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& xListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removePropertyChangeListener(
+ const rtl::OUString& aPropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ protected:
+
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xMSF;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentProvider > m_xProvider;
+ sal_Int32 m_nRow;
+ sal_Bool m_nWasNull;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bRowCountFinal;
+
+ typedef std::vector< com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > > IdentSet;
+ typedef std::vector< com::sun::star::uno::Reference<
+ com::sun::star::sdbc::XRow > > ItemSet;
+ typedef std::vector< rtl::OUString >
+ PathSet;
+
+ IdentSet m_aIdents;
+ ItemSet m_aItems;
+ PathSet m_aPath;
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property > m_sProperty;
+ com::sun::star::uno::Sequence<
+ com::sun::star::ucb::NumberedSortingInfo > m_sSortingInfo;
+
+ osl::Mutex m_aMutex;
+ cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
+
+ cppu::OInterfaceContainerHelper* m_pRowCountListeners;
+ cppu::OInterfaceContainerHelper* m_pIsFinalListeners;
+ };
+
+
+} // end namespace fileaccess
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpresultsetfactory.hxx b/ucb/source/ucp/ftp/ftpresultsetfactory.hxx
new file mode 100644
index 000000000000..24f14162e87e
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpresultsetfactory.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _FTP_FTPRESULTSETFACTORY_HXX_
+#define _FTP_FTPRESULTSETFACTORY_HXX_
+
+#include "ftpresultsetbase.hxx"
+
+
+
+namespace ftp {
+
+ class ResultSetBase;
+
+ class ResultSetFactory
+ {
+ public:
+
+ virtual ~ResultSetFactory() { };
+
+ virtual ResultSetBase* createResultSet() = 0;
+ };
+
+}
+
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpservices.cxx b/ucb/source/ucp/ftp/ftpservices.cxx
new file mode 100644
index 000000000000..fb62acd1cbc0
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpservices.cxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "ftpcontentprovider.hxx"
+
+using namespace com::sun::star;
+using namespace ftp;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // FTP Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ FTPContentProvider::getImplementationName_Static(),
+ FTPContentProvider::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >(
+ pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // FTP Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( FTPContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = FTPContentProvider::createServiceFactory( xSMgr );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/ftp/ftpstrcont.hxx b/ucb/source/ucp/ftp/ftpstrcont.hxx
new file mode 100644
index 000000000000..8598be8831ae
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpstrcont.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _FTP_STRCONT_HXX_
+#define _FTP_STRCONT_HXX_
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "ftpcfunc.hxx"
+
+
+namespace ftp {
+
+
+ class FTPInputStream;
+
+
+ class FTPOutputStreamContainer
+ : public FTPStreamContainer
+ {
+ public:
+
+ FTPOutputStreamContainer(const com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream>& out);
+ virtual ~FTPOutputStreamContainer() {}
+
+ virtual size_t write(void *buffer,size_t size,size_t nmemb);
+
+
+ private:
+
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream> m_out;
+ };
+
+
+ class FTPInputStreamContainer
+ : public FTPStreamContainer
+ {
+ public:
+
+ FTPInputStreamContainer(FTPInputStream* out);
+
+ virtual size_t write(void *buffer,size_t size,size_t nmemb);
+
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream> operator()();
+
+ private:
+
+ FTPInputStream* m_out;
+ };
+
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/ftpurl.cxx b/ucb/source/ucp/ftp/ftpurl.cxx
new file mode 100644
index 000000000000..c703e0942e8a
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpurl.cxx
@@ -0,0 +1,838 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <memory>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <string.h>
+#include <rtl/uri.hxx>
+
+#include "ftpstrcont.hxx"
+#include "ftpurl.hxx"
+#include "ftphandleprovider.hxx"
+#include "ftpinpstr.hxx"
+#include "ftpcfunc.hxx"
+#include "ftpcontainer.hxx"
+
+using namespace ftp;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+
+namespace {
+
+rtl::OUString encodePathSegment(rtl::OUString const & decoded) {
+ return rtl::Uri::encode(
+ decoded, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8);
+}
+
+rtl::OUString decodePathSegment(rtl::OUString const & encoded) {
+ return rtl::Uri::decode(
+ encoded, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+}
+
+}
+
+MemoryContainer::MemoryContainer()
+ : m_nLen(0),
+ m_nWritePos(0),
+ m_pBuffer(0)
+{
+}
+
+MemoryContainer::~MemoryContainer()
+{
+ rtl_freeMemory(m_pBuffer);
+}
+
+
+int MemoryContainer::append(
+ const void* pBuffer,
+ size_t size,
+ size_t nmemb
+) throw()
+{
+ sal_uInt32 nLen = size*nmemb;
+ sal_uInt32 tmp(nLen + m_nWritePos);
+
+ if(m_nLen < tmp) { // enlarge in steps of multiples of 1K
+ do {
+ m_nLen+=1024;
+ } while(m_nLen < tmp);
+
+ m_pBuffer = rtl_reallocateMemory(m_pBuffer,m_nLen);
+ }
+
+ rtl_copyMemory(static_cast<sal_Int8*>(m_pBuffer)+m_nWritePos,
+ pBuffer,nLen);
+ m_nWritePos = tmp;
+ return nLen;
+}
+
+
+extern "C" {
+
+ int memory_write(void *buffer,size_t size,size_t nmemb,void *stream)
+ {
+ MemoryContainer *_stream =
+ reinterpret_cast<MemoryContainer*>(stream);
+
+ if(!_stream)
+ return 0;
+
+ return _stream->append(buffer,size,nmemb);
+ }
+
+}
+
+
+FTPURL::FTPURL(const FTPURL& r)
+ : m_mutex(),
+ m_pFCP(r.m_pFCP),
+ m_aUsername(r.m_aUsername),
+ m_bShowPassword(r.m_bShowPassword),
+ m_aHost(r.m_aHost),
+ m_aPort(r.m_aPort),
+ m_aPathSegmentVec(r.m_aPathSegmentVec)
+
+{
+}
+
+
+FTPURL::FTPURL(const rtl::OUString& url,
+ FTPHandleProvider* pFCP)
+ throw(
+ malformed_exception
+ )
+ : m_pFCP(pFCP),
+ m_aUsername(rtl::OUString::createFromAscii("anonymous")),
+ m_bShowPassword(false),
+ m_aPort(rtl::OUString::createFromAscii("21"))
+{
+ parse(url); // can reset m_bShowPassword
+}
+
+
+FTPURL::~FTPURL()
+{
+}
+
+
+void FTPURL::parse(const rtl::OUString& url)
+ throw(
+ malformed_exception
+ )
+{
+ rtl::OUString aPassword,aAccount;
+ rtl::OString aIdent(url.getStr(),
+ url.getLength(),
+ RTL_TEXTENCODING_UTF8);
+
+ rtl::OString lower = aIdent.toAsciiLowerCase();
+ if(lower.getLength() < 6 ||
+ strncmp("ftp://",lower.getStr(),6))
+ throw malformed_exception();
+
+ char *buffer = new char[1+aIdent.getLength()];
+ const char* p2 = aIdent.getStr();
+ p2 += 6;
+
+ char ch;
+ char *p1 = buffer; // determine "username:password@host:port"
+ while((ch = *p2++) != '/' && ch)
+ *p1++ = ch;
+ *p1 = 0;
+
+ rtl::OUString aExpr(rtl::OUString(buffer,strlen(buffer),
+ RTL_TEXTENCODING_UTF8));
+
+ sal_Int32 l = aExpr.indexOf(sal_Unicode('@'));
+ m_aHost = aExpr.copy(1+l);
+
+ if(l != -1) {
+ // Now username and password.
+ aExpr = aExpr.copy(0,l);
+ l = aExpr.indexOf(sal_Unicode(':'));
+ if(l != -1) {
+ aPassword = aExpr.copy(1+l);
+ if(aPassword.getLength())
+ m_bShowPassword = true;
+ }
+ if(l > 0)
+ // Overwritte only if the username is not empty.
+ m_aUsername = aExpr.copy(0,l);
+ else if(aExpr.getLength())
+ m_aUsername = aExpr;
+ }
+
+ l = m_aHost.lastIndexOf(sal_Unicode(':'));
+ sal_Int32 ipv6Back = m_aHost.lastIndexOf(sal_Unicode(']'));
+ if((ipv6Back == -1 && l != -1) // not ipv6, but a port
+ ||
+ (ipv6Back != -1 && 1+ipv6Back == l) // ipv6, and a port
+ )
+ {
+ if(1+l<m_aHost.getLength())
+ m_aPort = m_aHost.copy(1+l);
+ m_aHost = m_aHost.copy(0,l);
+ }
+
+ while(ch) { // now determine the pathsegments ...
+ p1 = buffer;
+ while((ch = *p2++) != '/' && ch)
+ *p1++ = ch;
+ *p1 = 0;
+
+ if(buffer[0]) {
+ if(strcmp(buffer,"..") == 0 &&
+ m_aPathSegmentVec.size() &&
+ ! m_aPathSegmentVec.back().equalsAscii(".."))
+ m_aPathSegmentVec.pop_back();
+ else if(strcmp(buffer,".") == 0)
+ ; // Ignore
+ else
+ // This is a legal name.
+ m_aPathSegmentVec.push_back(
+ rtl::OUString(buffer,
+ strlen(buffer),
+ RTL_TEXTENCODING_UTF8));
+ }
+ }
+
+ delete[] buffer;
+
+ if(m_bShowPassword)
+ m_pFCP->setHost(m_aHost,
+ m_aPort,
+ m_aUsername,
+ aPassword,
+ aAccount);
+
+ // now check for something like ";type=i" at end of url
+ if(m_aPathSegmentVec.size() &&
+ (l = m_aPathSegmentVec.back().indexOf(sal_Unicode(';'))) != -1) {
+ m_aType = m_aPathSegmentVec.back().copy(l);
+ m_aPathSegmentVec.back() = m_aPathSegmentVec.back().copy(0,l);
+ }
+}
+
+
+rtl::OUString FTPURL::ident(bool withslash,bool internal) const
+{
+ // rebuild the url as one without ellipses,
+ // and more important, as one without username and
+ // password. ( These are set together with the command. )
+
+ rtl::OUStringBuffer bff;
+ bff.appendAscii("ftp://");
+
+ if(!m_aUsername.equalsAscii("anonymous")) {
+ bff.append(m_aUsername);
+
+ rtl::OUString aPassword,aAccount;
+ m_pFCP->forHost(m_aHost,
+ m_aPort,
+ m_aUsername,
+ aPassword,
+ aAccount);
+
+ if((m_bShowPassword || internal) &&
+ aPassword.getLength() )
+ bff.append(sal_Unicode(':'))
+ .append(aPassword);
+
+ bff.append(sal_Unicode('@'));
+ }
+ bff.append(m_aHost);
+
+ if(!m_aPort.equalsAscii("21"))
+ bff.append(sal_Unicode(':'))
+ .append(m_aPort)
+ .append(sal_Unicode('/'));
+ else
+ bff.append(sal_Unicode('/'));
+
+ for(unsigned i = 0; i < m_aPathSegmentVec.size(); ++i)
+ if(i == 0)
+ bff.append(m_aPathSegmentVec[i]);
+ else
+ bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
+ if(withslash)
+ if(bff.getLength() && bff[bff.getLength()-1] != sal_Unicode('/'))
+ bff.append(sal_Unicode('/'));
+
+ bff.append(m_aType);
+ return bff.makeStringAndClear();
+}
+
+
+rtl::OUString FTPURL::parent(bool internal) const
+{
+ rtl::OUStringBuffer bff;
+
+ bff.appendAscii("ftp://");
+
+ if(!m_aUsername.equalsAscii("anonymous")) {
+ bff.append(m_aUsername);
+
+ rtl::OUString aPassword,aAccount;
+ m_pFCP->forHost(m_aHost,
+ m_aPort,
+ m_aUsername,
+ aPassword,
+ aAccount);
+
+ if((internal || m_bShowPassword) && aPassword.getLength())
+ bff.append(sal_Unicode(':'))
+ .append(aPassword);
+
+ bff.append(sal_Unicode('@'));
+ }
+
+ bff.append(m_aHost);
+
+ if(!m_aPort.equalsAscii("21"))
+ bff.append(sal_Unicode(':'))
+ .append(m_aPort)
+ .append(sal_Unicode('/'));
+ else
+ bff.append(sal_Unicode('/'));
+
+ rtl::OUString last;
+
+ for(unsigned int i = 0; i < m_aPathSegmentVec.size(); ++i)
+ if(1+i == m_aPathSegmentVec.size())
+ last = m_aPathSegmentVec[i];
+ else if(i == 0)
+ bff.append(m_aPathSegmentVec[i]);
+ else
+ bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
+
+ if(!last.getLength())
+ bff.appendAscii("..");
+ else if(last.equalsAscii(".."))
+ bff.append(last).appendAscii("/..");
+
+ bff.append(m_aType);
+ return bff.makeStringAndClear();
+}
+
+
+void FTPURL::child(const rtl::OUString& title)
+{
+ m_aPathSegmentVec.push_back(encodePathSegment(title));
+}
+
+
+rtl::OUString FTPURL::child() const
+{
+ return
+ m_aPathSegmentVec.size() ?
+ decodePathSegment(m_aPathSegmentVec.back()) : rtl::OUString();
+}
+
+
+
+/** Listing of a directory.
+ */
+
+namespace ftp {
+
+ enum OS {
+ FTP_DOS,FTP_UNIX,FTP_VMS,FTP_UNKNOWN
+ };
+
+}
+
+
+#define SET_CONTROL_CONTAINER \
+ MemoryContainer control; \
+ curl_easy_setopt(curl, \
+ CURLOPT_HEADERFUNCTION, \
+ memory_write); \
+ curl_easy_setopt(curl, \
+ CURLOPT_WRITEHEADER, \
+ &control)
+
+
+#define SET_DATA_CONTAINER \
+ curl_easy_setopt(curl,CURLOPT_NOBODY,false); \
+ MemoryContainer data; \
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,memory_write); \
+ curl_easy_setopt(curl,CURLOPT_WRITEDATA,&data)
+
+#define SET_URL(url) \
+ rtl::OString urlParAscii(url.getStr(), \
+ url.getLength(), \
+ RTL_TEXTENCODING_UTF8); \
+ curl_easy_setopt(curl, \
+ CURLOPT_URL, \
+ urlParAscii.getStr());
+
+ // Setting username:password
+#define SET_USER_PASSWORD(username,password) \
+ rtl::OUString combi(username + \
+ rtl::OUString::createFromAscii(":") + \
+ password); \
+ rtl::OString aUserPsswd(combi.getStr(), \
+ combi.getLength(), \
+ RTL_TEXTENCODING_UTF8); \
+ curl_easy_setopt(curl, \
+ CURLOPT_USERPWD, \
+ aUserPsswd.getStr())
+
+
+
+FILE* FTPURL::open()
+ throw(curl_exception)
+{
+ if(!m_aPathSegmentVec.size())
+ throw curl_exception(CURLE_FTP_COULDNT_RETR_FILE);
+
+ CURL *curl = m_pFCP->handle();
+
+ SET_CONTROL_CONTAINER;
+ rtl::OUString url(ident(false,true));
+ SET_URL(url);
+ FILE *res = tmpfile();
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,file_write);
+ curl_easy_setopt(curl,CURLOPT_WRITEDATA,res);
+
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
+ CURLcode err = curl_easy_perform(curl);
+
+ if(err == CURLE_OK)
+ rewind(res);
+ else {
+ fclose(res),res = 0;
+ throw curl_exception(err);
+ }
+
+ return res;
+}
+
+
+std::vector<FTPDirentry> FTPURL::list(
+ sal_Int16 nMode
+) const
+ throw(
+ curl_exception
+ )
+{
+ CURL *curl = m_pFCP->handle();
+
+ SET_CONTROL_CONTAINER;
+ SET_DATA_CONTAINER;
+ rtl::OUString url(ident(true,true));
+ SET_URL(url);
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
+
+ CURLcode err = curl_easy_perform(curl);
+ if(err != CURLE_OK)
+ throw curl_exception(err);
+
+ // now evaluate the error messages
+
+ sal_uInt32 len = data.m_nWritePos;
+ char* fwd = (char*) data.m_pBuffer;
+ rtl::OString str(fwd,len);
+ char *p1, *p2;
+ p1 = p2 = fwd;
+
+ OS osKind(FTP_UNKNOWN);
+ std::vector<FTPDirentry> resvec;
+ FTPDirentry aDirEntry;
+ // ensure slash at the end
+ rtl::OUString viewurl(ident(true,false));
+
+ while(true) {
+ while(p2-fwd < int(len) && *p2 != '\n') ++p2;
+ if(p2-fwd == int(len)) break;
+
+ *p2 = 0;
+ switch(osKind) {
+ // While FTP knows the 'system'-command,
+ // which returns the operating system type,
+ // this is not usable here: There are Windows-server
+ // formatting the output like UNIX-ls command.
+ case FTP_DOS:
+ FTPDirectoryParser::parseDOS(aDirEntry,p1);
+ break;
+ case FTP_UNIX:
+ FTPDirectoryParser::parseUNIX(aDirEntry,p1);
+ break;
+ case FTP_VMS:
+ FTPDirectoryParser::parseVMS(aDirEntry,p1);
+ break;
+ default:
+ if(FTPDirectoryParser::parseUNIX(aDirEntry,p1))
+ osKind = FTP_UNIX;
+ else if(FTPDirectoryParser::parseDOS(aDirEntry,p1))
+ osKind = FTP_DOS;
+ else if(FTPDirectoryParser::parseVMS(aDirEntry,p1))
+ osKind = FTP_VMS;
+ }
+ aDirEntry.m_aName = aDirEntry.m_aName.trim();
+ if(osKind != int(FTP_UNKNOWN) &&
+ !aDirEntry.m_aName.equalsAscii("..") &&
+ !aDirEntry.m_aName.equalsAscii(".")) {
+ aDirEntry.m_aURL = viewurl + encodePathSegment(aDirEntry.m_aName);
+
+ sal_Bool isDir =
+ sal_Bool(aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR);
+ switch(nMode) {
+ case OpenMode::DOCUMENTS:
+ if(!isDir)
+ resvec.push_back(aDirEntry);
+ break;
+ case OpenMode::FOLDERS:
+ if(isDir)
+ resvec.push_back(aDirEntry);
+ break;
+ default:
+ resvec.push_back(aDirEntry);
+ };
+ }
+ aDirEntry.clear();
+ p1 = p2 + 1;
+ }
+
+ return resvec;
+}
+
+
+rtl::OUString FTPURL::net_title() const
+ throw(curl_exception)
+{
+ CURL *curl = m_pFCP->handle();
+
+ SET_CONTROL_CONTAINER;
+ curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
+ struct curl_slist *slist = 0;
+ // post request
+ slist = curl_slist_append(slist,"PWD");
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
+
+ bool try_more(true);
+ CURLcode err;
+ rtl::OUString aNetTitle;
+
+ while(true) {
+ rtl::OUString url(ident(false,true));
+
+ if(try_more &&
+ 1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
+ url += rtl::OUString::createFromAscii("/"); // add end-slash
+ else if(!try_more &&
+ 1+url.lastIndexOf(sal_Unicode('/')) == url.getLength())
+ url = url.copy(0,url.getLength()-1); // remove end-slash
+
+ SET_URL(url);
+ err = curl_easy_perform(curl);
+
+ if(err == CURLE_OK) { // get the title from the server
+ char* fwd = (char*) control.m_pBuffer;
+ sal_uInt32 len = (sal_uInt32) control.m_nWritePos;
+
+ aNetTitle = rtl::OUString(fwd,len,RTL_TEXTENCODING_UTF8);
+ // the buffer now contains the name of the file;
+ // analyze the output:
+ // Format of current working directory:
+ // 257 "/bla/bla" is current directory
+ sal_Int32 index1 = aNetTitle.lastIndexOf(
+ rtl::OUString::createFromAscii("257"));
+ index1 = 1+aNetTitle.indexOf(sal_Unicode('"'),index1);
+ sal_Int32 index2 = aNetTitle.indexOf(sal_Unicode('"'),index1);
+ aNetTitle = aNetTitle.copy(index1,index2-index1);
+ if(!aNetTitle.equalsAscii("/")) {
+ index1 = aNetTitle.lastIndexOf(sal_Unicode('/'));
+ aNetTitle = aNetTitle.copy(1+index1);
+ }
+ try_more = false;
+ } else if(err == CURLE_BAD_PASSWORD_ENTERED)
+ // the client should retry after getting the correct
+ // username + password
+ throw curl_exception(err);
+#if LIBCURL_VERSION_NUM>=0x070d01 /* 7.13.1 */
+ else if(err == CURLE_LOGIN_DENIED)
+ // the client should retry after getting the correct
+ // username + password
+ throw curl_exception(err);
+#endif
+ else if(try_more && err == CURLE_FTP_ACCESS_DENIED) {
+ // We were either denied access when trying to login to
+ // an FTP server or when trying to change working directory
+ // to the one given in the URL.
+ if(m_aPathSegmentVec.size())
+ // determine title form url
+ aNetTitle = decodePathSegment(m_aPathSegmentVec.back());
+ else
+ // must be root
+ aNetTitle = rtl::OUString::createFromAscii("/");
+ try_more = false;
+ }
+
+ if(try_more)
+ try_more = false;
+ else
+ break;
+ }
+
+ curl_slist_free_all(slist);
+ return aNetTitle;
+}
+
+
+FTPDirentry FTPURL::direntry() const
+ throw(curl_exception)
+{
+ rtl::OUString nettitle = net_title();
+ FTPDirentry aDirentry;
+
+ aDirentry.m_aName = nettitle; // init aDirentry
+ if(nettitle.equalsAscii("/") ||
+ nettitle.equalsAscii(".."))
+ aDirentry.m_nMode = INETCOREFTP_FILEMODE_ISDIR;
+ else
+ aDirentry.m_nMode = INETCOREFTP_FILEMODE_UNKNOWN;
+
+ aDirentry.m_nSize = 0;
+
+ if(!nettitle.equalsAscii("/")) {
+ // try to open the parent directory
+ FTPURL aURL(parent(),m_pFCP);
+
+ std::vector<FTPDirentry> aList = aURL.list(OpenMode::ALL);
+
+ for(unsigned i = 0; i < aList.size(); ++i) {
+ if(aList[i].m_aName == nettitle) { // the relevant file is found
+ aDirentry = aList[i];
+ break;
+ }
+ }
+ }
+ return aDirentry;
+}
+
+
+extern "C" {
+
+ size_t memory_read(void *ptr,size_t size,size_t nmemb,void *stream)
+ {
+ sal_Int32 nRequested = sal_Int32(size*nmemb);
+ CurlInput *curlInput = static_cast<CurlInput*>(stream);
+ if(curlInput)
+ return size_t(curlInput->read(((sal_Int8*)ptr),nRequested));
+ else
+ return 0;
+ }
+
+}
+
+
+void FTPURL::insert(bool replaceExisting,void* stream) const
+ throw(curl_exception)
+{
+ if(!replaceExisting) {
+// FTPDirentry aDirentry(direntry());
+// if(aDirentry.m_nMode == INETCOREFTP_FILEMODE_UNKNOWN)
+ // throw curl_exception(FILE_EXIST_DURING_INSERT);
+ throw curl_exception(FILE_MIGHT_EXIST_DURING_INSERT);
+ } // else
+ // overwrite is default in libcurl
+
+ CURL *curl = m_pFCP->handle();
+
+ SET_CONTROL_CONTAINER;
+ curl_easy_setopt(curl,CURLOPT_NOBODY,false); // no data => no transfer
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
+ curl_easy_setopt(curl,CURLOPT_QUOTE,0);
+ curl_easy_setopt(curl,CURLOPT_READFUNCTION,memory_read);
+ curl_easy_setopt(curl,CURLOPT_READDATA,stream);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD,1);
+
+ rtl::OUString url(ident(false,true));
+ SET_URL(url);
+
+ CURLcode err = curl_easy_perform(curl);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD,false);
+
+ if(err != CURLE_OK)
+ throw curl_exception(err);
+}
+
+
+
+void FTPURL::mkdir(bool ReplaceExisting) const
+ throw(curl_exception)
+{
+ rtl::OString title;
+ if(m_aPathSegmentVec.size()) {
+ rtl::OUString titleOU = m_aPathSegmentVec.back();
+ titleOU = decodePathSegment(titleOU);
+ title = rtl::OString(titleOU.getStr(),
+ titleOU.getLength(),
+ RTL_TEXTENCODING_UTF8);
+ }
+ else
+ // will give an error
+ title = rtl::OString("/");
+
+ rtl::OString aDel("del "); aDel += title;
+ rtl::OString mkd("mkd "); mkd += title;
+
+ struct curl_slist *slist = 0;
+
+ FTPDirentry aDirentry(direntry());
+ if(!ReplaceExisting) {
+// if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
+// throw curl_exception(FOLDER_EXIST_DURING_INSERT);
+ throw curl_exception(FOLDER_MIGHT_EXIST_DURING_INSERT);
+ } else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
+ slist = curl_slist_append(slist,aDel.getStr());
+
+ slist = curl_slist_append(slist,mkd.getStr());
+
+ CURL *curl = m_pFCP->handle();
+ SET_CONTROL_CONTAINER;
+ curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
+ curl_easy_setopt(curl,CURLOPT_QUOTE,0);
+
+ // post request
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
+
+ rtl::OUString url(parent(true));
+ if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
+ url += rtl::OUString::createFromAscii("/");
+ SET_URL(url);
+
+ CURLcode err = curl_easy_perform(curl);
+ curl_slist_free_all(slist);
+ if(err != CURLE_OK)
+ throw curl_exception(err);
+}
+
+
+rtl::OUString FTPURL::ren(const rtl::OUString& NewTitle)
+ throw(curl_exception)
+{
+ CURL *curl = m_pFCP->handle();
+
+ // post request
+ rtl::OString renamefrom("RNFR ");
+ rtl::OUString OldTitle = net_title();
+ renamefrom +=
+ rtl::OString(OldTitle.getStr(),
+ OldTitle.getLength(),
+ RTL_TEXTENCODING_UTF8);
+
+ rtl::OString renameto("RNTO ");
+ renameto +=
+ rtl::OString(NewTitle.getStr(),
+ NewTitle.getLength(),
+ RTL_TEXTENCODING_UTF8);
+
+ struct curl_slist *slist = 0;
+ slist = curl_slist_append(slist,renamefrom.getStr());
+ slist = curl_slist_append(slist,renameto.getStr());
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
+
+ SET_CONTROL_CONTAINER;
+ curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
+ curl_easy_setopt(curl,CURLOPT_QUOTE,0);
+
+ rtl::OUString url(parent(true));
+ if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
+ url += rtl::OUString::createFromAscii("/");
+ SET_URL(url);
+
+ CURLcode err = curl_easy_perform(curl);
+ curl_slist_free_all(slist);
+ if(err != CURLE_OK)
+ throw curl_exception(err);
+ else if(m_aPathSegmentVec.size() &&
+ !m_aPathSegmentVec.back().equalsAscii(".."))
+ m_aPathSegmentVec.back() = encodePathSegment(NewTitle);
+ return OldTitle;
+}
+
+
+
+void FTPURL::del() const
+ throw(curl_exception)
+{
+ FTPDirentry aDirentry(direntry());
+
+ rtl::OString dele(aDirentry.m_aName.getStr(),
+ aDirentry.m_aName.getLength(),
+ RTL_TEXTENCODING_UTF8);
+
+ if(aDirentry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) {
+ std::vector<FTPDirentry> vec = list(sal_Int16(OpenMode::ALL));
+ for( unsigned int i = 0; i < vec.size(); ++i )
+ try {
+ FTPURL url(vec[i].m_aURL,m_pFCP);
+ url.del();
+ } catch(const curl_exception&) {
+ }
+ dele = rtl::OString("RMD ") + dele;
+ }
+ else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
+ dele = rtl::OString("DELE ") + dele;
+ else
+ return;
+
+ // post request
+ CURL *curl = m_pFCP->handle();
+ struct curl_slist *slist = 0;
+ slist = curl_slist_append(slist,dele.getStr());
+ curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
+
+ SET_CONTROL_CONTAINER;
+ curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
+ curl_easy_setopt(curl,CURLOPT_QUOTE,0);
+
+ rtl::OUString url(parent(true));
+ if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
+ url += rtl::OUString::createFromAscii("/");
+ SET_URL(url);
+
+ CURLcode err = curl_easy_perform(curl);
+ curl_slist_free_all(slist);
+ if(err != CURLE_OK)
+ throw curl_exception(err);
+}
+
diff --git a/ucb/source/ucp/ftp/ftpurl.hxx b/ucb/source/ucp/ftp/ftpurl.hxx
new file mode 100644
index 000000000000..fa2acdcc2770
--- /dev/null
+++ b/ucb/source/ucp/ftp/ftpurl.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#ifndef _FTP_FTPURL_HXX_
+#define _FTP_FTPURL_HXX_
+
+#include "curl.hxx"
+#include <curl/easy.h>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+#include <stdio.h>
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <vector>
+
+#include "ftpdirp.hxx"
+#include "ftpcfunc.hxx"
+
+namespace ftp {
+
+ /** Forward declarations.
+ */
+
+ class FTPHandleProvider;
+
+
+ enum FTPErrors { FILE_EXIST_DURING_INSERT = CURL_LAST +1,
+ FOLDER_EXIST_DURING_INSERT,
+ FOLDER_MIGHT_EXIST_DURING_INSERT,
+ FILE_MIGHT_EXIST_DURING_INSERT };
+
+
+ class malformed_exception { };
+
+
+ class curl_exception
+ {
+ public:
+
+ curl_exception(sal_Int32 err)
+ : n_err(err) { }
+
+ sal_Int32 code() const { return n_err; }
+
+
+ private:
+
+ sal_Int32 n_err;
+ };
+
+ class CurlInput {
+
+ public:
+
+ // returns the number of bytes actually read
+ virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested) = 0;
+ };
+
+
+ class FTPURL
+ {
+ public:
+
+ FTPURL(
+ const rtl::OUString& aIdent,
+ FTPHandleProvider* pFCP = 0
+ )
+ throw(
+ malformed_exception
+ );
+
+ FTPURL(const FTPURL& r);
+
+ ~FTPURL();
+
+ rtl::OUString host() const { return m_aHost; }
+
+ rtl::OUString port() const { return m_aPort; }
+
+ rtl::OUString username() const { return m_aUsername; }
+
+ /** This returns the URL, but cleaned from
+ * unnessary ellipses.
+ */
+
+ rtl::OUString ident(bool withslash,bool internal) const;
+
+ /** returns the parent url.
+ */
+
+ rtl::OUString parent(bool internal = false) const;
+
+ /** sets the unencoded title */
+ void child(const rtl::OUString& title);
+
+ /** returns the unencoded title */
+ rtl::OUString child(void) const;
+
+ std::vector<FTPDirentry> list(sal_Int16 nMode) const
+ throw(curl_exception);
+
+ // returns a pointer to an open tempfile,
+ // seeked to the beginning of.
+ FILE* open() throw(curl_exception);
+
+ FTPDirentry direntry() const throw(curl_exception);
+
+ void insert(bool ReplaceExisting,void* stream) const
+ throw(curl_exception);
+
+ void mkdir(bool ReplaceExisting) const
+ throw(curl_exception);
+
+ rtl::OUString ren(const rtl::OUString& NewTitle)
+ throw(curl_exception);
+
+ void del() const
+ throw(curl_exception);
+
+
+ private:
+
+ osl::Mutex m_mutex;
+
+ FTPHandleProvider *m_pFCP;
+
+ mutable rtl::OUString m_aUsername;
+ bool m_bShowPassword;
+ mutable rtl::OUString m_aHost;
+ mutable rtl::OUString m_aPort;
+ mutable rtl::OUString m_aType;
+
+ /** Contains the encoded pathsegments of the url.
+ */
+ std::vector<rtl::OUString> m_aPathSegmentVec;
+
+ void parse(const rtl::OUString& url)
+ throw(
+ malformed_exception
+ );
+
+ rtl::OUString net_title() const throw(curl_exception);
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/makefile.mk b/ucb/source/ucp/ftp/makefile.mk
new file mode 100644
index 000000000000..a0f141004089
--- /dev/null
+++ b/ucb/source/ucp/ftp/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+TARGET=ucpftp
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCPFTP_MAJOR=1
+
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+# first target ( shared library )
+
+SLOFILES1=\
+ $(SLO)$/ftpservices.obj \
+ $(SLO)$/ftpcontentprovider.obj \
+ $(SLO)$/ftpcontent.obj \
+ $(SLO)$/ftpcontentidentifier.obj \
+ $(SLO)$/ftpcontentcaps.obj \
+ $(SLO)$/ftpdynresultset.obj \
+ $(SLO)$/ftpresultsetbase.obj \
+ $(SLO)$/ftpresultsetI.obj \
+ $(SLO)$/ftploaderthread.obj \
+ $(SLO)$/ftpinpstr.obj \
+ $(SLO)$/ftpdirp.obj \
+ $(SLO)$/ftpcfunc.obj \
+ $(SLO)$/ftpurl.obj \
+ $(SLO)$/ftpintreq.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES1)
+
+# --- Shared-Library 1 ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCPFTP_MAJOR)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB) \
+ $(CURLLIB)
+
+.IF "$(GUI)" == "OS2"
+SHL1STDLIBS+=ssl.lib crypto.lib libz.lib
+.ENDIF
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS= \
+ $(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # L10N_framework
+.INCLUDE: target.mk
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ucb/source/ucp/ftp/test.cxx b/ucb/source/ucp/ftp/test.cxx
new file mode 100644
index 000000000000..9bc6585400ba
--- /dev/null
+++ b/ucb/source/ucp/ftp/test.cxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "test_ftpurl.hxx"
+#include <stdio.h>
+#include <unistd.h>
+
+// #include <osl/process.h>
+// #include <osl/thread.hxx>
+
+// #include <ucbhelper/configurationkeys.hxx>
+// #include <cppuhelper/bootstrap.hxx>
+// #include <cppuhelper/servicefactory.hxx>
+// #include <comphelper/processfactory.hxx>
+// #include <comphelper/regpathhelper.hxx>
+// #include <com/sun/star/lang/XComponent.hpp>
+// #include <com/sun/star/lang/XMultiServiceFactory.hpp>
+// #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
+// #include <com/sun/star/ucb/XContent.hpp>
+// #include <com/sun/star/ucb/XContentProvider.hpp>
+// #include <com/sun/star/ucb/XCommandProcessor.hpp>
+// #include <com/sun/star/ucb/OpenMode.hpp>
+// #include <com/sun/star/ucb/Command.hpp>
+// #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+// #include <com/sun/star/io/XActiveDataSink.hpp>
+// #include <com/sun/star/beans/Property.hpp>
+
+
+// #include "debughelper.hxx"
+// #include "test_activedatasink.hxx"
+// #include "test_ftpurl.hxx"
+// #include "test_multiservicefac.hxx"
+// #include "ftpcontentprovider.hxx"
+// #include "ftpcontentidentifier.hxx"
+
+
+// using namespace test_ftp;
+// using namespace rtl;
+// using namespace com::sun::star::uno;
+// using namespace com::sun::star::lang;
+// using namespace com::sun::star::ucb;
+// using namespace com::sun::star::beans;
+// using namespace com::sun::star::io;
+
+
+
+// class FTPThread
+// : public osl::Thread
+// {
+// public:
+
+// FTPThread();
+
+// int number_of_errors() { return _number_of_errors; }
+
+// protected:
+
+// void SAL_CALL run();
+
+
+// private:
+
+// ftp::FTPContentProvider *pProvider;
+// Reference<XContentProvider> xProvider;
+// Reference<XMultiServiceFactory> xFac;
+
+// int _number_of_errors;
+// };
+
+
+// Reference< XMultiServiceFactory > createApplicationServiceManager()
+// {
+// try
+// {
+// Reference<XComponentContext> xComponentContext =
+// ::cppu::defaultBootstrap_InitialComponentContext();
+// Reference<XMultiServiceFactory> xMS(
+// xComponentContext->getServiceManager(),
+// UNO_QUERY);
+
+// return xMS;
+// }
+// catch( ::com::sun::star::uno::Exception& )
+// {
+// return Reference< XMultiServiceFactory >();
+// }
+// }
+
+
+// FTPThread::FTPThread()
+// : _number_of_errors(0),
+// xFac(createApplicationServiceManager())
+// {
+// pProvider = new ftp::FTPContentProvider(xFac);
+// xProvider = Reference<XContentProvider>(pProvider);
+
+// if(!xProvider.is())
+// ++_number_of_errors;
+// }
+
+
+// void FTPThread::run() {
+// if(!xFac.is()) {
+// ++_number_of_errors;
+// exit(1);
+// }
+
+// Reference<XContentIdentifier> xIdent(
+// new ftp::FTPContentIdentifier(
+// rtl::OUString::createFromAscii("ftp://abi:psswd@abi-1/file"),
+// pProvider));
+
+// Reference<XContent> xContent = xProvider->queryContent(xIdent);
+// if(!xContent.is())
+// {
+// err_msg("no content",OUString());
+// exit(1);
+// }
+
+
+// Reference<XActiveDataSink> xActDS(new Test_ActiveDataSink());
+// OpenCommandArgument2 aOpenCommand(OpenMode::DOCUMENT,
+// 0,
+// Reference<XInterface>(xActDS,UNO_QUERY),
+// Sequence<Property>(0),
+// Sequence<NumberedSortingInfo>(0));
+// Any aAny; aAny <<= aOpenCommand;
+
+// Command aCommand(OUString::createFromAscii("open"),
+// -1,
+// aAny);
+
+// Reference<XCommandProcessor> xCommandProcessor(xContent,UNO_QUERY);
+// if(!xCommandProcessor.is())
+// {
+// err_msg("no command_processor",OUString());
+// exit(1);
+// }
+// xCommandProcessor->execute(aCommand,
+// 0,Reference<XCommandEnvironment>(0));
+
+// Reference<XInputStream> xInputStream = xActDS->getInputStream();
+// if(!xInputStream.is())
+// ;
+// }
+
+
+int main(int argc,char* argv[])
+{
+// FTPThread aThread;
+// aThread.create();
+// aThread.join();
+
+ typedef int (*INT_FUNC)(void);
+ INT_FUNC tests[] = { test_ftpurl,
+ test_ftpparent,
+ test_ftpproperties,
+ test_ftpopen,
+ test_ftplist,
+ 0 }; // don't remove ending zero
+
+ int err_level = 0;
+
+ fprintf(stderr,"------- Testing ----------\n");
+
+ int i = -1;
+ do {
+ INT_FUNC f = tests[++i];
+ if(f) {
+ err_level += (*f)();
+ fprintf(stderr,".");
+ } else
+ break;
+ } while(true);
+
+ if(err_level) {
+ fprintf(stderr,"number of failed tests: %d\n",err_level);
+ fprintf(stderr,"----------------------------------\n");
+ } else
+ fprintf(stderr,"no errors\n");
+
+ return err_level;
+}
+
+
+
+// char *scefile = 0;
+// if(strcmp(argv[1],"-sce") == 0)
+// scefile = argv[2];
+
+// if(!scefile) {
+// fprintf(stderr,"usage: ftptest -sce filename\n");
+// return 1;
+// }
+
+// rtl::OUString sceurl;
+// osl::FileBase::RC err =
+// osl::FileBase::getFileURLFromSystemPath(
+// rtl::OUString(scefile,
+// strlen(scefile),
+// RTL_TEXTENCODING_UTF8),
+// sceurl);
+
+// osl::File aFile(sceurl);
+// err = aFile.open(OpenFlag_Read);
+// if(err != osl::FileBase::E_None) {
+// fprintf(stderr,"could not open sce-file %s\n",scefile);
+// return 1;
+// }
+
+// sal_uInt64 n;
+// char buffer[256];
+// rtl::OUStringBuffer bff;
+// do {
+// err = aFile.read((void*)buffer,256,n);
+// bff.appendAscii(buffer,sal_Int32(n));
+// } while(err == osl::FileBase::E_None && n == 256);
+
+// aFile.close();
+
+// rtl::OUString sce = bff.makeStringAndClear();
+
+// fprintf(stderr,rtl::OString(sce.getStr(),
+// sce.getLength(),
+// RTL_TEXTENCODING_UTF8).getStr());
+
+// rtl::OUString lib,tmp,testlib;
+// std::vector<rtl::OUString> tests;
+// sal_Int32 TEST = sce.indexOf(rtl::OUString::createFromAscii("TEST"));
+// sal_Int32 WITH = sce.indexOf(rtl::OUString::createFromAscii("WITH"));
+// sal_Int32 FROM = sce.indexOf(rtl::OUString::createFromAscii("FROM"));
+// lib = sce.copy(TEST+4,WITH-TEST-4).trim();
+
+// tmp = sce.copy(WITH+4,FROM-WITH-4).trim();
+// sal_Int32 nIndex = 0;
+// do
+// {
+// rtl::OUString token = tmp.getToken(0,';',nIndex).trim();
+// if(token.getLength())
+// tests.push_back(token);
+// } while(nIndex >= 0);
+
+// testlib = sce.copy(FROM+4).trim();
+
+// // fprintf(stderr,"%s\n",
+// // rtl::OString(token.getStr(),
+// // token.getLength(),
+// // RTL_TEXTENCODING_UTF8).getStr());
+
+// osl::Module testLib;
+// if(!testLib.load(testlib)) {
+// fprintf(stderr,"library not found: %s\n",
+// rtl::OString(testlib.getStr(),
+// testlib.getLength(),
+// RTL_TEXTENCODING_UTF8).getStr());
+// return 1;
+// }
+
+// osl::Module mathLib;
+// mathLib.load(rtl::OUString::createFromAscii("libm.so"));
+// typedef double (*DF)(double);
+// DF func = (DF)mathLib.getSymbol(rtl::OUString::createFromAscii("cos"));
+// fprintf(stderr,"-------double %f ----------\n",(*func)(2.0));
+
+// fprintf(stderr,"-------testing %s ----------\n",scefile);
diff --git a/ucb/source/ucp/ftp/test.py b/ucb/source/ucp/ftp/test.py
new file mode 100644
index 000000000000..931d9a3ec8a5
--- /dev/null
+++ b/ucb/source/ucp/ftp/test.py
@@ -0,0 +1,25 @@
+#/usr/bin/env python
+
+import re,os
+
+def grep(pattern,dirname,names):
+ for name in names:
+ filename = os.path.join(dirname,name)
+ if os.path.isfile(filename):
+ lines = open(filename,"r").readlines()
+ for line in lines:
+ if pattern.search(line):
+ print filename
+ break
+
+
+def find(pattern,directory = "."):
+ os.path.walk(directory,grep,re.compile(pattern))
+
+
+if __name__ == "__main__":
+ import sys
+ if len(sys.argv) == 2:
+ find(sys.argv[1])
+ elif len(sys.argv) == 2:
+ find(sys.argv[2],sys.argv[1])
diff --git a/ucb/source/ucp/ftp/test_activedatasink.cxx b/ucb/source/ucp/ftp/test_activedatasink.cxx
new file mode 100644
index 000000000000..5265dc530be9
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_activedatasink.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#ifndef _TEST_ACTIVEDATASINK_HXX_
+#include "test_activedatasink.hxx"
+#endif
+
+
+using namespace test_ftp;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+
+
+Any SAL_CALL Test_ActiveDataSink::queryInterface( const Type& rType ) throw( RuntimeException ) {
+ Any aRet = ::cppu::queryInterface(rType,
+ SAL_STATIC_CAST( XActiveDataSink*,this ));
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+}
+
+
+
+void SAL_CALL Test_ActiveDataSink::acquire( void ) throw() {
+ OWeakObject::acquire();
+}
+
+
+
+void SAL_CALL Test_ActiveDataSink::release( void ) throw() {
+ OWeakObject::release();
+}
diff --git a/ucb/source/ucp/ftp/test_activedatasink.hxx b/ucb/source/ucp/ftp/test_activedatasink.hxx
new file mode 100644
index 000000000000..55e62d90f5a3
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_activedatasink.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _TEST_ACTIVEDATASINK_HXX_
+#define _TEST_ACTIVEDATASINK_HXX_
+
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+
+namespace test_ftp {
+
+
+ class Test_ActiveDataSink
+ : public cppu::OWeakObject,
+ public com::sun::star::io::XActiveDataSink
+ {
+ public:
+
+ // XInterface
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ virtual void SAL_CALL acquire( void ) throw();
+
+ virtual void SAL_CALL release( void ) throw();
+
+
+ // XActiveDataSink
+
+ virtual void SAL_CALL
+ setInputStream(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& aStream )
+ throw(com::sun::star::uno::RuntimeException)
+ {
+ m_xInputStream = aStream;
+ }
+
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL
+ getInputStream( )
+ throw(::com::sun::star::uno::RuntimeException)
+ {
+ return m_xInputStream;
+ }
+
+
+ private:
+
+ com::sun::star::uno::Reference<com::sun::star::io::XInputStream> m_xInputStream;
+
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/test_ftpurl.cxx b/ucb/source/ucp/ftp/test_ftpurl.cxx
new file mode 100755
index 000000000000..8e623c630aa8
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_ftpurl.cxx
@@ -0,0 +1,284 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include "ftpurl.hxx"
+#include "ftploaderthread.hxx"
+#include "ftphandleprovider.hxx"
+#include "debughelper.hxx"
+#include <rtl/memory.h>
+#include <vector>
+
+#define TESTEVAL \
+ if(number_of_errors) \
+ fprintf(stderr,"errors in %s: %d\n",name,number_of_errors); \
+ return number_of_errors
+
+
+namespace ccsu = com::sun::star::ucb;
+
+
+struct ServerInfo {
+ rtl::OUString host;
+ rtl::OUString port;
+ rtl::OUString username;
+ rtl::OUString password;
+ rtl::OUString account;
+};
+
+
+class FTPHandleProviderI
+ : public ftp::FTPHandleProvider {
+
+public:
+
+ FTPHandleProviderI()
+ : p(new ftp::FTPLoaderThread) {
+ }
+
+ ~FTPHandleProviderI() {
+ delete p;
+ }
+
+ virtual CURL* handle() {
+ return p->handle();
+ }
+
+ bool forHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ rtl::OUString& password,
+ rtl::OUString& account)
+ {
+ for(unsigned int i = 0; i < m_ServerInfo.size(); ++i)
+ if(host == m_ServerInfo[i].host &&
+ port == m_ServerInfo[i].port &&
+ username == m_ServerInfo[i].username ) {
+ password = m_ServerInfo[i].password;
+ account = m_ServerInfo[i].account;
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual bool setHost(const rtl::OUString& host,
+ const rtl::OUString& port,
+ const rtl::OUString& username,
+ const rtl::OUString& password,
+ const rtl::OUString& account)
+ {
+ ServerInfo inf;
+ inf.host = host;
+ inf.port = port;
+ inf.username = username;
+ inf.password = password;
+ inf.account = account;
+
+ bool present(false);
+ for(unsigned int i = 0; i < m_ServerInfo.size(); ++i)
+ if(host == m_ServerInfo[i].host &&
+ port == m_ServerInfo[i].port) {
+ m_ServerInfo[i] = inf;
+ present = true;
+ }
+
+ if(!present)
+ m_ServerInfo.push_back(inf);
+
+ return !present;
+
+ }
+
+
+private:
+
+ std::vector<ServerInfo> m_ServerInfo;
+ ftp::FTPLoaderThread *p;
+};
+
+
+
+// Here are some test for the parsing of an url.
+
+#define TESTURL \
+{ \
+ftp::FTPURL url(rtl::OUString::createFromAscii(ascii),&prov); \
+if(!url.username().equalsAscii(n)) {\
+++number_of_errors; \
+err_msg("wrong username: ",url.username()); \
+}}
+
+int test_ftpurl(void) {
+ const char* name = "test_ftpurl";
+ int number_of_errors = 0;
+
+ FTPHandleProviderI prov;
+ char* ascii,*n,*p;
+
+ ascii = "ftp://abi:psswd@host/eins/../drei", n = "abi", p = "psswd";
+ TESTURL;
+
+ ascii = "ftp://:psswd@host:22/eins/../drei", n = "anonymous", p = "psswd";
+ TESTURL;
+
+ ascii = "ftp://host/bla/../../test/", n = "anonymous", p = "";
+ TESTURL;
+
+ TESTEVAL;
+}
+
+
+int test_ftplist(void) {
+ int number_of_errors = 0;
+ const char* name = "test_ftplist";
+
+ FTPHandleProviderI provider;
+
+ ftp::FTPURL url(
+ rtl::OUString::createFromAscii(
+ "ftp://abi:psswd@abi-1/dir"),
+ &provider);
+
+ std::vector<ftp::FTPDirentry> vec =
+ url.list(com::sun::star::ucb::OpenMode::ALL);
+
+ if(vec.size() != 3)
+ ++number_of_errors;
+
+ if(!(vec[0].m_aName.equalsAscii("dir1") &&
+ vec[1].m_aName.equalsAscii("dir2") &&
+ vec[2].m_aName.equalsAscii("file1")))
+ ++number_of_errors;
+
+ TESTEVAL;
+}
+
+
+#define TESTPARENT \
+ { \
+ ftp::FTPURL url(rtl::OUString::createFromAscii(ascii),&prov); \
+ urlStr = url.parent(); \
+ if(!urlStr.equalsAscii(expect)) \
+ ++number_of_errors; \
+ }
+
+
+int test_ftpparent(void) {
+ int number_of_errors = 0;
+ const char* name = "test_ftpparent";
+ FTPHandleProviderI prov;
+
+ rtl::OUString urlStr;
+ char *ascii,*expect;
+
+ ascii = "ftp://abi:psswd@abi-1/file";
+ expect = "ftp://abi:psswd@abi-1/";
+ TESTPARENT;
+
+ ascii = "ftp://abi:psswd@abi-1/dir/../file";
+ expect = "ftp://abi:psswd@abi-1/";
+ TESTPARENT;
+
+ ascii = "ftp://abi:psswd@abi-1/..";
+ expect = "ftp://abi:psswd@abi-1/../..";
+ TESTPARENT;
+
+ ascii = "ftp://abi:psswd@abi-1/../../dir";
+ expect = "ftp://abi:psswd@abi-1/../..";
+ TESTPARENT;
+
+ ascii = "ftp://abi:psswd@abi-1/";
+ expect = "ftp://abi:psswd@abi-1/..";
+ TESTPARENT;
+
+ TESTEVAL;
+}
+
+
+int test_ftpproperties(void) {
+ int number_of_errors = 0;
+ const char* name = "test_ftpproperties";
+ FTPHandleProviderI provider;
+
+ ftp::FTPURL url(
+ rtl::OUString::createFromAscii(
+ "ftp://abi:psswd@abi-1/file"),
+ &provider);
+
+ ftp::FTPDirentry ade(url.direntry());
+
+ if(!(ade.m_aName.equalsAscii("file") &&
+ ade.isFile()))
+ ++number_of_errors;
+
+ TESTEVAL;
+}
+
+
+int test_ftpopen(void)
+{
+ int number_of_errors = 0;
+ const char* name = "test_ftpopen";
+
+ FTPHandleProviderI provider;
+ ftp::FTPURL url(
+ rtl::OUString::createFromAscii(
+ "ftp://abi:psswd@abi-1/file"),
+ &provider);
+
+ FILE* file = url.open();
+ if(file) {
+ int nbuf,ndest;
+ const int bffsz = 256;
+ char buff[bffsz];
+ char *dest = (char*) malloc(sizeof(char));
+ dest[0] = 0;
+ do {
+ rtl_zeroMemory((void*)buff,bffsz);
+ fread(buff,bffsz-1,1,file);
+ nbuf = strlen(buff);
+ ndest = strlen(dest);
+ dest = (char*)realloc(dest,ndest + nbuf + 1);
+ strncat(dest,buff,nbuf);
+ } while(nbuf == bffsz-1);
+ fclose(file);
+
+ const char* expected = "You are now looking at the filecontent.\n";
+ if(strcmp(expected,dest))
+ ++number_of_errors;
+ free(dest);
+ } else
+ ++number_of_errors;
+
+ TESTEVAL;
+}
+
+
diff --git a/ucb/source/ucp/ftp/test_ftpurl.hxx b/ucb/source/ucp/ftp/test_ftpurl.hxx
new file mode 100755
index 000000000000..641e29fa8087
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_ftpurl.hxx
@@ -0,0 +1,5 @@
+extern int test_ftpurl(void);
+extern int test_ftpproperties(void);
+extern int test_ftpopen(void);
+extern int test_ftplist(void);
+extern int test_ftpparent(void);
diff --git a/ucb/source/ucp/ftp/test_interactionhandler.hxx b/ucb/source/ucp/ftp/test_interactionhandler.hxx
new file mode 100644
index 000000000000..a0ea9f9ff75a
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_interactionhandler.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _TEST_ACTIVEDATASINK_HXX_
+#define _TEST_ACTIVEDATASINK_HXX_
+
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+namespace test_ftp {
+
+
+ class Test_InteractionHandler
+ : public cppu::OWeakObject,
+ public com::sun::star::task::XInteractionHandler
+ {
+ public:
+
+ // XInterface
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ virtual void SAL_CALL acquire( void ) throw();
+
+ virtual void SAL_CALL release( void ) throw();
+
+
+ // XInteractionHandler
+
+ virtual void SAL_CALL
+ handle( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::task::XInteractionRequest >& Request )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+
+ };
+
+}
+
+
+#endif
diff --git a/ucb/source/ucp/ftp/test_multiservicefac.cxx b/ucb/source/ucp/ftp/test_multiservicefac.cxx
new file mode 100644
index 000000000000..3c9570516b99
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_multiservicefac.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include "test_multiservicefac.hxx"
+
+
+using namespace test_ftp;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+
+
+Any SAL_CALL
+Test_MultiServiceFactory::queryInterface(
+ const Type& rType
+)
+ throw(
+ RuntimeException
+ )
+{
+ Any aRet = ::cppu::queryInterface(rType,
+ SAL_STATIC_CAST( XMultiServiceFactory*,
+ this ));
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
+
+}
+
+
+void SAL_CALL Test_MultiServiceFactory::acquire( void ) throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL Test_MultiServiceFactory::release( void ) throw()
+{
+ OWeakObject::release();
+}
+
+ // XMultiServiceFactory
+
+ Reference<
+XInterface > SAL_CALL
+Test_MultiServiceFactory::createInstance(
+ const ::rtl::OUString& aServiceSpecifier
+)
+ throw (
+ Exception,
+ RuntimeException
+ )
+{
+ return Reference<
+ XInterface >(0);
+}
+
+
+Reference<
+XInterface > SAL_CALL
+Test_MultiServiceFactory::createInstanceWithArguments(
+ const ::rtl::OUString& ServiceSpecifier,
+ const Sequence
+ < Any >& Arguments
+)
+ throw (
+ Exception,
+ RuntimeException
+ )
+{
+ return Reference<
+ XInterface >(0);
+}
+
+Sequence< ::rtl::OUString > SAL_CALL
+Test_MultiServiceFactory::getAvailableServiceNames(
+)
+ throw (
+ RuntimeException
+ )
+{
+ return Sequence< ::rtl::OUString >(0);
+}
diff --git a/ucb/source/ucp/ftp/test_multiservicefac.hxx b/ucb/source/ucp/ftp/test_multiservicefac.hxx
new file mode 100644
index 000000000000..874a03f43a1c
--- /dev/null
+++ b/ucb/source/ucp/ftp/test_multiservicefac.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#ifndef _TEST_MULTISERVICEFAC_HXX_
+#define _TEST_MULTISERVICEFAC_HXX_
+
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+
+namespace test_ftp {
+
+ class Test_MultiServiceFactory
+ : public cppu::OWeakObject,
+ public com::sun::star::lang::XMultiServiceFactory
+ {
+ public:
+
+ // XInterface
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& rType )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ virtual void SAL_CALL acquire( void ) throw();
+
+ virtual void SAL_CALL release( void ) throw();
+
+ // XMultiServiceFactory
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface > SAL_CALL
+ createInstance(
+ const ::rtl::OUString& aServiceSpecifier
+ )
+ throw (
+ ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface > SAL_CALL
+ createInstanceWithArguments(
+ const ::rtl::OUString& ServiceSpecifier,
+ const ::com::sun::star::uno::Sequence
+ < ::com::sun::star::uno::Any >& Arguments
+ )
+ throw (
+ ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException
+ );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getAvailableServiceNames(
+ )
+ throw (
+ ::com::sun::star::uno::RuntimeException
+ );
+ };
+
+}
+
+#endif
+
diff --git a/ucb/source/ucp/ftp/ucpftp.xml b/ucb/source/ucp/ftp/ucpftp.xml
new file mode 100644
index 000000000000..041fa1e1abc1
--- /dev/null
+++ b/ucb/source/ucp/ftp/ucpftp.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpftp
+ </module-name>
+
+ <component-description>
+ <author>
+ Andreas Bille
+ </author>
+ <name>
+ com.sun.star.comp.ucb.FTPContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to ftp servers.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.FTPContentProvider
+ </supported-service>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+ <project-build-dependency> curl </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> curl </runtime-module-dependency>
+
+ <type> com.sun.star.beans.UnknownPropertyException </type>
+ <type> com.sun.star.beans.Property </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XInputStream </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.io.XActiveDataStreamer </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkConnectException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkResolveNameException </type>
+ <type> com.sun.star.ucb.InteractiveIOException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.NumberedSortingInfo </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.IOErrorCode </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.ListActionType </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XContentProviderManager </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.CommandInfo </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.Command </type>
+ <type> com.sun.star.ucb.XCommandEnvironment </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentIdentifier </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.util.DateTime </type>
+ <type> com.sun.star.sdbc.XResultSet </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+</module-description>
diff --git a/ucb/source/ucp/gio/gio_content.cxx b/ucb/source/ucp/gio/gio_content.cxx
new file mode 100644
index 000000000000..bf0d16a654af
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_content.cxx
@@ -0,0 +1,1334 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <osl/time.h>
+
+#include <osl/diagnose.h>
+#include <osl/doublecheckedlocking.h>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/interactionrequest.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+
+#include <osl/conditn.hxx>
+
+#include "gio_content.hxx"
+#include "gio_provider.hxx"
+#include "gio_resultset.hxx"
+#include "gio_inputstream.hxx"
+#include "gio_outputstream.hxx"
+#include "gio_mount.hxx"
+
+#include <stdio.h>
+
+using namespace com::sun::star;
+
+namespace gio
+{
+
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier)
+ throw ( ucb::ContentCreationException )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(false)
+{
+#ifdef DEBUG
+ fprintf(stderr, "New Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
+#endif
+}
+
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ sal_Bool bIsFolder)
+ throw ( ucb::ContentCreationException )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_pProvider( pProvider ), mpFile (NULL), mpInfo( NULL ), mbTransient(true)
+{
+#ifdef DEBUG
+ fprintf(stderr, "Create Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ mpInfo = g_file_info_new();
+ g_file_info_set_file_type(mpInfo, bIsFolder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR);
+}
+
+Content::~Content()
+{
+ if (mpInfo) g_object_unref(mpInfo);
+ if (mpFile) g_object_unref(mpFile);
+}
+
+rtl::OUString Content::getParentURL()
+{
+ rtl::OUString sURL;
+ if (GFile* pFile = g_file_get_parent(getGFile()))
+ {
+ char* pPath = g_file_get_uri(pFile);
+ g_object_unref(pFile);
+ sURL = rtl::OUString::createFromAscii(pPath);
+ g_free(pPath);
+ }
+ return sURL;
+}
+
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ //TODO
+ //stick a map from each CommandId to a new GCancellable and propogate
+ //it throughout the g_file_* calls
+}
+
+rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException )
+{
+ return isFolder(uno::Reference< ucb::XCommandEnvironment >())
+ ? rtl::OUString::createFromAscii( GIO_FOLDER_TYPE )
+ : rtl::OUString::createFromAscii( GIO_FILE_TYPE );
+}
+
+#define EXCEPT(aExcept) \
+do { \
+ if (bThrow) throw aExcept;\
+ aRet = uno::makeAny( aExcept );\
+} while(0)
+
+uno::Any convertToException(GError *pError, const uno::Reference< uno::XInterface >& rContext, bool bThrow)
+{
+ uno::Any aRet;
+
+ gint eCode = pError->code;
+ rtl::OUString sMessage(pError->message, strlen(pError->message), RTL_TEXTENCODING_UTF8);
+ g_error_free(pError);
+
+ rtl::OUString sName;
+ rtl::OUString sHost;
+
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= sName;
+
+ switch (eCode)
+ {
+ case G_IO_ERROR_FAILED:
+ { io::IOException aExcept(sMessage, rContext);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NOT_MOUNTED:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING_PATH, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NOT_FOUND:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_EXISTING, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_EXISTS:
+ { ucb::NameClashException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, sName);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_INVALID_ARGUMENT:
+ { lang::IllegalArgumentException aExcept(sMessage, rContext, -1 );
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_PERMISSION_DENIED:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_ACCESS_DENIED, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_IS_DIRECTORY:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NOT_REGULAR_FILE:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_FILE, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NOT_DIRECTORY:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NO_DIRECTORY, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_FILENAME_TOO_LONG:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NAME_TOO_LONG, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_PENDING:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_PENDING, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_CLOSED:
+ case G_IO_ERROR_CANCELLED:
+ case G_IO_ERROR_TOO_MANY_LINKS:
+ case G_IO_ERROR_WRONG_ETAG:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_GENERAL, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NOT_SUPPORTED:
+ case G_IO_ERROR_CANT_CREATE_BACKUP:
+ case G_IO_ERROR_WOULD_MERGE:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_NOT_SUPPORTED, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_NO_SPACE:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_OUT_OF_DISK_SPACE, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_INVALID_FILENAME:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_INVALID_CHARACTER, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_READ_ONLY:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_WRITE_PROTECTED, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_TIMED_OUT:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_DEVICE_NOT_READY, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_WOULD_RECURSE:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_RECURSIVE, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_BUSY:
+ case G_IO_ERROR_WOULD_BLOCK:
+ { ucb::InteractiveAugmentedIOException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, ucb::IOErrorCode_LOCKING_VIOLATION, aArgs);
+ EXCEPT(aExcept); }
+ break;
+ case G_IO_ERROR_HOST_NOT_FOUND:
+ { ucb::InteractiveNetworkResolveNameException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR, sHost);
+ EXCEPT(aExcept);}
+ break;
+ default:
+ case G_IO_ERROR_ALREADY_MOUNTED:
+ case G_IO_ERROR_NOT_EMPTY:
+ case G_IO_ERROR_NOT_SYMBOLIC_LINK:
+ case G_IO_ERROR_NOT_MOUNTABLE_FILE:
+ case G_IO_ERROR_FAILED_HANDLED:
+ { ucb::InteractiveNetworkGeneralException aExcept(sMessage, rContext,
+ task::InteractionClassification_ERROR);
+ EXCEPT(aExcept);}
+ break;
+ }
+ return aRet;
+}
+
+uno::Any Content::mapGIOError( GError *pError )
+{
+ if (!pError)
+ return getBadArgExcept();
+
+ return convertToException(pError, static_cast< cppu::OWeakObject * >(this), false);
+}
+
+uno::Any Content::getBadArgExcept()
+{
+ return uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii( "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ), -1) );
+}
+
+class MountOperation
+{
+ GMainLoop *mpLoop;
+ GMountOperation *mpAuthentication;
+ GError *mpError;
+ static void Completed(GObject *source, GAsyncResult *res, gpointer user_data);
+public:
+ MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv);
+ ~MountOperation();
+ GError *Mount(GFile *pFile);
+};
+
+MountOperation::MountOperation(const uno::Reference< ucb::XCommandEnvironment >& xEnv) : mpError(NULL)
+{
+ mpLoop = g_main_loop_new(NULL, FALSE);
+ mpAuthentication = ooo_mount_operation_new(xEnv);
+}
+
+void MountOperation::Completed(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ MountOperation *pThis = (MountOperation*)user_data;
+ g_file_mount_enclosing_volume_finish(G_FILE(source), res, &(pThis->mpError));
+ g_main_loop_quit(pThis->mpLoop);
+}
+
+GError *MountOperation::Mount(GFile *pFile)
+{
+ g_file_mount_enclosing_volume(pFile, G_MOUNT_MOUNT_NONE, mpAuthentication, NULL, MountOperation::Completed, this);
+ g_main_loop_run(mpLoop);
+ return mpError;
+}
+
+MountOperation::~MountOperation()
+{
+ g_object_unref(mpAuthentication);
+ g_main_loop_unref(mpLoop);
+}
+
+GFileInfo* Content::getGFileInfo(const uno::Reference< ucb::XCommandEnvironment >& xEnv, GError **ppError)
+{
+ /*If we don't have it already, and we're not a "pre-creation" content then query for the info"*/
+ if (!mpInfo && !mbTransient)
+ {
+ if (!(mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError)))
+ {
+ //Try and mount if unmounted
+ if (ppError && (*ppError)->code == G_IO_ERROR_NOT_MOUNTED)
+ {
+ g_error_free(*ppError);
+
+ MountOperation aMounter(xEnv);
+ *ppError = aMounter.Mount(getGFile());
+
+ //No Mount error, reattempt query
+ if (!*ppError)
+ mpInfo = g_file_query_info(getGFile(), "*", G_FILE_QUERY_INFO_NONE, NULL, ppError);
+ }
+ }
+ }
+ return mpInfo;
+}
+
+GFile* Content::getGFile()
+{
+ if (!mpFile)
+ mpFile = g_file_new_for_uri(rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
+ return mpFile;
+}
+
+bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv)
+{
+ GFileInfo *pInfo = getGFileInfo(xEnv);
+ return pInfo && (g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY);
+}
+
+static util::DateTime getDateFromUnix (time_t t)
+{
+ TimeValue tv;
+ tv.Nanosec = 0;
+ tv.Seconds = t;
+ oslDateTime dt;
+
+ if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
+ return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
+ dt.Day, dt.Month, dt.Year);
+ else
+ return util::DateTime();
+}
+
+uno::Reference< sdbc::XRow > Content::getPropertyValuesFromGFileInfo(GFileInfo *pInfo,
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ const uno::Sequence< beans::Property >& rProperties)
+{
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nProps;
+ const beans::Property* pProps;
+
+ nProps = rProperties.getLength();
+ pProps = rProperties.getConstArray();
+
+ for( sal_Int32 n = 0; n < nProps; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE))
+ xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_REGULAR ||
+ g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_UNKNOWN ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) )
+ xRow->appendBoolean( rProp, ( g_file_info_get_file_type( pInfo ) == G_FILE_TYPE_DIRECTORY ));
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
+ {
+ const char *pName = g_file_info_get_display_name(pInfo);
+ xRow->appendString( rProp, rtl::OUString(pName, strlen(pName), RTL_TEXTENCODING_UTF8) );
+ }
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) )
+ xRow->appendBoolean( rProp, !g_file_info_get_attribute_boolean( pInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CREATED ) )
+ xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CREATED)) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED ) )
+ xRow->appendTimestamp( rProp, getDateFromUnix(g_file_info_get_attribute_uint64(pInfo, G_FILE_ATTRIBUTE_TIME_CHANGED)) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE) )
+ xRow->appendLong( rProp, ( g_file_info_get_size( pInfo ) ));
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) )
+ {
+ //What do we use this for ?
+ xRow->appendBoolean( rProp, sal_False );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisc" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT ) )
+ xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsRemoveable" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) )
+ xRow->appendBoolean( rProp, g_file_info_get_attribute_boolean(pInfo, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFloppy" ) ) )
+ {
+ xRow->appendBoolean( rProp, sal_False );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
+ {
+ if( g_file_info_has_attribute( pInfo, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) )
+ xRow->appendBoolean( rProp, ( g_file_info_get_is_hidden ( pInfo ) ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
+ }
+#ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "Looking for unsupported property %s\n",
+ rtl::OUStringToOString(rProp.Name, RTL_TEXTENCODING_UTF8).getStr());
+ }
+#endif
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ GError *pError = NULL;
+ GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
+ if (!pInfo)
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+
+ return getPropertyValuesFromGFileInfo(pInfo, m_xSMgr, xEnv, rProperties);
+}
+
+static lang::IllegalAccessException
+getReadOnlyException( const uno::Reference< uno::XInterface >& rContext )
+{
+ return lang::IllegalAccessException ( rtl::OUString::createFromAscii( "Property is read-only!" ), rContext );
+}
+
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( aURL.getLength() - 1 ) )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) && ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) )
+ {
+ // No further slashes / only a final slash. It's a child!
+ rChildren.push_back( ::gio::Content::ContentRef (static_cast< ::gio::Content * >(xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+sal_Bool Content::exchangeIdentity( const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ if ( mbTransient )
+ {
+ m_xIdentifier = xNewId;
+ return sal_False;
+ }
+
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ // Exchange own identitity.
+ if ( exchange( xNewId ) )
+ {
+ // Process instanciated children...
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier > xOldChildId = xChild->getIdentifier();
+ rtl::OUString aOldChildURL = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL = aOldChildURL.replaceAt(
+ 0, aOldURL.getLength(), xNewId->getContentIdentifier() );
+
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ GError *pError=NULL;
+ GFileInfo *pNewInfo=NULL;
+ GFileInfo *pInfo = getGFileInfo(xEnv, &pError);
+ if (pInfo)
+ pNewInfo = g_file_info_dup(pInfo);
+ else
+ {
+ if (!mbTransient)
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+ else
+ {
+ if (pError)
+ g_error_free(pError);
+ pNewInfo = g_file_info_new();
+ }
+ }
+
+ sal_Int32 nCount = rValues.getLength();
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = -1;
+
+ sal_Int32 nChanged = 0, nTitlePos = -1;
+ const char *newName = NULL;
+ uno::Sequence< beans::PropertyChangeEvent > aChanges(nCount);
+
+ uno::Sequence< uno::Any > aRet( nCount );
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+#ifdef DEBUG
+ g_warning("Set prop '%s'", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
+ }
+ else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ rtl::OUString aNewTitle;
+ if (!( rValue.Value >>= aNewTitle ))
+ {
+ aRet[ n ] <<= beans::IllegalTypeException
+ ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ continue;
+ }
+
+ if ( aNewTitle.getLength() <= 0 )
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException
+ ( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ), -1 );
+ continue;
+
+ }
+
+ rtl::OString sNewTitle = OUStringToOString(aNewTitle, RTL_TEXTENCODING_UTF8);
+ newName = sNewTitle.getStr();
+ const char *oldName = g_file_info_get_name( pInfo);
+
+ if (!newName || !oldName || strcmp(newName, oldName))
+ {
+#ifdef DEBUG
+ g_warning ("Set new name to '%s'", newName);
+#endif
+
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ if (oldName)
+ aEvent.OldValue = uno::makeAny(rtl::OUString(oldName, strlen(oldName), RTL_TEXTENCODING_UTF8));
+ aEvent.NewValue = uno::makeAny(aNewTitle);
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nTitlePos = nChanged++;
+
+ g_file_info_set_name(pNewInfo, newName);
+ }
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "Unknown property %s\n", rtl::OUStringToOString(rValue.Name, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ aRet[ n ] <<= getReadOnlyException( static_cast< cppu::OWeakObject * >(this) );
+ //TODO
+ }
+ }
+
+ if (nChanged)
+ {
+ bool bOk = true;
+ if (!mbTransient)
+ {
+ if ((bOk = doSetFileInfo(pNewInfo)))
+ {
+ for (sal_Int32 i = 0; i < nChanged; ++i)
+ aRet[ i ] <<= getBadArgExcept();
+ }
+ }
+
+ if (bOk)
+ {
+ if (nTitlePos > -1)
+ {
+ rtl::OUString aNewURL = getParentURL();
+ aNewURL += rtl::OUString( newName, strlen(newName), RTL_TEXTENCODING_UTF8 );
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL );
+
+ if (!exchangeIdentity( xNewId ) )
+ {
+ aRet[ nTitlePos ] <<= uno::Exception
+ ( rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if (!mbTransient) //Discard and refetch
+ {
+ g_object_unref(mpInfo);
+ mpInfo = NULL;
+ }
+
+ if (mpInfo)
+ {
+ g_file_info_copy_into(pNewInfo, mpInfo);
+ g_object_unref(pNewInfo);
+ }
+ else
+ mpInfo = pNewInfo;
+
+ if (mpFile) //Discard and refetch
+ {
+ g_object_unref(mpFile);
+ mpFile = NULL;
+ }
+ }
+
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+bool Content::doSetFileInfo(GFileInfo *pNewInfo)
+{
+ g_assert (!mbTransient);
+
+ bool bOk = true;
+ GFile *pFile = getGFile();
+ if(!g_file_set_attributes_from_info(pFile, pNewInfo, G_FILE_QUERY_INFO_NONE, NULL, NULL))
+ bOk = false;
+ return bOk;
+}
+
+const int TRANSFER_BUFFER_SIZE = 65536;
+
+void Content::copyData( uno::Reference< io::XInputStream > xIn,
+ uno::Reference< io::XOutputStream > xOut )
+{
+ uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
+
+ g_return_if_fail( xIn.is() && xOut.is() );
+
+ while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
+ xOut->writeBytes( theData );
+
+ xOut->closeOutput();
+}
+
+sal_Bool Content::feedSink( uno::Reference< uno::XInterface > xSink,
+ const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
+{
+ if ( !xSink.is() )
+ return sal_False;
+
+ uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
+ uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
+
+ if ( !xOut.is() && !xDataSink.is() )
+ return sal_False;
+
+ GError *pError=NULL;
+ GFileInputStream *pStream = g_file_read(getGFile(), NULL, &pError);
+ if (!pStream)
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+
+ uno::Reference< io::XInputStream > xIn = new ::gio::InputStream(pStream);
+ if ( !xIn.is() )
+ return sal_False;
+
+ if ( xOut.is() )
+ copyData( xIn, xOut );
+
+ if ( xDataSink.is() )
+ xDataSink->setInputStream( xIn );
+
+ return sal_True;
+}
+
+uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ bool bIsFolder = isFolder(xEnv);
+
+ if (!g_file_query_exists(getGFile(), NULL))
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
+ uno::Any aErr = uno::makeAny(
+ ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
+ );
+
+ ucbhelper::cancelCommandExecution(aErr, xEnv);
+ }
+
+ uno::Any aRet;
+
+ sal_Bool bOpenFolder = (
+ ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
+ ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
+ ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
+ );
+
+ if ( bOpenFolder && bIsFolder )
+ {
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
+ aRet <<= xSet;
+ }
+ else if ( rOpenCommand.Sink.is() )
+ {
+ if (
+ ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
+ )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny ( ucb::UnsupportedOpenModeException
+ ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( rOpenCommand.Mode ) ) ),
+ xEnv );
+ }
+
+ if ( !feedSink( rOpenCommand.Sink, xEnv ) )
+ {
+ // Note: rOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+#ifdef DEBUG
+ g_warning ("Failed to load data from '%s'",
+ rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
+#endif
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny (ucb::UnsupportedDataSinkException
+ ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
+ rOpenCommand.Sink ) ),
+ xEnv );
+ }
+ }
+ else
+ g_warning ("Open falling through ...");
+ return aRet;
+}
+
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+#ifdef DEBUG
+ fprintf(stderr, "Content::execute %s\n", rtl::OUStringToOString(aCommand.Name, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ uno::Any aRet;
+
+ if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ))
+ {
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ aRet <<= getPropertyValues( Properties, xEnv );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ))
+ aRet <<= getPropertySetInfo( xEnv, sal_False );
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ))
+ aRet <<= getCommandInfo( xEnv, sal_False );
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "open" ) ))
+ {
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ aRet = open( aOpenCommand, xEnv );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "transfer" ) ))
+ {
+ ucb::TransferInfo transferArgs;
+ if ( !( aCommand.Argument >>= transferArgs ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ transfer( transferArgs, xEnv );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ))
+ {
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ aRet <<= setPropertyValues( aProperties, xEnv );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) )
+ && isFolder( xEnv ) )
+ {
+ ucb::ContentInfo arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ aRet <<= createNewContent( arg );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ))
+ {
+ ucb::InsertCommandArgument arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+ insert( arg.Data, arg.ReplaceExisting, xEnv );
+ }
+ else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ))
+ {
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+
+ //If no delete physical, try and trashcan it, if that doesn't work go
+ //ahead and try and delete it anyway
+ if (!bDeletePhysical && !g_file_trash(getGFile(), NULL, NULL))
+ bDeletePhysical = true;
+
+ if (bDeletePhysical)
+ {
+ GError *pError = NULL;
+ if (!g_file_delete( getGFile(), NULL, &pError))
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+ }
+
+ destroy( bDeletePhysical );
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "UNKNOWN COMMAND\n");
+ //TODO
+#endif
+
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny( ucb::UnsupportedCommandException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ }
+
+ return aRet;
+}
+
+void Content::destroy( sal_Bool bDeletePhysical )
+ throw( uno::Exception )
+{
+ uno::Reference< ucb::XContent > xThis = this;
+
+ deleted();
+
+ ::gio::Content::ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical );
+ ++it;
+ }
+}
+
+void Content::insert(const uno::Reference< io::XInputStream > &xInputStream,
+ sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment > &xEnv )
+ throw( uno::Exception )
+{
+ GError *pError = NULL;
+ GFileInfo *pInfo = getGFileInfo(xEnv);
+
+ if ( g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
+ g_file_info_get_file_type(pInfo) == G_FILE_TYPE_DIRECTORY )
+ {
+#ifdef DEBUG
+ g_warning ("Make directory");
+#endif
+ if( !g_file_make_directory( getGFile(), NULL, &pError))
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+ return;
+ }
+
+ if ( !xInputStream.is() )
+ {
+ ucbhelper::cancelCommandExecution( uno::makeAny
+ ( ucb::MissingInputStreamException
+ ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ }
+
+ GFileOutputStream* pOutStream = NULL;
+ if ( bReplaceExisting )
+ {
+ if (!(pOutStream = g_file_replace(getGFile(), NULL, false, G_FILE_CREATE_PRIVATE, NULL, &pError)))
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+ }
+ else
+ {
+ if (!(pOutStream = g_file_create (getGFile(), G_FILE_CREATE_PRIVATE, NULL, &pError)))
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+ }
+
+ uno::Reference < io::XOutputStream > xOutput = new ::gio::OutputStream(pOutStream);
+ copyData( xInputStream, xOutput );
+
+ if (mbTransient)
+ {
+ mbTransient = sal_False;
+ inserted();
+ }
+}
+
+void Content::transfer( const ucb::TransferInfo& aTransferInfo, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ rtl::OUString sDest = m_xIdentifier->getContentIdentifier();
+ if (aTransferInfo.NewTitle.getLength())
+ sDest += aTransferInfo.NewTitle;
+ else
+ sDest += rtl::OUString::createFromAscii(g_file_get_basename(getGFile()));
+
+ GFile *pDest = g_file_new_for_uri(rtl::OUStringToOString(sDest, RTL_TEXTENCODING_UTF8).getStr());
+ GFile *pSource = g_file_new_for_uri(rtl::OUStringToOString(aTransferInfo.SourceURL, RTL_TEXTENCODING_UTF8).getStr());
+
+ gboolean bSuccess = false;
+ GError *pError = NULL;
+ if (aTransferInfo.MoveData)
+ bSuccess = g_file_move(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
+ else
+ bSuccess = g_file_copy(pSource, pDest, G_FILE_COPY_OVERWRITE, NULL, NULL, 0, &pError);
+ g_object_unref(pSource);
+ g_object_unref(pDest);
+ if (!bSuccess)
+ ucbhelper::cancelCommandExecution(mapGIOError(pError), xEnv);
+}
+
+uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv)
+ throw( uno::RuntimeException )
+{
+ if ( isFolder( xEnv ) )
+ {
+ uno::Sequence< ucb::ContentInfo > seq(2);
+
+ // Minimum set of props we really need
+ uno::Sequence< beans::Property > props( 1 );
+ props[0] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
+
+ // file
+ seq[0].Type = rtl::OUString::createFromAscii( GIO_FILE_TYPE );
+ seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
+ ucb::ContentInfoAttribute::KIND_DOCUMENT );
+ seq[0].Properties = props;
+
+ // folder
+ seq[1].Type = rtl::OUString::createFromAscii( GIO_FOLDER_TYPE );
+ seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
+ seq[1].Properties = props;
+
+ return seq;
+ }
+ else
+ {
+ return uno::Sequence< ucb::ContentInfo >();
+ }
+}
+
+uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
+}
+
+uno::Reference< ucb::XContent >
+ SAL_CALL Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ bool create_document;
+ const char *name;
+
+ if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FILE_TYPE ) ) )
+ create_document = true;
+ else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GIO_FOLDER_TYPE ) ) )
+ create_document = false;
+ else
+ {
+#ifdef DEBUG
+ g_warning( "Failed to create new content '%s'", rtl::OUStringToOString(Info.Type,
+ RTL_TEXTENCODING_UTF8).getStr() );
+#endif
+ return uno::Reference< ucb::XContent >();
+ }
+
+#ifdef DEBUG
+ g_warning( "createNewContent (%d)", (int) create_document );
+#endif
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ name = create_document ? "[New_Content]" : "[New_Collection]";
+ aURL += rtl::OUString::createFromAscii( name );
+
+ uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(m_xSMgr, aURL));
+
+ try
+ {
+ return new ::gio::Content( m_xSMgr, m_pProvider, xId, !create_document );
+ } catch ( ucb::ContentCreationException & )
+ {
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
+ {
+ static cppu::OTypeCollection aFolderCollection
+ (CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) );
+ return aFolderCollection.getTypes();
+ }
+ else
+ {
+ static cppu::OTypeCollection aFileCollection
+ (CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+
+ return aFileCollection.getTypes();
+ }
+}
+
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ static const beans::Property aGenericProperties[] =
+ {
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
+ -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
+ -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
+ -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisc" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemoveable" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
+ -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
+ };
+
+ const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
+ return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
+}
+
+uno::Sequence< ucb::CommandInfo > Content::getCommands( const uno::Reference< ucb::XCommandEnvironment > & xEnv)
+{
+ static ucb::CommandInfo aCommandInfoTable[] =
+ {
+ // Required commands
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1, getCppuVoidType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1, getCppuVoidType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
+
+ // Optional standard commands
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1, getCppuBooleanType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
+
+ // Folder Only, omitted if not a folder
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
+ };
+
+ const int nProps = sizeof (aCommandInfoTable) / sizeof (aCommandInfoTable[0]);
+ return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 2);
+}
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+void SAL_CALL Content::acquire() throw()
+{
+ ContentImplHelper::acquire();
+}
+
+void SAL_CALL Content::release() throw()
+{
+ ContentImplHelper::release();
+}
+
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
+}
+
+rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii("com.sun.star.comp.GIOContent" );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii("com.sun.star.ucb.GIOContent" );
+ return aSNS;
+}
+
+}
diff --git a/ucb/source/ucp/gio/gio_content.hxx b/ucb/source/ucp/gio/gio_content.hxx
new file mode 100644
index 000000000000..1c00f8c79d6e
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_content.hxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_CONTENT_HXX
+#define GIO_CONTENT_HXX
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+#include <gio/gio.h>
+
+#include <list>
+
+namespace com { namespace sun { namespace star {
+ namespace beans {
+ struct Property;
+ struct PropertyValue;
+ }
+ namespace sdbc {
+ class XRow;
+ }
+}}}
+namespace ucbhelper
+{
+ class Content;
+}
+
+
+namespace gio
+{
+
+#define GIO_CONTENT_SERVICE_NAME "com.sun.star.ucb.GIOContent"
+
+#define GIO_FILE_TYPE "application/vnd.sun.staroffice.gio-file"
+#define GIO_FOLDER_TYPE "application/vnd.sun.staroffice.gio-folder"
+
+com::sun::star::uno::Any convertToException(GError *pError,
+ const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& rContext, bool bThrow=true);
+
+class ContentProvider;
+class ContentProperties;
+class Content : public ::ucbhelper::ContentImplHelper, public com::sun::star::ucb::XContentCreator
+{
+private:
+ ContentProvider *m_pProvider;
+ GFile* mpFile;
+ GFileInfo *mpInfo;
+ bool mbTransient;
+
+ GFileInfo *getGFileInfo(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv,
+ GError **ppError=NULL);
+ bool isFolder(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv);
+
+ com::sun::star::uno::Any mapGIOError( GError *error );
+ com::sun::star::uno::Any getBadArgExcept();
+
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ getPropertyValues(
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& rProperties,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv );
+private:
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+
+ void queryChildren( ContentRefList& rChildren );
+
+ bool doSetFileInfo ( GFileInfo *pNewInfo );
+
+ com::sun::star::uno::Any open(const com::sun::star::ucb::OpenCommandArgument2 & rArg,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( com::sun::star::uno::Exception );
+
+ void transfer( const com::sun::star::ucb::TransferInfo& rTransferInfo,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( com::sun::star::uno::Exception );
+
+ void insert( const com::sun::star::uno::Reference< com::sun::star::io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( com::sun::star::uno::Exception );
+
+ void destroy( sal_Bool bDeletePhysical ) throw( com::sun::star::uno::Exception );
+
+ void copyData( com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xIn,
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > xOut );
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any >
+ setPropertyValues( const com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyValue >& rValues,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+ sal_Bool feedSink( com::sun::star::uno::Reference< com::sun::star::uno::XInterface> aSink,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ createInputStream(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( com::sun::star::uno::Exception );
+
+ sal_Bool exchangeIdentity(const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xNewId);
+
+public:
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr, ContentProvider *pProvider,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Identifier)
+ throw ( com::sun::star::ucb::ContentCreationException );
+
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr, ContentProvider *pProvider,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Identifier,
+ sal_Bool bIsFolder)
+ throw ( com::sun::star::ucb::ContentCreationException );
+
+ virtual ~Content();
+
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > getPropertyValuesFromGFileInfo(
+ GFileInfo *pInfo, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
+ const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& rProperties);
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+
+ virtual ::rtl::OUString getParentURL();
+
+ XINTERFACE_DECL()
+
+ XTYPEPROVIDER_DECL()
+
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception, com::sun::star::ucb::CommandAbortedException, com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ SAL_CALL queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ SAL_CALL createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ queryCreatableContentsInfo(
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv)
+ throw( com::sun::star::uno::RuntimeException );
+
+ GFile* getGFile();
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/gio/gio_datasupplier.cxx b/ucb/source/ucp/gio/gio_datasupplier.cxx
new file mode 100644
index 000000000000..22cd4afa08fe
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_datasupplier.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <vector>
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+
+#include <com/sun/star/ucb/OpenMode.hpp>
+
+#include "gio_datasupplier.hxx"
+#include "gio_content.hxx"
+#include "gio_provider.hxx"
+
+#include <stdio.h>
+
+using namespace com::sun::star;
+
+using namespace gio;
+
+namespace gio
+{
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const uno::Reference< ::gio::Content >& rContent, sal_Int32 nOpenMode )
+ : mxContent(rContent), m_xSMgr(rxSMgr), mnOpenMode(nOpenMode), mbCountFinal(false)
+{
+}
+
+bool DataSupplier::getData()
+{
+ if (mbCountFinal)
+ return true;
+
+ GFile *pFile = mxContent->getGFile();
+
+ GFileEnumerator* pEnumerator = g_file_enumerate_children(pFile, "*",
+ G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+ if (!pEnumerator)
+ return sal_False;
+
+ GFileInfo *pInfo = NULL;
+ while ((pInfo = g_file_enumerator_next_file (pEnumerator, NULL, NULL)))
+ {
+ switch ( mnOpenMode )
+ {
+ case ucb::OpenMode::FOLDERS:
+ if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_DIRECTORY)
+ continue;
+ break;
+ case ucb::OpenMode::DOCUMENTS:
+ if (g_file_info_get_file_type(pInfo) != G_FILE_TYPE_REGULAR)
+ continue;
+ break;
+ case ucb::OpenMode::ALL:
+ default:
+ break;
+ }
+
+ maResults.push_back( new ResultListEntry( pInfo ) );
+ g_object_unref(pInfo);
+ }
+
+ mbCountFinal = sal_True;
+
+ g_file_enumerator_close(pEnumerator, NULL, NULL);
+ return true;
+}
+
+DataSupplier::~DataSupplier()
+{
+ ResultList::const_iterator it = maResults.begin();
+ ResultList::const_iterator end = maResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ if ( nIndex < maResults.size() )
+ {
+ ::rtl::OUString aId = maResults[ nIndex ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ GFile *pFile = mxContent->getGFile();
+ char* parent = g_file_get_uri(pFile);
+ rtl::OUString aId = rtl::OUString::createFromAscii( parent );
+ g_free(parent);
+
+ char *escaped_name =
+ g_uri_escape_string( g_file_info_get_name(maResults[ nIndex ]->pInfo) , NULL, false);
+
+ if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ aId += rtl::OUString::createFromAscii( escaped_name );
+
+ g_free( escaped_name );
+
+ maResults[ nIndex ]->aId = aId;
+ return aId;
+
+ return aId;
+ }
+
+ return ::rtl::OUString();
+}
+
+uno::Reference< ucb::XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ if ( nIndex < maResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId = maResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ ::rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aId );
+ maResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+uno::Reference< ucb::XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ if ( nIndex < maResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent = maResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent = mxContent->getProvider()->queryContent( xId );
+ maResults[ nIndex ]->xContent = xContent;
+ return xContent;
+ }
+ catch ( ucb::IllegalIdentifierException& )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ if ( maResults.size() > nIndex ) // Result already present.
+ return sal_True;
+
+ if ( getData() && maResults.size() > nIndex )
+ return sal_True;
+
+ return sal_False;
+}
+
+sal_uInt32 DataSupplier::totalCount()
+{
+ getData();
+ return maResults.size();
+}
+
+sal_uInt32 DataSupplier::currentCount()
+{
+ return maResults.size();
+}
+
+sal_Bool DataSupplier::isCountFinal()
+{
+ return mbCountFinal;
+}
+
+uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ if ( nIndex < maResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow = maResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ uno::Reference< ucb::XContent > xContent( queryContent( nIndex ) );
+ if ( xContent.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XCommandProcessor > xCmdProc(
+ xContent, uno::UNO_QUERY_THROW );
+ sal_Int32 nCmdId( xCmdProc->createCommandIdentifier() );
+ ucb::Command aCmd;
+ aCmd.Name = rtl::OUString::createFromAscii( "getPropertyValues" );
+ aCmd.Handle = -1;
+ aCmd.Argument <<= getResultSet()->getProperties();
+ uno::Any aResult( xCmdProc->execute(
+ aCmd, nCmdId, getResultSet()->getEnvironment() ) );
+ uno::Reference< sdbc::XRow > xRow;
+ if ( aResult >>= xRow )
+ {
+ maResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+ }
+ }
+ return uno::Reference< sdbc::XRow >();
+}
+
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ if ( nIndex < maResults.size() )
+ maResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+void DataSupplier::close()
+{
+}
+
+void DataSupplier::validate() throw( ucb::ResultSetException )
+{
+}
+
+}
diff --git a/ucb/source/ucp/gio/gio_datasupplier.hxx b/ucb/source/ucp/gio/gio_datasupplier.hxx
new file mode 100644
index 000000000000..b39d7c913ffa
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_datasupplier.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_DATASUPPLIER_HXX
+#define GIO_DATASUPPLIER_HXX
+
+#include <ucbhelper/resultset.hxx>
+#include "gio_content.hxx"
+#include <vector>
+
+namespace gio
+{
+
+class Content;
+
+struct ResultListEntry
+{
+ ::rtl::OUString aId;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > xId;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XContent > xContent;
+ com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > xRow;
+ GFileInfo *pInfo;
+
+ ResultListEntry( GFileInfo *pInInfo ) : pInfo(pInInfo)
+ {
+ g_object_ref( pInfo );
+ }
+
+ ~ResultListEntry()
+ {
+ g_object_unref( pInfo );
+ }
+};
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+class DataSupplier : public ucbhelper::ResultSetDataSupplier
+{
+private:
+ com::sun::star::uno::Reference< ::gio::Content > mxContent;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ sal_Int32 mnOpenMode;
+ bool mbCountFinal;
+ bool getData();
+ ResultList maResults;
+public:
+ DataSupplier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const com::sun::star::uno::Reference< Content >& rContent, sal_Int32 nOpenMode );
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/gio/gio_inputstream.cxx b/ucb/source/ucp/gio/gio_inputstream.cxx
new file mode 100644
index 000000000000..b5295a71bcd2
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_inputstream.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/memory.h>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <string.h>
+
+#include "gio_inputstream.hxx"
+#include "gio_content.hxx"
+
+using namespace com::sun::star;
+
+namespace gio
+{
+
+InputStream::InputStream(GFileInputStream *pStream) : Seekable(G_SEEKABLE(pStream)), mpStream(pStream)
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+}
+
+InputStream::~InputStream( void )
+{
+ closeInput();
+}
+
+sal_Int32 SAL_CALL InputStream::available()
+ throw( io::NotConnectedException, io::IOException, uno::RuntimeException )
+{
+ return 0;
+}
+
+void SAL_CALL InputStream::closeInput()
+ throw( io::NotConnectedException, io::IOException, uno::RuntimeException )
+{
+ if (mpStream)
+ g_input_stream_close(G_INPUT_STREAM(mpStream), NULL, NULL);
+}
+
+void SAL_CALL InputStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ if (!g_seekable_can_seek(G_SEEKABLE(mpStream)))
+ throw io::IOException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Seek unsupported")),
+ static_cast< cppu::OWeakObject * >(this));
+
+ GError *pError=NULL;
+ if (!g_seekable_seek(G_SEEKABLE(mpStream), nBytesToSkip, G_SEEK_CUR, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+}
+
+sal_Int32 SAL_CALL InputStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ try
+ {
+ aData.realloc( nBytesToRead );
+ }
+ catch ( const uno::Exception &e )
+ {
+ throw io::BufferSizeExceededException();
+ }
+
+ gsize nBytesRead = 0;
+ GError *pError=NULL;
+ if (!g_input_stream_read_all(G_INPUT_STREAM(mpStream), aData.getArray(), nBytesToRead, &nBytesRead, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+ aData.realloc(nBytesRead);
+ return nBytesRead;
+}
+
+sal_Int32 SAL_CALL InputStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException )
+{
+ return readBytes(aData, nMaxBytesToRead);
+}
+
+uno::Any InputStream::queryInterface( const uno::Type &type ) throw( uno::RuntimeException )
+{
+ uno::Any aRet = ::cppu::queryInterface ( type,
+ static_cast< XInputStream * >( this ) );
+
+ return aRet.hasValue() ? aRet : Seekable::queryInterface( type );
+}
+
+}
diff --git a/ucb/source/ucp/gio/gio_inputstream.hxx b/ucb/source/ucp/gio/gio_inputstream.hxx
new file mode 100644
index 000000000000..467a14a9a94c
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_inputstream.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_INPUTSTREAM_HXX
+#define GIO_INPUTSTREAM_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include "gio_seekable.hxx"
+
+namespace gio
+{
+
+class InputStream :
+ public ::com::sun::star::io::XInputStream,
+ public Seekable
+{
+private:
+ GFileInputStream *mpStream;
+
+public:
+ InputStream ( GFileInputStream *pStream );
+ virtual ~InputStream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire( void ) throw () { OWeakObject::acquire(); }
+ virtual void SAL_CALL release( void ) throw() { OWeakObject::release(); }
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL available( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL closeInput( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+} // namespace gio
+#endif
diff --git a/ucb/source/ucp/gio/gio_mount.cxx b/ucb/source/ucp/gio/gio_mount.cxx
new file mode 100644
index 000000000000..a32457c81a75
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_mount.cxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "gio_mount.hxx"
+#include <ucbhelper/simpleauthenticationrequest.hxx>
+#include <stdio.h>
+#include <string.h>
+
+G_DEFINE_TYPE (OOoMountOperation, ooo_mount_operation, G_TYPE_MOUNT_OPERATION);
+
+static void ooo_mount_operation_ask_password (GMountOperation *op,
+ const char *message, const char *default_user, const char *default_domain,
+ GAskPasswordFlags flags);
+
+static void ooo_mount_operation_init (OOoMountOperation *op)
+{
+ op->m_pPrevPassword = NULL;
+ op->m_pPrevUsername = NULL;
+}
+
+static void ooo_mount_operation_finalize (GObject *object)
+{
+ OOoMountOperation *mount_op = OOO_MOUNT_OPERATION (object);
+ if (mount_op->m_pPrevUsername)
+ free(mount_op->m_pPrevUsername);
+ if (mount_op->m_pPrevPassword)
+ free(mount_op->m_pPrevPassword);
+
+ G_OBJECT_CLASS (ooo_mount_operation_parent_class)->finalize (object);
+}
+
+static void ooo_mount_operation_class_init (OOoMountOperationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = ooo_mount_operation_finalize;
+
+ GMountOperationClass *mount_op_class = G_MOUNT_OPERATION_CLASS (klass);
+ mount_op_class->ask_password = ooo_mount_operation_ask_password;
+}
+
+using namespace com::sun::star;
+
+static void ooo_mount_operation_ask_password (GMountOperation *op,
+ const char * /*message*/, const char *default_user,
+ const char *default_domain, GAskPasswordFlags flags)
+{
+ uno::Reference< task::XInteractionHandler > xIH;
+
+ OOoMountOperation *pThis = (OOoMountOperation*)op;
+
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > &xEnv = *(pThis->pEnv);
+
+ if (xEnv.is())
+ xIH = xEnv->getInteractionHandler();
+
+ if (!xIH.is())
+ {
+ g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
+ return;
+ }
+
+ ::rtl::OUString aHostName, aDomain, aUserName, aPassword;
+
+ ucbhelper::SimpleAuthenticationRequest::EntityType eUserName =
+ (flags & G_ASK_PASSWORD_NEED_USERNAME)
+ ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
+ : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
+
+ if (default_user)
+ aUserName = rtl::OUString(default_user, strlen(default_user), RTL_TEXTENCODING_UTF8);
+
+ ucbhelper::SimpleAuthenticationRequest::EntityType ePassword =
+ (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
+ : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
+
+ rtl::OUString aPrevPassword, aPrevUsername;
+ if (pThis->m_pPrevUsername)
+ aPrevUsername = rtl::OUString(pThis->m_pPrevUsername, strlen(pThis->m_pPrevUsername), RTL_TEXTENCODING_UTF8);
+ if (pThis->m_pPrevPassword)
+ aPrevPassword = rtl::OUString(pThis->m_pPrevPassword, strlen(pThis->m_pPrevPassword), RTL_TEXTENCODING_UTF8);
+
+ //The damn dialog is stupidly broken, so do like webdav, i.e. "#102871#"
+ if ( aUserName.getLength() == 0 )
+ aUserName = aPrevUsername;
+
+ if ( aPassword.getLength() == 0 )
+ aPassword = aPrevPassword;
+
+ ucbhelper::SimpleAuthenticationRequest::EntityType eDomain =
+ (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+ ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY
+ : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
+
+ if (default_domain)
+ aDomain = rtl::OUString(default_domain, strlen(default_domain), RTL_TEXTENCODING_UTF8);
+
+ uno::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
+ = new ucbhelper::SimpleAuthenticationRequest (rtl::OUString() /* FIXME: provide URL here */, aHostName, eDomain, aDomain, eUserName, aUserName, ePassword, aPassword);
+
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
+
+ if ( !xSelection.is() )
+ {
+ g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
+ return;
+ }
+
+ uno::Reference< task::XInteractionAbort > xAbort(xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
+ return;
+ }
+
+ const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp = xRequest->getAuthenticationSupplier();
+ aUserName = xSupp->getUserName();
+ aPassword = xSupp->getPassword();
+
+ if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+ g_mount_operation_set_username(op, rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr());
+
+ if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ g_mount_operation_set_password(op, rtl::OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr());
+
+ if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+ g_mount_operation_set_domain(op, rtl::OUStringToOString(xSupp->getRealm(), RTL_TEXTENCODING_UTF8).getStr());
+
+ switch (xSupp->getRememberPasswordMode())
+ {
+ default:
+ case ucb::RememberAuthentication_NO:
+ g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_NEVER);
+ break;
+ case ucb::RememberAuthentication_SESSION:
+ g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_FOR_SESSION);
+ break;
+ case ucb::RememberAuthentication_PERSISTENT:
+ g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_PERMANENTLY);
+ break;
+ }
+
+ if (pThis->m_pPrevPassword)
+ free(pThis->m_pPrevPassword);
+ pThis->m_pPrevPassword = strdup(rtl::OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr());
+ if (pThis->m_pPrevUsername)
+ free(pThis->m_pPrevUsername);
+ pThis->m_pPrevUsername = strdup(rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr());
+ g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
+}
+
+GMountOperation *ooo_mount_operation_new(const uno::Reference< ucb::XCommandEnvironment >& rEnv)
+{
+ OOoMountOperation *pRet = (OOoMountOperation*)g_object_new (OOO_TYPE_MOUNT_OPERATION, NULL);
+ pRet->pEnv = &rEnv;
+ return (GMountOperation*)pRet;
+}
diff --git a/ucb/source/ucp/gio/gio_mount.hxx b/ucb/source/ucp/gio/gio_mount.hxx
new file mode 100644
index 000000000000..e88ef01651a3
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_mount.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_MOUNT_HXX
+#define GIO_MOUNT_HXX
+
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define OOO_TYPE_MOUNT_OPERATION (ooo_mount_operation_get_type ())
+#define OOO_MOUNT_OPERATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperation))
+#define OOO_MOUNT_OPERATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))
+#define OOO_IS_MOUNT_OPERATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OOO_TYPE_MOUNT_OPERATION))
+#define OOO_IS_MOUNT_OPERATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OOO_TYPE_MOUNT_OPERATION))
+#define OOO_MOUNT_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OOO_TYPE_MOUNT_OPERATION, OOoMountOperationClass))
+
+typedef struct OOoMountOperation OOoMountOperation;
+typedef struct OOoMountOperationClass OOoMountOperationClass;
+typedef struct OOoMountOperationPrivate OOoMountOperationPrivate;
+
+struct OOoMountOperation
+{
+ GMountOperation parent_instance;
+
+ const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > *pEnv;
+ char *m_pPrevUsername;
+ char *m_pPrevPassword;
+};
+
+struct OOoMountOperationClass
+{
+ GMountOperationClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+
+GType ooo_mount_operation_get_type (void);
+GMountOperation *ooo_mount_operation_new(const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& rEnv);
+
+G_END_DECLS
+#endif
diff --git a/ucb/source/ucp/gio/gio_outputstream.cxx b/ucb/source/ucp/gio/gio_outputstream.cxx
new file mode 100644
index 000000000000..ddd0d19e7f2b
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_outputstream.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/memory.h>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <string.h>
+
+#include "gio_outputstream.hxx"
+#include "gio_content.hxx"
+
+using namespace com::sun::star;
+
+namespace gio
+{
+
+OutputStream::OutputStream(GFileOutputStream *pStream) : Seekable(G_SEEKABLE(pStream)), mpStream(pStream)
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+}
+
+OutputStream::~OutputStream( void )
+{
+ closeOutput();
+}
+
+void SAL_CALL OutputStream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& rData )
+ throw( io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ GError *pError=NULL;
+ if (!g_output_stream_write_all(G_OUTPUT_STREAM(mpStream), rData.getConstArray(), rData.getLength(), NULL, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+}
+
+void SAL_CALL OutputStream::flush( void )
+ throw( io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ GError *pError=NULL;
+ if (!g_output_stream_flush(G_OUTPUT_STREAM(mpStream), NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+}
+
+void SAL_CALL OutputStream::closeOutput( void )
+ throw( io::NotConnectedException, io::IOException,
+ uno::RuntimeException )
+{
+ if (mpStream)
+ g_output_stream_close(G_OUTPUT_STREAM(mpStream), NULL, NULL);
+}
+
+uno::Any OutputStream::queryInterface( const uno::Type &type ) throw( uno::RuntimeException )
+{
+ uno::Any aRet = ::cppu::queryInterface ( type,
+ static_cast< XOutputStream * >( this ) );
+
+ return aRet.hasValue() ? aRet : Seekable::queryInterface( type );
+}
+
+}
diff --git a/ucb/source/ucp/gio/gio_outputstream.hxx b/ucb/source/ucp/gio/gio_outputstream.hxx
new file mode 100644
index 000000000000..d1328fc58e3e
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_outputstream.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_OUTPUTSTREAM_HXX
+#define GIO_OUTPUTSTREAM_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include "gio_seekable.hxx"
+
+namespace gio
+{
+
+class OutputStream :
+ public ::com::sun::star::io::XOutputStream,
+ public Seekable
+{
+private:
+ GFileOutputStream *mpStream;
+
+public:
+ OutputStream ( GFileOutputStream *pStream );
+ virtual ~OutputStream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire( void ) throw () { OWeakObject::acquire(); }
+ virtual void SAL_CALL release( void ) throw() { OWeakObject::release(); }
+
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL flush( void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+
+ virtual void SAL_CALL closeOutput( void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+};
+
+} // namespace gio
+#endif
diff --git a/ucb/source/ucp/gio/gio_provider.cxx b/ucb/source/ucp/gio/gio_provider.cxx
new file mode 100644
index 000000000000..b39bc4462bbe
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_provider.cxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/contenthelper.hxx>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include "gio_provider.hxx"
+#include "gio_content.hxx"
+
+#include <stdio.h>
+
+using namespace com::sun::star;
+
+namespace gio
+{
+uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ContentProvider::queryContent(
+ const uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ uno::RuntimeException )
+{
+#ifdef DEBUG
+ fprintf(stderr, "QueryContent: '%s'",
+ (const sal_Char *)rtl::OUStringToOString
+ (Identifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8));
+#endif
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent = queryExistingContent( Identifier ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ try
+ {
+ xContent = new ::gio::Content(m_xSMgr, this, Identifier);
+ }
+ catch ( com::sun::star::ucb::ContentCreationException const & )
+ {
+ throw com::sun::star::ucb::IllegalIdentifierException();
+ }
+
+ if ( !xContent->getIdentifier().is() )
+ throw com::sun::star::ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rSMgr )
+{
+}
+
+ContentProvider::~ContentProvider()
+{
+}
+
+XINTERFACE_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ com::sun::star::ucb::XContentProvider );
+
+XTYPEPROVIDER_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ com::sun::star::ucb::XContentProvider );
+
+XSERVICEINFO_IMPL_1( ContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.GIOContentProvider" ),
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GIOContentProvider" ) );
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+}
+
+static sal_Bool writeInfo( void *pRegistryKey,
+ const rtl::OUString &rImplementationName, uno::Sequence< rtl::OUString > const &rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * > (pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {}
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char **ppEnvTypeName, uno_Environment **)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void *pRegistryKey )
+{
+ return pRegistryKey &&
+ writeInfo( pRegistryKey,
+ ::gio::ContentProvider::getImplementationName_Static(),
+ ::gio::ContentProvider::getSupportedServiceNames_Static() );
+}
+
+extern "C" void * SAL_CALL component_getFactory( const sal_Char *pImplName,
+ void *pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr
+ (reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ g_type_init();
+
+ if ( !::gio::ContentProvider::getImplementationName_Static().compareToAscii( pImplName ) )
+ xFactory = ::gio::ContentProvider::createServiceFactory( xSMgr );
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
diff --git a/ucb/source/ucp/gio/gio_provider.hxx b/ucb/source/ucp/gio/gio_provider.hxx
new file mode 100644
index 000000000000..4fa2fba1807d
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_provider.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_PROVIDER_HXX
+#define GIO_PROVIDER_HXX
+
+#include <com/sun/star/beans/Property.hpp>
+#include <ucbhelper/providerhelper.hxx>
+
+#define GIO_CONTENT_PROVIDER_SERVICE_NAME "com.sun.star.ucb.GIOContentProvider"
+
+namespace gio
+{
+
+class ContentProvider : public ::ucbhelper::ContentProviderImplHelper
+{
+public:
+ ContentProvider( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/gio/gio_resultset.cxx b/ucb/source/ucp/gio/gio_resultset.cxx
new file mode 100644
index 000000000000..68c3654915f6
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_resultset.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "gio_datasupplier.hxx"
+#include "gio_resultset.hxx"
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+using namespace gio;
+
+DynamicResultSet::DynamicResultSet(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const Reference< Content >& rxContent,
+ const OpenCommandArgument2& rCommand,
+ const Reference< XCommandEnvironment >& rxEnv )
+ : ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv )
+{
+}
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1 = new ::ucbhelper::ResultSet(
+ m_xSMgr, m_aCommand.Properties,
+ new DataSupplier( m_xSMgr, m_xContent, m_aCommand.Mode ), m_xEnv );
+}
+
+void DynamicResultSet::initDynamic()
+{
+ initStatic();
+ m_xResultSet2 = m_xResultSet1;
+}
diff --git a/ucb/source/ucp/gio/gio_resultset.hxx b/ucb/source/ucp/gio/gio_resultset.hxx
new file mode 100644
index 000000000000..620c58cf7edb
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_resultset.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_RESULTSET_HXX
+#define GIO_RESULTSET_HXX
+
+#include <ucbhelper/resultsethelper.hxx>
+#include "gio_content.hxx"
+
+namespace gio
+{
+
+ class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+ {
+ com::sun::star::uno::Reference< Content > m_xContent;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+ private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+ public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const com::sun::star::uno::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+ };
+}
+
+#endif
diff --git a/ucb/source/ucp/gio/gio_seekable.cxx b/ucb/source/ucp/gio/gio_seekable.cxx
new file mode 100644
index 000000000000..3bfce6b9b6b9
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_seekable.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/memory.h>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <string.h>
+
+#include "gio_seekable.hxx"
+#include "gio_content.hxx"
+
+using namespace com::sun::star;
+
+namespace gio
+{
+
+Seekable::Seekable(GSeekable *pStream) : mpStream(pStream)
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+}
+
+Seekable::~Seekable( void )
+{
+}
+
+void SAL_CALL Seekable::truncate( void )
+ throw( io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ if (!g_seekable_can_truncate(mpStream))
+ throw io::IOException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Truncate unsupported")),
+ static_cast< cppu::OWeakObject * >(this));
+
+ GError *pError=NULL;
+ if (!g_seekable_truncate(mpStream, 0, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+}
+
+void SAL_CALL Seekable::seek( sal_Int64 location )
+ throw( lang::IllegalArgumentException, io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ if (!g_seekable_can_seek(mpStream))
+ throw io::IOException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Seek unsupported")),
+ static_cast< cppu::OWeakObject * >(this));
+
+ GError *pError=NULL;
+ if (!g_seekable_seek(mpStream, location, G_SEEK_SET, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+}
+
+sal_Int64 SAL_CALL Seekable::getPosition() throw( io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ return g_seekable_tell(mpStream);
+}
+
+sal_Int64 SAL_CALL Seekable::getLength() throw( io::IOException, uno::RuntimeException )
+{
+ if (!mpStream)
+ throw io::NotConnectedException();
+
+ bool bOk = false;
+ sal_uInt64 nSize = 0;
+
+ GFileInfo* pInfo = G_IS_FILE_INPUT_STREAM(mpStream)
+ ? g_file_input_stream_query_info(G_FILE_INPUT_STREAM(mpStream), const_cast<char*>(G_FILE_ATTRIBUTE_STANDARD_SIZE), NULL, NULL)
+ : g_file_output_stream_query_info(G_FILE_OUTPUT_STREAM(mpStream), const_cast<char*>(G_FILE_ATTRIBUTE_STANDARD_SIZE), NULL, NULL);
+
+ if (pInfo)
+ {
+ if (g_file_info_has_attribute(pInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE))
+ {
+ nSize = g_file_info_get_size(pInfo);
+ bOk = true;
+ }
+ g_object_unref(pInfo);
+ }
+
+ if (!bOk)
+ {
+ GError *pError=NULL;
+ sal_Int64 nCurr = getPosition();
+ if (!g_seekable_seek(mpStream, 0, G_SEEK_END, NULL, &pError))
+ convertToException(pError, static_cast< cppu::OWeakObject * >(this));
+ nSize = getPosition();
+ seek(nCurr);
+ bOk = true;
+ }
+
+ if (!bOk)
+ throw io::IOException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Getting size unsupported")),
+ static_cast< cppu::OWeakObject * >(this));
+
+ return nSize;
+}
+
+uno::Any Seekable::queryInterface( const uno::Type &type ) throw( uno::RuntimeException )
+{
+ uno::Any aRet = ::cppu::queryInterface ( type,
+ static_cast< XSeekable * >( this ) );
+
+ if (!aRet.hasValue() && g_seekable_can_truncate(mpStream))
+ aRet = ::cppu::queryInterface ( type, static_cast< XTruncate * >( this ) );
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
+}
+
+}
diff --git a/ucb/source/ucp/gio/gio_seekable.hxx b/ucb/source/ucp/gio/gio_seekable.hxx
new file mode 100644
index 000000000000..43324b0651a1
--- /dev/null
+++ b/ucb/source/ucp/gio/gio_seekable.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef GIO_SEEKABLE_HXX
+#define GIO_SEEKABLE_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include <gio/gio.h>
+
+namespace gio
+{
+
+class Seekable : public ::com::sun::star::io::XTruncate,
+ public ::com::sun::star::io::XSeekable,
+ public ::cppu::OWeakObject
+{
+private:
+ GSeekable *mpStream;
+public:
+ Seekable( GSeekable *pStream );
+ virtual ~Seekable();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire( void ) throw () { OWeakObject::acquire(); }
+ virtual void SAL_CALL release( void ) throw() { OWeakObject::release(); }
+
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getPosition()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XTruncate
+ virtual void SAL_CALL truncate( void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+};
+
+} // namespace gio
+#endif
diff --git a/ucb/source/ucp/gio/makefile.mk b/ucb/source/ucp/gio/makefile.mk
new file mode 100644
index 000000000000..86b32fbc0739
--- /dev/null
+++ b/ucb/source/ucp/gio/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+# Version
+UCPGIO_MAJOR=1
+TARGET=ucpgio
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+UNIXTEXT=$(MISC)/$(TARGET)-ucd.txt
+
+.IF "$(ENABLE_GIO)"!=""
+COMPILER_WARN_ALL=TRUE
+PKGCONFIG_MODULES=gio-2.0
+.INCLUDE: pkg_config.mk
+
+.IF "$(OS)" == "SOLARIS"
+LINKFLAGS+=-z nodefs
+.ENDIF # "$(OS)" == "SOLARIS"
+
+# no "lib" prefix
+DLLPRE =
+
+SLOFILES=$(SLO)$/gio_provider.obj\
+ $(SLO)$/gio_content.obj\
+ $(SLO)$/gio_resultset.obj\
+ $(SLO)$/gio_datasupplier.obj\
+ $(SLO)$/gio_seekable.obj\
+ $(SLO)$/gio_inputstream.obj\
+ $(SLO)$/gio_outputstream.obj\
+ $(SLO)$/gio_mount.obj
+
+SHL1TARGET=$(TARGET)$(UCPGIO_MAJOR).uno
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1IMPLIB=i$(TARGET)
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1STDLIBS+=$(PKGCONFIG_LIBS)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+.ENDIF # "$(ENABLE_GIO)"!=""
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
diff --git a/ucb/source/ucp/gio/ucpgio-ucd.txt b/ucb/source/ucp/gio/ucpgio-ucd.txt
new file mode 100644
index 000000000000..ce7657fa73e3
--- /dev/null
+++ b/ucb/source/ucp/gio/ucpgio-ucd.txt
@@ -0,0 +1,6 @@
+[ComponentDescriptor]
+ImplementationName=com.sun.star.comp.GIOContentProvider
+ComponentName=ucpgio1.uno.so
+LoaderName=com.sun.star.loader.SharedLibrary
+[SupportedServices]
+com.sun.star.ucb.GIOContentProvider
diff --git a/ucb/source/ucp/gio/ucpgio.xml b/ucb/source/ucp/gio/ucpgio.xml
new file mode 100644
index 000000000000..20bfe43e5a6f
--- /dev/null
+++ b/ucb/source/ucp/gio/ucpgio.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpgio
+ </module-name>
+
+ <component-description>
+ <author>
+ Caolán McNamara &;amp; Jan Navrati
+ </author>
+ <name>
+ com.sun.star.comp.ucb.GIOContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to contents stored on an GIO
+ location.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.GIOContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationAccess
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> external </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XInputStream </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentCreationException </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.PostCommandArgument2 </type>
+ <type> com.sun.star.ucb.RememberAuthentication </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.XCommandEnvironment </type>
+ <type> com.sun.star.ucb.UnsupportedCommandException </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandInfoChangeNotifier </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.util.DateTime </type>
+</module-description>
diff --git a/ucb/source/ucp/gvfs/gvfs_content.cxx b/ucb/source/ucp/gvfs/gvfs_content.cxx
new file mode 100644
index 000000000000..3b1d726f9304
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_content.cxx
@@ -0,0 +1,1817 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "osl/time.h"
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/interactionrequest.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <ucbhelper/simpleauthenticationrequest.hxx>
+
+const int TRANSFER_BUFFER_SIZE = 65536;
+
+/*
+ * NB. Name escaping is done only for URIs
+ * the 'Title' property is unescaped on set/get
+ */
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-result.h>
+#include <libgnomevfs/gnome-vfs-standard-callbacks.h>
+extern "C" { // missing in the header: doh.
+# include <libgnomevfs/gnome-vfs-module-callback.h>
+}
+
+#include "gvfs_content.hxx"
+#include "gvfs_provider.hxx"
+#include "gvfs_directory.hxx"
+#include "gvfs_stream.hxx"
+
+using namespace gvfs;
+using namespace com::sun::star;
+
+#define CLEAR_INFO(info) memset((info), 0, sizeof ((info)[0]))
+
+
+static char *
+OUStringToGnome( const rtl::OUString &str )
+{
+ rtl::OString aTempStr = rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 );
+ return g_strdup( (const sal_Char *) aTempStr );
+}
+
+static rtl::OUString
+GnomeToOUString( const char *utf8_str)
+{
+ if (!utf8_str)
+ return rtl::OUString();
+ else
+ return rtl::OUString( utf8_str, strlen( utf8_str ), RTL_TEXTENCODING_UTF8 );
+}
+
+
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier)
+ throw ( ucb::ContentCreationException )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_pProvider( pProvider ),
+ m_bTransient( sal_False )
+{
+ CLEAR_INFO (&m_info);
+#ifdef DEBUG
+ g_warning ("New Content ('%s')", getURI());
+#endif
+}
+
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider * pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ sal_Bool IsFolder)
+ throw ( ucb::ContentCreationException )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_pProvider( pProvider ),
+ m_bTransient( sal_True )
+{
+ CLEAR_INFO (&m_info);
+
+#ifdef DEBUG
+ g_warning ("New Transient content ('%s') (%d)", getURI(), IsFolder);
+#endif
+// m_info.name = FIXME: set name ?
+ m_info.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE;
+ m_info.type = IsFolder ? GNOME_VFS_FILE_TYPE_DIRECTORY :
+ GNOME_VFS_FILE_TYPE_REGULAR;
+}
+
+// virtual
+Content::~Content()
+{
+ gnome_vfs_file_info_clear( &m_info );
+}
+
+//
+// XInterface methods.
+//
+
+void SAL_CALL Content::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+void SAL_CALL Content::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ // Note: isFolder may require network activities! So call it only
+ // if it is really necessary!!!
+ uno::Any aRet = cppu::queryInterface( rType,
+ static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ return isFolder( uno::Reference< ucb::XCommandEnvironment >() )
+ ? aRet : uno::Any();
+ else
+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
+}
+
+//
+// XTypeProvider methods.
+//
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ static cppu::OTypeCollection *pFolderCollection = NULL;
+ static cppu::OTypeCollection *pFileCollection = NULL;
+
+ if (!pFolderCollection) {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ if (!pFolderCollection) {
+ static cppu::OTypeCollection aFolderCollection
+ (CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ static cppu::OTypeCollection aFileCollection
+ (CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+
+ pFolderCollection = &aFolderCollection;
+ pFileCollection = &aFileCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+
+ if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
+ return pFolderCollection->getTypes();
+ else
+ return pFileCollection->getTypes();
+}
+
+//
+// XServiceInfo methods.
+//
+
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii("com.sun.star.comp.GnomeVFSContent" );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContent" );
+ return aSNS;
+}
+
+//
+// XContent methods.
+//
+
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
+ return rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
+ else
+ return rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
+}
+
+//
+// XCommandProcessor methods.
+//
+
+uno::Any Content::getBadArgExcept()
+{
+ return uno::makeAny( lang::IllegalArgumentException
+ ( rtl::OUString::createFromAscii( "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) );
+}
+
+#include <stdio.h>
+
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ uno::Any aRet;
+
+#ifdef DEBUG
+ {
+ uno::Reference< task::XInteractionHandler > xIH;
+
+ if ( xEnv.is() )
+ xIH = xEnv->getInteractionHandler();
+ g_warning( "Execute command: '%s' with %s interaction env",
+ OUStringToGnome( aCommand.Name ),
+ xIH.is() ? "" : "NO" );
+ }
+#endif
+
+#define COMMAND_IS(cmd,name) ( (cmd).Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( name ) ) )
+
+ if ( COMMAND_IS( aCommand, "getPropertyValues" ) ) {
+ uno::Sequence< beans::Property > Properties;
+
+ if ( !( aCommand.Argument >>= Properties ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+
+ aRet <<= getPropertyValues( Properties, xEnv );
+
+ } else if ( COMMAND_IS( aCommand, "setPropertyValues" ) ) {
+ uno::Sequence< beans::PropertyValue > aProperties;
+
+ if ( !( aCommand.Argument >>= aProperties ) ||
+ !aProperties.getLength() )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+
+ aRet <<= setPropertyValues( aProperties, xEnv );
+
+ } else if ( COMMAND_IS( aCommand, "getPropertySetInfo" ) ) {
+ aRet <<= getPropertySetInfo( xEnv, sal_False );
+
+ } else if ( COMMAND_IS( aCommand, "getCommandInfo" ) ) {
+ aRet <<= getCommandInfo( xEnv, sal_False );
+
+ } else if ( COMMAND_IS( aCommand, "open" ) ) {
+ rtl::OUString str = m_xIdentifier->getContentIdentifier();
+ rtl::OString stra(
+ str.getStr(),
+ str.getLength(),
+ RTL_TEXTENCODING_UTF8);
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+
+ sal_Bool bOpenFolder =
+ ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) ||
+ ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
+ ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) );
+
+ if ( bOpenFolder && isFolder( xEnv ) ) {
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet(m_xSMgr, this, aOpenCommand, xEnv );
+ aRet <<= xSet;
+
+ } else if ( aOpenCommand.Sink.is() ) {
+
+ if ( ( aOpenCommand.Mode
+ == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( aOpenCommand.Mode
+ == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) {
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny ( ucb::UnsupportedOpenModeException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( aOpenCommand.Mode ) ) ),
+ xEnv );
+ }
+ if ( !feedSink( aOpenCommand.Sink, xEnv ) ) {
+ // Note: aOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+#ifdef DEBUG
+ g_warning ("Failed to load data from '%s'", getURI());
+#endif
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny (ucb::UnsupportedDataSinkException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aOpenCommand.Sink ) ),
+ xEnv );
+ }
+ }
+#ifdef DEBUG
+ else
+ g_warning ("Open falling through ...");
+#endif
+
+ } else if ( COMMAND_IS( aCommand, "createNewContent" ) && isFolder( xEnv ) ) {
+ ucb::ContentInfo arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+
+ aRet <<= createNewContent( arg );
+
+ } else if ( COMMAND_IS( aCommand, "insert" ) ) {
+ ucb::InsertCommandArgument arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
+
+ insert( arg.Data, arg.ReplaceExisting, xEnv );
+
+ } else if ( COMMAND_IS( aCommand, "delete" ) ) {
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+
+ ::rtl::OString aURI = getOURI();
+ GnomeVFSResult result = gnome_vfs_unlink ((const sal_Char *) aURI);
+
+ if (result != GNOME_VFS_OK)
+ cancelCommandExecution( result, xEnv, sal_True );
+
+ destroy( bDeletePhysical );
+
+ } else if ( COMMAND_IS( aCommand, "transfer" ) && isFolder( xEnv ) ) {
+ ucb::TransferInfo transferArgs;
+
+ if ( !( aCommand.Argument >>= transferArgs ) )
+ ucbhelper::cancelCommandExecution( getBadArgExcept(), xEnv );
+
+ transfer( transferArgs, xEnv );
+
+ } else { // Unsuported
+#ifdef DEBUG
+ g_warning( "Unsupported command: '%s'",
+ OUStringToGnome( aCommand.Name ) );
+#endif
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny( ucb::UnsupportedCommandException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ }
+#undef COMMAND_IS
+
+ return aRet;
+}
+
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ // FIXME: we should use the GnomeVFSCancellation APIs here ...
+}
+
+//
+// XContentCreator methods.
+//
+
+uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv)
+ throw( uno::RuntimeException )
+{
+ if ( isFolder( xEnv ) )
+ {
+ uno::Sequence< ucb::ContentInfo > seq(2);
+
+ // Minimum set of props we really need
+ uno::Sequence< beans::Property > props( 1 );
+ props[0] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
+
+ // file
+ seq[0].Type = rtl::OUString::createFromAscii( GVFS_FILE_TYPE );
+ seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
+ ucb::ContentInfoAttribute::KIND_DOCUMENT );
+ seq[0].Properties = props;
+
+ // folder
+ seq[1].Type = rtl::OUString::createFromAscii( GVFS_FOLDER_TYPE );
+ seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
+ seq[1].Properties = props;
+
+ return seq;
+ }
+ else
+ {
+ return uno::Sequence< ucb::ContentInfo >();
+ }
+}
+
+uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
+}
+
+uno::Reference< ucb::XContent > SAL_CALL
+Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ bool create_document;
+ const char *name;
+
+ if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FILE_TYPE ) ) )
+ create_document = true;
+ else if ( Info.Type.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( GVFS_FOLDER_TYPE ) ) )
+ create_document = false;
+ else {
+#ifdef DEBUG
+ g_warning( "Failed to create new content '%s'",
+ OUStringToGnome( Info.Type ) );
+#endif
+ return uno::Reference< ucb::XContent >();
+ }
+
+#ifdef DEBUG
+ g_warning( "createNewContent (%d)", (int) create_document );
+#endif
+
+ rtl::OUString aURL = getOUURI();
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ name = create_document ? "[New_Content]" : "[New_Collection]";
+ // This looks problematic to me cf. webdav
+ aURL += rtl::OUString::createFromAscii( name );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ ( new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) );
+
+ try {
+ return new ::gvfs::Content( m_xSMgr, m_pProvider, xId, !create_document );
+ } catch ( ucb::ContentCreationException & ) {
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+rtl::OUString Content::getParentURL()
+{
+ rtl::OUString aParentURL;
+ // <scheme>:// -> ""
+ // <scheme>://foo -> ""
+ // <scheme>://foo/ -> ""
+ // <scheme>://foo/bar -> <scheme>://foo/
+ // <scheme>://foo/bar/ -> <scheme>://foo/
+ // <scheme>://foo/bar/abc -> <scheme>://foo/bar/
+
+ rtl::OUString aURL = getOUURI();
+
+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
+ if ( nPos == ( aURL.getLength() - 1 ) ) {
+ // Trailing slash found. Skip.
+ nPos = aURL.lastIndexOf( '/', nPos );
+ }
+
+ sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
+ if ( nPos1 != -1 )
+ nPos1 = aURL.lastIndexOf( '/', nPos1 );
+
+ if ( nPos1 != -1 )
+ aParentURL = rtl::OUString( aURL.copy( 0, nPos + 1 ) );
+
+#ifdef DEBUG
+ g_warning ("getParentURL '%s' -> '%s'",
+ getURI(), (const sal_Char *) rtl::OUStringToOString
+ ( aParentURL, RTL_TEXTENCODING_UTF8 ) );
+#endif
+
+ return aParentURL;
+}
+
+static util::DateTime
+getDateFromUnix (time_t t)
+{
+ TimeValue tv;
+ tv.Nanosec = 0;
+ tv.Seconds = t;
+ oslDateTime dt;
+
+ if ( osl_getDateTimeFromTimeValue( &tv, &dt ) )
+ return util::DateTime( 0, dt.Seconds, dt.Minutes, dt.Hours,
+ dt.Day, dt.Month, dt.Year);
+ else
+ return util::DateTime();
+}
+
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ int nProps;
+ GnomeVFSResult result;
+ uno::Sequence< beans::Property > allProperties;
+
+ if( ( result = getInfo( xEnv ) ) != GNOME_VFS_OK )
+ cancelCommandExecution( result, xEnv, sal_False );
+
+ const beans::Property* pProps;
+
+ if( rProperties.getLength() ) {
+ nProps = rProperties.getLength();
+ pProps = rProperties.getConstArray();
+ } else {
+ allProperties = getPropertySetInfo( xEnv )->getProperties();
+ nProps = allProperties.getLength();
+ pProps = allProperties.getConstArray();
+ }
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( m_xSMgr );
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ for( sal_Int32 n = 0; n < nProps; ++n ) {
+ const beans::Property& rProp = pProps[ n ];
+
+ if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
+ if (m_info.name && m_info.name[0] == '/')
+ g_warning ("Odd NFS title on item '%s' == '%s'",
+ getURI(), m_info.name);
+ xRow->appendString( rProp, GnomeToOUString( m_info.name ) );
+ }
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ xRow->appendString( rProp, getContentType () );
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) {
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
+ xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_REGULAR ||
+ m_info.type == GNOME_VFS_FILE_TYPE_UNKNOWN ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) {
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE)
+ xRow->appendBoolean( rProp, ( m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) ) {
+
+ GnomeVFSFileInfo* fileInfo = gnome_vfs_file_info_new ();
+
+ ::rtl::OString aURI = getOURI();
+ gnome_vfs_get_file_info
+ ( (const sal_Char *)aURI, fileInfo,
+ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS );
+
+ if (fileInfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_ACCESS) {
+ bool read_only = true;
+
+ if (fileInfo->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE)
+ read_only = false;
+
+ xRow->appendBoolean( rProp, read_only );
+ } else
+ xRow->appendVoid( rProp );
+ gnome_vfs_file_info_unref (fileInfo);
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) {
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
+ xRow->appendLong( rProp, m_info.size );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsHidden" ) ) )
+ xRow->appendBoolean( rProp, ( m_info.name && m_info.name[0] == '.' ) );
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsVolume" ) ) ||
+ rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsCompactDisk" ) ) )
+ xRow->appendBoolean( rProp, sal_False );
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ) {
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_CTIME)
+ xRow->appendTimestamp( rProp, getDateFromUnix( m_info.ctime ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME)
+ xRow->appendTimestamp( rProp, getDateFromUnix( m_info.mtime ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+
+ else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) {
+ // We do this by sniffing in gnome-vfs; rather expensively.
+#ifdef DEBUG
+ g_warning ("FIXME: Requested mime-type - an expensive op. indeed!");
+#endif
+ xRow->appendVoid( rProp );
+ } else if (rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
+
+ else {
+ xRow->appendVoid( rProp );
+ }
+ }
+#ifdef DEBUG
+ g_warning ("getPropertyValues on '%s' %d properties returned (of %d)",
+ getURI(), (int)xRow->getLength(), (int)nProps);
+#endif
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+static lang::IllegalAccessException
+getReadOnlyException( Content *ctnt )
+{
+ return lang::IllegalAccessException
+ ( rtl::OUString::createFromAscii( "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( ctnt ) );
+}
+
+rtl::OUString
+Content::makeNewURL( const char */*newName*/ )
+{
+ rtl::OUString aNewURL = getParentURL();
+ if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+
+ char *name = gnome_vfs_escape_string( m_info.name );
+ aNewURL += GnomeToOUString( name );
+ g_free( name );
+
+ return aNewURL;
+}
+
+// This is slightly complicated by needing to support either 'move' or 'setname'
+GnomeVFSResult
+Content::doSetFileInfo( const GnomeVFSFileInfo *newInfo,
+ GnomeVFSSetFileInfoMask setMask,
+ const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
+{
+ GnomeVFSResult result = GNOME_VFS_OK;
+
+ g_assert (!m_bTransient);
+
+ ::rtl::OString aURI = getOURI();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // The simple approach:
+ if( setMask != GNOME_VFS_SET_FILE_INFO_NONE )
+ result = gnome_vfs_set_file_info // missed a const in the API there
+ ( (const sal_Char *) aURI, (GnomeVFSFileInfo *)newInfo, setMask );
+
+ if ( result == GNOME_VFS_ERROR_NOT_SUPPORTED &&
+ ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) ) {
+ // Try a move instead
+#ifdef DEBUG
+ g_warning( "SetFileInfo not supported on '%s'", getURI() );
+#endif
+
+ char *newURI = OUStringToGnome( makeNewURL( newInfo->name ) );
+
+ result = gnome_vfs_move ((const sal_Char *)aURI, newURI, FALSE);
+
+ g_free (newURI);
+ }
+
+ return result;
+}
+
+
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ rtl::OUString aNewTitle;
+ GnomeVFSFileInfo newInfo;
+ int setMask = GNOME_VFS_SET_FILE_INFO_NONE;
+
+ getInfo( xEnv );
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ gnome_vfs_file_info_copy( &newInfo, &m_info );
+
+ Authentication aAuth( xEnv );
+
+ int nChanged = 0, nTitlePos = 0;
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = -1;
+ // aEvent.PropertyName = fill in later ...
+ // aEvent.OldValue =
+ // aEvent.NewValue =
+
+ int nCount = rValues.getLength();
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nCount; ++n ) {
+ const beans::PropertyValue& rValue = pValues[ n ];
+
+#ifdef DEBUG
+ g_warning( "Set prop '%s'", OUStringToGnome( rValue.Name ) );
+#endif
+ if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ aRet[ n ] <<= getReadOnlyException( this );
+
+ else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) {
+ if ( rValue.Value >>= aNewTitle ) {
+ if ( aNewTitle.getLength() <= 0 )
+ aRet[ n ] <<= lang::IllegalArgumentException
+ ( rtl::OUString::createFromAscii( "Empty title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ), -1 );
+ else {
+ char *newName = OUStringToGnome( aNewTitle );
+
+ if( !newName || !m_info.name || strcmp( newName, m_info.name ) ) {
+#ifdef DEBUG
+ g_warning ("Set new name to '%s'", newName);
+#endif
+
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( GnomeToOUString( newInfo.name ) );
+ aEvent.NewValue = uno::makeAny( aNewTitle );
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nTitlePos = nChanged++;
+
+ newInfo.name = newName;
+ setMask |= GNOME_VFS_SET_FILE_INFO_NAME;
+ } else // same name
+ g_free (newName);
+ }
+ } else
+ aRet[ n ] <<= beans::IllegalTypeException
+ ( rtl::OUString::createFromAscii( "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+
+ } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ||
+ rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) {
+ // FIXME: should be able to set the timestamps
+ aRet[ n ] <<= getReadOnlyException( this );
+ } else {
+#ifdef DEBUG
+ g_warning( "Unhandled property '%s'", OUStringToGnome( rValue.Name ) );
+#endif
+ aRet[ n ] <<= getReadOnlyException( this );
+ }
+ }
+
+ GnomeVFSResult result = GNOME_VFS_OK;
+
+ if ( !m_bTransient &&
+ ( result = doSetFileInfo( &newInfo,
+ (GnomeVFSSetFileInfoMask) setMask,
+ xEnv ) ) != GNOME_VFS_OK ) {
+ for (int i = 0; i < nChanged; i++)
+ aRet[ i ] <<= mapVFSException( result, sal_True );
+
+ }
+
+ if ( result == GNOME_VFS_OK) {
+ gnome_vfs_file_info_copy( &m_info, &newInfo );
+
+ if ( setMask & GNOME_VFS_SET_FILE_INFO_NAME ) {
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, makeNewURL( newInfo.name ) );
+
+ aGuard.clear();
+ if (!exchangeIdentity( xNewId ) )
+ aRet[ nTitlePos ] <<= uno::Exception
+ ( rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ gnome_vfs_file_info_clear( &newInfo );
+
+ if ( nChanged > 0 ) {
+ aGuard.clear();
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = getOUURI();
+ sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( aURL.getLength() - 1 ) )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end ) {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) ||
+ ( nPos == ( aChildURL.getLength() - 1 ) ) ) {
+ // No further slashes / only a final slash. It's a child!
+ rChildren.push_back( ::gvfs::Content::ContentRef
+ (static_cast< ::gvfs::Content * >(xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+void Content::insert(
+ const uno::Reference< io::XInputStream > &xInputStream,
+ sal_Bool bReplaceExisting,
+ const uno::Reference< ucb::XCommandEnvironment > &xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+#ifdef DEBUG
+ g_warning( "Insert '%s' (%d) (0x%x:%d)", getURI(), bReplaceExisting,
+ m_info.valid_fields, m_info.type );
+#endif
+
+ GnomeVFSResult result = getInfo( xEnv );
+ // a racy design indeed.
+ if( !bReplaceExisting && !m_bTransient &&
+ result != GNOME_VFS_ERROR_NOT_FOUND) {
+#ifdef DEBUG
+ g_warning ("Nasty error inserting to '%s' ('%s')",
+ getURI(), gnome_vfs_result_to_string( result ));
+#endif
+ cancelCommandExecution( GNOME_VFS_ERROR_FILE_EXISTS, xEnv, sal_True );
+ }
+
+ if ( m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
+ m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY ) {
+ ::rtl::OString aURI = getOURI();
+ int perm;
+
+ perm = ( GNOME_VFS_PERM_USER_ALL |
+ GNOME_VFS_PERM_GROUP_READ |
+ GNOME_VFS_PERM_OTHER_READ );
+
+#ifdef DEBUG
+ g_warning ("Make directory");
+#endif
+ result = gnome_vfs_make_directory( (const sal_Char *) aURI, perm );
+
+ if( result != GNOME_VFS_OK )
+ cancelCommandExecution( result, xEnv, sal_True );
+
+ return;
+ }
+
+ if ( !xInputStream.is() ) {
+ // FIXME: slightly unclear whether to accept this and create an empty file
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny
+ ( ucb::MissingInputStreamException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ }
+
+ GnomeVFSHandle *handle = NULL;
+ ::rtl::OString aURI = getOURI();
+
+ result = GNOME_VFS_OK;
+ if ( bReplaceExisting ) {
+ Authentication aAuth( xEnv );
+ result = gnome_vfs_open( &handle, (const sal_Char *)aURI,
+ GNOME_VFS_OPEN_WRITE );
+ }
+
+ if ( result != GNOME_VFS_OK ) {
+ int perm;
+ Authentication aAuth( xEnv );
+
+ perm = ( ( GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ ) |
+ ( GNOME_VFS_PERM_GROUP_WRITE | GNOME_VFS_PERM_GROUP_READ ) );
+
+ result = gnome_vfs_create
+ ( &handle, (const sal_Char *)aURI, GNOME_VFS_OPEN_WRITE, TRUE, perm );
+ }
+
+ if( result != GNOME_VFS_OK )
+ cancelCommandExecution( result, xEnv, sal_True );
+
+ if ( !xInputStream.is() ) {
+ result = gnome_vfs_close( handle );
+ if (result != GNOME_VFS_OK)
+ cancelCommandExecution( result, xEnv, sal_True );
+
+ } else { // copy it over
+ uno::Reference < io::XOutputStream > xOutput =
+ new gvfs::Stream( handle, &m_info );
+
+ copyData( xInputStream, xOutput );
+ }
+
+ if (m_bTransient) {
+ m_bTransient = sal_False;
+ aGuard.clear();
+ inserted();
+ }
+}
+
+void Content::transfer(const ucb::TransferInfo & /*rArgs*/,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ // FIXME: see gnome-vfs-xfer.h - but we need to be able to easily
+ // detect which are gnome-vfs owned URI types ...
+ ucbhelper::cancelCommandExecution
+ ( uno::makeAny
+ ( ucb::InteractiveBadTransferURLException
+ ( rtl::OUString::createFromAscii( "Unsupported URL scheme!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+}
+
+void Content::destroy( sal_Bool bDeletePhysical )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+ rtl::OUString aURL = getOUURI();
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ deleted();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Process instanciated children...
+ ::gvfs::Content::ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end ) {
+ (*it)->destroy( bDeletePhysical );
+ ++it;
+ }
+}
+
+// Used by the 'setPropertyValues' method for
+// propagating the renaming of a Content.
+sal_Bool Content::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+#ifdef DEBUG
+ g_warning( "exchangeIdentity from '%s' to '%s'",
+ getURI(), OUStringToGnome( xNewId->getContentIdentifier() ) );
+#endif
+
+ if ( m_bTransient ) {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ /* FIXME: can we not screw up an identically named
+ * Content pointing to ourself here ? */
+ m_xIdentifier = xNewId;
+ return sal_False;
+ }
+
+ rtl::OUString aOldURL = getOUURI();
+
+ // Exchange own identitity.
+ if ( exchange( xNewId ) ) {
+
+ // Process instanciated children...
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end ) {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier >
+ xOldChildId = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier >
+ xNewChildId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+GnomeVFSResult
+Content::getInfo( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ GnomeVFSResult result;
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if (m_bTransient)
+ result = GNOME_VFS_OK;
+
+ else if ( !m_info.valid_fields ) {
+ ::rtl::OString aURI = getOURI();
+ Authentication aAuth( xEnv );
+ result = gnome_vfs_get_file_info
+ ( (const sal_Char *)aURI, &m_info, GNOME_VFS_FILE_INFO_DEFAULT );
+ if (result != GNOME_VFS_OK)
+ gnome_vfs_file_info_clear( &m_info );
+ } else
+ result = GNOME_VFS_OK;
+#ifdef DEBUG
+ g_warning( "getInfo on '%s' returns '%s' (%d) (0x%x)",
+ getURI(), gnome_vfs_result_to_string( result ),
+ result, m_info.valid_fields );
+#endif
+ return result;
+}
+
+sal_Bool
+Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ getInfo( xEnv );
+ return (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
+ m_info.type == GNOME_VFS_FILE_TYPE_DIRECTORY);
+}
+
+uno::Any Content::mapVFSException( const GnomeVFSResult result, sal_Bool bWrite )
+{
+ uno::Any aException;
+ const char *gvfs_message;
+ rtl::OUString message;
+ uno::Sequence< uno::Any > aArgs( 1 );
+
+#ifdef DEBUG
+ g_warning ("Map VFS exception '%s' (%d)",
+ gnome_vfs_result_to_string( result ), result );
+#endif
+
+ if ((gvfs_message = gnome_vfs_result_to_string (result)))
+ message = GnomeToOUString( gvfs_message );
+
+ switch (result) {
+ case GNOME_VFS_OK:
+ g_error ("VFS_OK mapped to exception.");
+ break;
+ case GNOME_VFS_ERROR_EOF:
+ g_warning ("VFS_EOF not handled somewhere.");
+ break;
+ case GNOME_VFS_ERROR_NOT_FOUND:
+ aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
+ aException <<=
+ ucb::InteractiveAugmentedIOException
+ ( rtl::OUString::createFromAscii( "Not found!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ ucb::IOErrorCode_NOT_EXISTING,
+ aArgs );
+ break;
+ case GNOME_VFS_ERROR_BAD_PARAMETERS:
+ aException <<=
+ lang::IllegalArgumentException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ break;
+ case GNOME_VFS_ERROR_GENERIC:
+ case GNOME_VFS_ERROR_INTERNAL:
+ case GNOME_VFS_ERROR_NOT_SUPPORTED:
+#ifdef DEBUG
+ g_warning ("Internal - un-mapped error");
+#endif
+ aException <<= io::IOException();
+ break;
+ case GNOME_VFS_ERROR_IO:
+ if ( bWrite )
+ aException <<=
+ ucb::InteractiveNetworkWriteException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ message );
+ else
+ aException <<=
+ ucb::InteractiveNetworkReadException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ message );
+ break;
+ case GNOME_VFS_ERROR_HOST_NOT_FOUND:
+ case GNOME_VFS_ERROR_INVALID_HOST_NAME:
+ aException <<=
+ ucb::InteractiveNetworkResolveNameException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ message );
+ break;
+ case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
+ case GNOME_VFS_ERROR_SERVICE_OBSOLETE:
+ case GNOME_VFS_ERROR_PROTOCOL_ERROR:
+ case GNOME_VFS_ERROR_NO_MASTER_BROWSER:
+ aException <<=
+ ucb::InteractiveNetworkConnectException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ message );
+ break;
+
+ case GNOME_VFS_ERROR_FILE_EXISTS:
+ aException <<= ucb::NameClashException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ message );
+ break;
+
+ case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
+ aException <<= ucb::UnsupportedOpenModeException();
+ break;
+
+ case GNOME_VFS_ERROR_CORRUPTED_DATA:
+ case GNOME_VFS_ERROR_WRONG_FORMAT:
+ case GNOME_VFS_ERROR_BAD_FILE:
+ case GNOME_VFS_ERROR_TOO_BIG:
+ case GNOME_VFS_ERROR_NO_SPACE:
+ case GNOME_VFS_ERROR_READ_ONLY:
+ case GNOME_VFS_ERROR_INVALID_URI:
+ case GNOME_VFS_ERROR_NOT_OPEN:
+ case GNOME_VFS_ERROR_ACCESS_DENIED:
+ case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
+ case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
+ case GNOME_VFS_ERROR_IN_PROGRESS:
+ case GNOME_VFS_ERROR_INTERRUPTED:
+ case GNOME_VFS_ERROR_LOOP:
+ case GNOME_VFS_ERROR_NOT_PERMITTED:
+ case GNOME_VFS_ERROR_IS_DIRECTORY:
+ case GNOME_VFS_ERROR_NO_MEMORY:
+ case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
+ case GNOME_VFS_ERROR_LOGIN_FAILED:
+ case GNOME_VFS_ERROR_CANCELLED:
+ case GNOME_VFS_ERROR_DIRECTORY_BUSY:
+ case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
+ case GNOME_VFS_ERROR_TOO_MANY_LINKS:
+ case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:
+ case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
+ case GNOME_VFS_ERROR_NAME_TOO_LONG:
+#ifdef DEBUG
+ g_warning( "FIXME: Un-mapped VFS exception '%s' (%d)",
+ gnome_vfs_result_to_string( result ), result );
+#endif
+ default:
+ aException <<= ucb::InteractiveNetworkGeneralException
+ ( rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR );
+ break;
+ }
+
+ return aException;
+}
+
+void Content::cancelCommandExecution(
+ GnomeVFSResult result,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ sal_Bool bWrite /* = sal_False */ )
+ throw ( uno::Exception )
+{
+ ucbhelper::cancelCommandExecution( mapVFSException( result, bWrite ), xEnv );
+ // Unreachable
+}
+
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ static const beans::Property aGenericProperties[] = {
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ // Optional ...
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
+ -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
+ -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+// FIXME: Too expensive for now (?)
+// beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+// -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+// beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
+ -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisk" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ),
+ -1, getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
+ beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
+ -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY )
+ };
+
+ const int nProps = sizeof (aGenericProperties) / sizeof (aGenericProperties[0]);
+
+ return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
+
+}
+
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+{
+ static ucb::CommandInfo aCommandInfoTable[] = {
+ // Required commands
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1, getCppuVoidType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1, getCppuVoidType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
+
+ // Optional standard commands
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1, getCppuBooleanType() ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
+
+ // Folder Only, omitted if not a folder
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
+ ucb::CommandInfo
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
+ };
+
+ const int nProps
+ = sizeof( aCommandInfoTable ) / sizeof( aCommandInfoTable[ 0 ] );
+ return uno::Sequence< ucb::CommandInfo >(
+ aCommandInfoTable, isFolder( xEnv ) ? nProps : nProps - 2 );
+}
+
+rtl::OUString
+Content::getOUURI ()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return m_xIdentifier->getContentIdentifier();
+}
+
+rtl::OString
+Content::getOURI ()
+{
+ return rtl::OUStringToOString( getOUURI(), RTL_TEXTENCODING_UTF8 );
+}
+
+char *
+Content::getURI ()
+{
+ return OUStringToGnome( getOUURI() );
+}
+
+void
+Content::copyData( uno::Reference< io::XInputStream > xIn,
+ uno::Reference< io::XOutputStream > xOut )
+{
+ uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
+
+ g_return_if_fail( xIn.is() && xOut.is() );
+
+ while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
+ xOut->writeBytes( theData );
+
+ xOut->closeOutput();
+}
+
+// Inherits an authentication context
+uno::Reference< io::XInputStream >
+Content::createTempStream(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ GnomeVFSResult result;
+ GnomeVFSHandle *handle = NULL;
+ ::rtl::OString aURI = getOURI();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ // Something badly wrong happened - can't seek => stream to a temporary file
+ const rtl::OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
+ uno::Reference < io::XOutputStream > xTempOut =
+ uno::Reference < io::XOutputStream >
+ ( m_xSMgr->createInstance( sServiceName ), uno::UNO_QUERY );
+
+ if ( !xTempOut.is() )
+ cancelCommandExecution( GNOME_VFS_ERROR_IO, xEnv );
+
+ result = gnome_vfs_open
+ ( &handle, (const sal_Char *)aURI, GNOME_VFS_OPEN_READ );
+ if (result != GNOME_VFS_OK)
+ cancelCommandExecution( result, xEnv );
+
+ uno::Reference < io::XInputStream > pStream = new ::gvfs::Stream( handle, &m_info );
+ copyData( pStream, xTempOut );
+
+ return uno::Reference < io::XInputStream > ( xTempOut, uno::UNO_QUERY );
+}
+
+uno::Reference< io::XInputStream >
+Content::createInputStream(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ GnomeVFSHandle *handle = NULL;
+ GnomeVFSResult result;
+ uno::Reference<io::XInputStream > xIn;
+
+ Authentication aAuth( xEnv );
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ getInfo( xEnv );
+ ::rtl::OString aURI = getOURI();
+
+ if ( !(m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) )
+ return createTempStream( xEnv );
+
+ result = gnome_vfs_open
+ ( &handle, (const sal_Char *)aURI,
+ (GnomeVFSOpenMode) (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM ) );
+
+ if (result == GNOME_VFS_ERROR_INVALID_OPEN_MODE ||
+ result == GNOME_VFS_ERROR_NOT_SUPPORTED)
+ return createTempStream( xEnv );
+
+ if (result != GNOME_VFS_OK)
+ cancelCommandExecution( result, xEnv );
+
+ // Try a seek just to make sure it's Random access: some lie.
+ result = gnome_vfs_seek( handle, GNOME_VFS_SEEK_START, 0);
+ if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) {
+ gnome_vfs_close( handle );
+ return createTempStream( xEnv );
+ }
+
+ if (result != GNOME_VFS_OK)
+ cancelCommandExecution( result, xEnv );
+
+ if (handle != NULL)
+ xIn = new ::gvfs::Stream( handle, &m_info );
+
+ return xIn;
+}
+
+sal_Bool
+Content::feedSink( uno::Reference< uno::XInterface > aSink,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+{
+ if ( !aSink.is() )
+ return sal_False;
+
+ uno::Reference< io::XOutputStream > xOut
+ = uno::Reference< io::XOutputStream >(aSink, uno::UNO_QUERY );
+ uno::Reference< io::XActiveDataSink > xDataSink
+ = uno::Reference< io::XActiveDataSink >(aSink, uno::UNO_QUERY );
+
+ if ( !xOut.is() && !xDataSink.is() )
+ return sal_False;
+
+ uno::Reference< io::XInputStream > xIn = createInputStream( xEnv );
+ if ( !xIn.is() )
+ return sal_False;
+
+ if ( xOut.is() )
+ copyData( xIn, xOut );
+
+ if ( xDataSink.is() )
+ xDataSink->setInputStream( xIn );
+
+ return sal_True;
+}
+
+extern "C" {
+
+#ifndef GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION
+# error "We require Gnome VFS 2.6.x to compile (will run fine with < 2.6)"
+#endif
+
+ static void
+ vfs_authentication_callback (gconstpointer in_void,
+ gsize in_size,
+ gpointer out_void,
+ gsize out_size,
+ gpointer callback_data)
+ {
+ task::XInteractionHandler *xIH;
+
+#ifdef DEBUG
+ g_warning ("Full authentication callback (%p) ...", callback_data);
+#endif
+
+ if( !( xIH = (task::XInteractionHandler *) callback_data ) )
+ return;
+
+ const GnomeVFSModuleCallbackFullAuthenticationIn *in =
+ (const GnomeVFSModuleCallbackFullAuthenticationIn *) in_void;
+ GnomeVFSModuleCallbackFullAuthenticationOut *out =
+ (GnomeVFSModuleCallbackFullAuthenticationOut *) out_void;
+
+ g_return_if_fail (in != NULL && out != NULL);
+ g_return_if_fail (sizeof (GnomeVFSModuleCallbackFullAuthenticationIn) == in_size &&
+ sizeof (GnomeVFSModuleCallbackFullAuthenticationOut) == out_size);
+
+#ifdef DEBUG
+# define NNIL(x) (x?x:"<Null>")
+ g_warning (" InComing data 0x%x uri '%s' prot '%s' server '%s' object '%s' "
+ "port %d auth_t '%s' user '%s' domain '%s' "
+ "def user '%s', def domain '%s'",
+ (int) in->flags, NNIL(in->uri), NNIL(in->protocol),
+ NNIL(in->server), NNIL(in->object),
+ (int) in->port, NNIL(in->authtype), NNIL(in->username), NNIL(in->domain),
+ NNIL(in->default_user), NNIL(in->default_domain));
+# undef NNIL
+#endif
+
+ ucbhelper::SimpleAuthenticationRequest::EntityType
+ eDomain, eUserName, ePassword;
+ ::rtl::OUString aHostName, aDomain, aUserName, aPassword;
+
+ aHostName = GnomeToOUString( in->server );
+
+ if (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN)
+ {
+ aDomain = GnomeToOUString( in->domain );
+ eDomain = ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY;
+ if (!aDomain.getLength())
+ aDomain = GnomeToOUString( in->default_domain );
+ }
+ else // no underlying capability to display realm otherwise
+ eDomain = ucbhelper::SimpleAuthenticationRequest::ENTITY_NA;
+
+ aUserName = GnomeToOUString( in->username );
+ if (!aUserName.getLength())
+ aUserName = GnomeToOUString( in->default_user );
+ eUserName = (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME) ?
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY :
+ (aUserName.getLength() ?
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_FIXED :
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_NA);
+
+ // No suggested password.
+ ePassword = (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_PASSWORD) ?
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY :
+ ucbhelper::SimpleAuthenticationRequest::ENTITY_FIXED;
+
+ // Really, really bad things happen if we don't provide
+ // the same user/password as was entered last time if
+ // we failed to authenticate - infinite looping / flickering
+ // madness etc. [ nice infrastructure ! ]
+ static rtl::OUString aLastUserName, aLastPassword;
+ if (in->flags & GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED)
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ aUserName = aLastUserName;
+ aPassword = aLastPassword;
+ }
+
+ rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
+ = new ucbhelper::SimpleAuthenticationRequest (GnomeToOUString(in->uri),
+ aHostName, eDomain, aDomain,
+ eUserName, aUserName,
+ ePassword, aPassword);
+
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() ) {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(xSelection.get(), uno::UNO_QUERY );
+ if ( !xAbort.is() ) {
+ const rtl::Reference<
+ ucbhelper::InteractionSupplyAuthentication > & xSupp
+ = xRequest->getAuthenticationSupplier();
+
+ aUserName = xSupp->getUserName();
+ aDomain = xSupp->getRealm();
+ aPassword = xSupp->getPassword();
+
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ aLastUserName = aUserName;
+ aLastPassword = aPassword;
+ }
+
+ out->username = OUStringToGnome( aUserName );
+ out->domain = OUStringToGnome( aDomain );
+ out->password = OUStringToGnome( aPassword );
+ out->save_password = xSupp->getRememberPasswordMode();
+
+#ifdef DEBUG
+ g_warning ("Got valid user/domain/password '%s' '%s' '%s', %s password",
+ out->username, out->domain, out->password,
+ out->save_password ? "save" : "don't save");
+#endif
+ }
+ else
+ out->abort_auth = TRUE;
+ }
+ else
+ out->abort_auth = TRUE;
+ }
+
+ static void
+ vfs_authentication_old_callback (gconstpointer in_void,
+ gsize in_size,
+ gpointer out_void,
+ gsize out_size,
+ gpointer callback_data)
+ {
+#ifdef DEBUG
+ g_warning ("Old authentication callback (%p) [ UNTESTED ] ...", callback_data);
+#endif
+ const GnomeVFSModuleCallbackAuthenticationIn *in =
+ (const GnomeVFSModuleCallbackAuthenticationIn *) in_void;
+ GnomeVFSModuleCallbackAuthenticationOut *out =
+ (GnomeVFSModuleCallbackAuthenticationOut *) out_void;
+
+ g_return_if_fail (in != NULL && out != NULL);
+ g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size &&
+ sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
+
+ GnomeVFSModuleCallbackFullAuthenticationIn mapped_in = {
+ (GnomeVFSModuleCallbackFullAuthenticationFlags)
+ (GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_PASSWORD |
+ GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_USERNAME |
+ GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_NEED_DOMAIN),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ GnomeVFSModuleCallbackFullAuthenticationOut mapped_out = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ // Map the old style input auth. data to the new style structure.
+ if (in->previous_attempt_failed)
+ mapped_in.flags = (GnomeVFSModuleCallbackFullAuthenticationFlags)
+ (mapped_in.flags |
+ GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED);
+
+ GnomeVFSURI *pURI = NULL;
+ // Urk - parse all this from the URL ...
+ mapped_in.uri = in->uri;
+ if (in->uri)
+ {
+ pURI = gnome_vfs_uri_new( in->uri );
+ mapped_in.protocol = (char *) gnome_vfs_uri_get_scheme (pURI);
+ mapped_in.server = (char *) gnome_vfs_uri_get_host_name (pURI);
+ mapped_in.port = gnome_vfs_uri_get_host_port (pURI);
+ mapped_in.username = (char *) gnome_vfs_uri_get_user_name (pURI);
+ }
+ mapped_in.domain = in->realm;
+ mapped_in.default_user = mapped_in.username;
+ mapped_in.default_domain = mapped_in.domain;
+
+ vfs_authentication_callback ((gconstpointer) &mapped_in,
+ sizeof (mapped_in),
+ (gpointer) &mapped_out,
+ sizeof (mapped_out),
+ callback_data);
+
+ if (pURI)
+ gnome_vfs_uri_unref (pURI);
+
+ // Map the new style auth. out data to the old style out structure.
+ out->username = mapped_out.username;
+ out->password = mapped_out.password;
+ g_free (mapped_out.domain);
+ g_free (mapped_out.keyring);
+ }
+
+
+ static void
+ auth_destroy (gpointer data)
+ {
+ task::XInteractionHandler *xIH;
+ if( ( xIH = ( task::XInteractionHandler * )data ) )
+ xIH->release();
+ }
+
+ // This sucks, but gnome-vfs doesn't much like
+ // repeated set / unsets - so we have to compensate.
+ GPrivate *auth_queue = NULL;
+
+ void auth_queue_destroy( gpointer data )
+ {
+ GList *l;
+ GQueue *vq = (GQueue *) data;
+
+ for (l = vq->head; l; l = l->next)
+ auth_destroy (l->data);
+ g_queue_free (vq);
+ }
+}
+
+static void
+refresh_auth( GQueue *vq )
+{
+ GList *l;
+
+ gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION );
+ gnome_vfs_module_callback_pop( GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION );
+
+ for (l = vq->head; l; l = l->next) {
+ if (l->data) {
+ gnome_vfs_module_callback_push
+ ( GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
+ vfs_authentication_old_callback, l->data, NULL );
+ gnome_vfs_module_callback_push
+ ( GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION,
+ vfs_authentication_callback, l->data, NULL );
+ break;
+ }
+ }
+}
+
+gvfs::Authentication::Authentication(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+{
+ GQueue *vq;
+ uno::Reference< task::XInteractionHandler > xIH;
+
+ if ( xEnv.is() )
+ xIH = xEnv->getInteractionHandler();
+
+ if ( xIH.is() )
+ xIH->acquire();
+
+ if( !(vq = (GQueue *)g_private_get( auth_queue ) ) ) {
+ vq = g_queue_new();
+ g_private_set( auth_queue, vq );
+ }
+
+ g_queue_push_head( vq, (gpointer) xIH.get() );
+ refresh_auth( vq );
+}
+
+gvfs::Authentication::~Authentication()
+{
+ GQueue *vq;
+ gpointer data;
+
+ vq = (GQueue *)g_private_get( auth_queue );
+
+ data = g_queue_pop_head( vq );
+ auth_destroy (data);
+
+ refresh_auth( vq );
+}
diff --git a/ucb/source/ucp/gvfs/gvfs_content.hxx b/ucb/source/ucp/gvfs/gvfs_content.hxx
new file mode 100644
index 000000000000..b2f6bec4ca11
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_content.hxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _GVFS_UCP_CONTENT_HXX
+#define _GVFS_UCP_CONTENT_HXX
+
+#include <memory>
+#include <list>
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+
+#include <glib/gthread.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-directory.h>
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+ struct PropertyValue;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace io {
+ class XInputStream;
+ class XOutputStream;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class XRow;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ struct TransferInfo;
+} } } }
+
+namespace gvfs
+{
+
+class ContentProvider;
+class ContentProperties;
+
+// Random made up names - AFAICS
+#define GVFS_FILE_TYPE "application/vnd.sun.staroffice.gvfs-file"
+#define GVFS_FOLDER_TYPE "application/vnd.sun.staroffice.gvfs-folder"
+
+class Authentication
+{
+public:
+ // Helper class to make exceptions pleasant
+ Authentication( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ ~Authentication();
+};
+
+class Content : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+//=========================================================================
+// Internals
+//=========================================================================
+private:
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+
+ // Instance data
+ ContentProvider *m_pProvider; // No need for a ref, base class holds object
+ sal_Bool m_bTransient; // A non-existant (as yet) item
+ GnomeVFSFileInfo m_info; // cached status information
+
+ // Internal helpers
+ void queryChildren ( ContentRefList& rChildren );
+ ::com::sun::star::uno::Any getBadArgExcept ();
+ GnomeVFSResult getInfo ( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+ sal_Bool isFolder ( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+ sal_Bool exchangeIdentity( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId);
+ GnomeVFSResult doSetFileInfo ( const GnomeVFSFileInfo *newInfo,
+ GnomeVFSSetFileInfoMask setMask,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+ ::rtl::OUString makeNewURL ( const char *newName );
+ // End Internal helpers
+
+ // For ucbhelper
+ virtual ::rtl::OUString getParentURL();
+ // For ucbhelper
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ // For ucbhelper
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+
+public:
+ // Command "getPropertyValues"
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+private:
+ // Command "setPropertyValues"
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+ // Command "insert"
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "transfer"
+ void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "delete"
+ void destroy( sal_Bool bDeletePhysical )
+ throw( ::com::sun::star::uno::Exception );
+
+ // "open" helpers
+ void copyData( ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > xIn,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XOutputStream > xOut );
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream >
+ createTempStream( const ::com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream >
+ createInputStream( const ::com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+ sal_Bool feedSink( ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface> aSink,
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+ ::com::sun::star::uno::Any mapVFSException( const GnomeVFSResult result,
+ sal_Bool bWrite );
+
+ void cancelCommandExecution(const GnomeVFSResult result,
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv,
+ sal_Bool bWrite = sal_False )
+ throw( ::com::sun::star::uno::Exception );
+
+
+public:
+ // Non-interface bits
+ char *getURI ();
+ rtl::OString getOURI ();
+ rtl::OUString getOUURI ();
+
+//=========================================================================
+// Externals
+//=========================================================================
+public:
+
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider *pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier)
+ throw ( ::com::sun::star::ucb::ContentCreationException );
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider *pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ sal_Bool isFolder)
+ throw ( ::com::sun::star::ucb::ContentCreationException );
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ queryCreatableContentsInfo(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv)
+ throw( com::sun::star::uno::RuntimeException );
+};
+
+}
+
+extern "C" {
+ extern GPrivate *auth_queue;
+ extern void auth_queue_destroy( gpointer data );
+}
+
+#endif
diff --git a/ucb/source/ucp/gvfs/gvfs_directory.cxx b/ucb/source/ucp/gvfs/gvfs_directory.cxx
new file mode 100644
index 000000000000..b93f34d9003f
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_directory.cxx
@@ -0,0 +1,423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/*
+ * This file pinched from webdavdatasupplier (etc.)
+ * cut & paste + new getData impl. & collate ResultSet code.
+ */
+#include <vector>
+#include <osl/diagnose.h>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+
+#include "gvfs_directory.hxx"
+
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-directory.h>
+
+using namespace com::sun::star;
+using namespace gvfs;
+
+// DynamicResultSet Implementation.
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand,
+ const uno::Reference< ucb::XCommandEnvironment >& rxEnv )
+ : ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv )
+{
+}
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+}
+void DynamicResultSet::initDynamic()
+{
+ initStatic();
+ m_xResultSet2 = m_xResultSet1;
+}
+
+//=========================================================================
+
+
+// DataSupplier Implementation.
+
+
+
+struct ResultListEntry
+{
+ rtl::OUString aId;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+ GnomeVFSFileInfo aInfo;
+
+ ResultListEntry( const GnomeVFSFileInfo *fileInfo)
+ {
+ gnome_vfs_file_info_copy (&aInfo, fileInfo);
+ }
+
+ ~ResultListEntry()
+ {
+ gnome_vfs_file_info_clear (&aInfo);
+ }
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct gvfs::DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
+ ~DataSupplier_Impl()
+ {
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+ }
+};
+
+DataSupplier::DataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+DataSupplier::~DataSupplier()
+{
+ delete m_pImpl;
+}
+
+// virtual
+rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() ) {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
+ if ( aId.getLength() ) // cached
+ return aId;
+ }
+
+ if ( getResult( nIndex ) ) {
+ rtl::OUString aId = m_pImpl->m_xContent->getOUURI();
+
+ char *escaped_name;
+ escaped_name = gnome_vfs_escape_string( m_pImpl->m_aResults[ nIndex ]->aInfo.name );
+
+ if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ aId += rtl::OUString::createFromAscii( escaped_name );
+
+ g_free( escaped_name );
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+
+ return rtl::OUString();
+}
+
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() ) {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() ) // Already cached.
+ return xId;
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() ) {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+// virtual
+uno::Reference< ucb::XContent >
+DataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() ) {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() ) // Already cached.
+ return xContent;
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() ) {
+ try
+ {
+ // FIXME:
+ // It would be really nice to propagate this information
+ // to the Content, but we can't then register it with the
+ // ContentProvider, and the ucbhelper hinders here.
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException& ) {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+// virtual
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex ) // Result already present.
+ return sal_True;
+
+ if ( getData() && m_pImpl->m_aResults.size() > nIndex )
+ return sal_True;
+
+ return sal_False;
+}
+
+// virtual
+sal_uInt32 DataSupplier::totalCount()
+{
+ getData();
+
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ return m_pImpl->m_aResults.size();
+}
+
+// virtual
+sal_uInt32 DataSupplier::currentCount()
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ return m_pImpl->m_aResults.size();
+}
+
+// virtual
+sal_Bool DataSupplier::isCountFinal()
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+ return m_pImpl->m_bCountFinal;
+}
+
+// virtual
+uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() ) {
+ uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() ) // Already cached.
+ return xRow;
+ }
+
+ if ( getResult( nIndex ) ) {
+ // Inefficient - but we can't create xContent's sensibly
+ // nor can we do the property code sensibly cleanly staticaly.
+ Content *pContent = static_cast< ::gvfs::Content * >(queryContent( nIndex ).get());
+
+ uno::Reference< sdbc::XRow > xRow =
+ pContent->getPropertyValues( getResultSet()->getProperties(),
+ getResultSet()->getEnvironment() );
+
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+// virtual
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+// virtual
+void DataSupplier::close()
+{
+}
+
+// virtual
+void DataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+}
+
+sal_Bool DataSupplier::getData()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( !m_pImpl->m_bCountFinal ) {
+ GnomeVFSResult result;
+ GnomeVFSDirectoryHandle *dirHandle = NULL;
+
+ {
+ Authentication aAuth( getResultSet()->getEnvironment() );
+ char *uri = m_pImpl->m_xContent->getURI();
+ result = gnome_vfs_directory_open
+ ( &dirHandle, uri, GNOME_VFS_FILE_INFO_DEFAULT );
+
+ if (result != GNOME_VFS_OK) {
+#ifdef DEBUG
+ g_warning ("Failed open of '%s' with '%s'",
+ uri, gnome_vfs_result_to_string( result ));
+#endif
+ g_free( uri );
+ return sal_False;
+ }
+
+ g_free( uri );
+ }
+
+ GnomeVFSFileInfo* fileInfo = gnome_vfs_file_info_new ();
+
+ while ((result = gnome_vfs_directory_read_next (dirHandle, fileInfo)) == GNOME_VFS_OK) {
+ if( fileInfo->name && fileInfo->name[0] == '.' &&
+ ( fileInfo->name[1] == '\0' ||
+ ( fileInfo->name[1] == '.' && fileInfo->name[2] == '\0' ) ) )
+ continue;
+
+ switch ( m_pImpl->m_nOpenMode ) {
+ case ucb::OpenMode::FOLDERS:
+ if ( !(fileInfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) ||
+ fileInfo->type != GNOME_VFS_FILE_TYPE_DIRECTORY )
+ continue;
+ break;
+
+ case ucb::OpenMode::DOCUMENTS:
+ if ( !(fileInfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) ||
+ fileInfo->type != GNOME_VFS_FILE_TYPE_REGULAR )
+ continue;
+ break;
+
+ case ucb::OpenMode::ALL:
+ default:
+ break;
+ }
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( fileInfo ) );
+ }
+
+ gnome_vfs_file_info_unref (fileInfo);
+
+#ifdef DEBUG
+ g_warning ("Got %d directory entries", result);
+#endif
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ // Callback possible, because listeners may be informed!
+ aGuard.clear();
+ getResultSet()->rowCountFinal();
+
+ if (result != GNOME_VFS_ERROR_EOF) {
+#ifdef DEBUG
+ g_warning( "Failed read_next '%s'",
+ gnome_vfs_result_to_string( result ) );
+#endif
+ return sal_False;
+ }
+
+ result = gnome_vfs_directory_close (dirHandle);
+ if (result != GNOME_VFS_OK) {
+#ifdef DEBUG
+ g_warning( "Failed close '%s'",
+ gnome_vfs_result_to_string( result ) );
+#endif
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+
+
diff --git a/ucb/source/ucp/gvfs/gvfs_directory.hxx b/ucb/source/ucp/gvfs/gvfs_directory.hxx
new file mode 100644
index 000000000000..f914554f7736
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_directory.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _GVFS_UCP_RESULTSET_HXX
+#define _GVFS_UCP_RESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultset.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "gvfs_content.hxx"
+
+namespace gvfs {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+};
+
+
+struct DataSupplier_Impl;
+class DataSupplier : public ucbhelper::ResultSetDataSupplier
+{
+private:
+ gvfs::DataSupplier_Impl *m_pImpl;
+ sal_Bool getData();
+
+public:
+ DataSupplier( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode);
+
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+ virtual void close();
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/gvfs/gvfs_provider.cxx b/ucb/source/ucp/gvfs/gvfs_provider.cxx
new file mode 100644
index 000000000000..52376bf4153e
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_provider.cxx
@@ -0,0 +1,228 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <libgnomevfs/gnome-vfs-init.h>
+#include "gvfs_provider.hxx"
+#include "gvfs_content.hxx"
+
+using namespace com::sun::star;
+using namespace gvfs;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rSMgr )
+{
+}
+// sdafas
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ com::sun::star::ucb::XContentProvider );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ com::sun::star::ucb::XContentProvider );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( ContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.GnomeVFSContentProvider" ),
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContentProvider" ) );
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+uno::Reference< com::sun::star::ucb::XContent > SAL_CALL
+ContentProvider::queryContent(
+ const uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ uno::RuntimeException )
+{
+#ifdef DEBUG
+ g_warning ("QueryContent: '%s'",
+ (const sal_Char *)rtl::OUStringToOString
+ (Identifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8));
+#endif
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< com::sun::star::ucb::XContent > xContent
+ = queryExistingContent( Identifier ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ try
+ {
+ xContent = new ::gvfs::Content(m_xSMgr, this, Identifier );
+ registerNewContent( xContent );
+ }
+ catch ( com::sun::star::ucb::ContentCreationException const & )
+ {
+ throw com::sun::star::ucb::IllegalIdentifierException();
+ }
+
+ if ( !xContent->getIdentifier().is() )
+ throw com::sun::star::ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
+
+//============================ shlib entry points =============================================
+
+
+// cut and paste verbatim from webdav (that sucks).
+static sal_Bool
+writeInfo( void *pRegistryKey,
+ const rtl::OUString &rImplementationName,
+ uno::Sequence< rtl::OUString > const &rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try {
+ xKey = static_cast< registry::XRegistryKey * >
+ (pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & ) {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n ) {
+ try {
+ xKey->createKey( rServiceNames[ n ] );
+
+ } catch ( registry::InvalidRegistryException const & ) {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+extern "C" void SAL_CALL
+component_getImplementationEnvironment( const sal_Char **ppEnvTypeName,
+ uno_Environment **/*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" sal_Bool SAL_CALL
+component_writeInfo( void */*pServiceManager*/,
+ void *pRegistryKey )
+{
+ return pRegistryKey &&
+ writeInfo( pRegistryKey,
+ ::gvfs::ContentProvider::getImplementationName_Static(),
+ ::gvfs::ContentProvider::getSupportedServiceNames_Static() );
+}
+extern "C" void * SAL_CALL
+component_getFactory( const sal_Char *pImplName,
+ void *pServiceManager,
+ void */*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if (!gnome_vfs_initialized ())
+ gnome_vfs_init ();
+ if (!auth_queue)
+ auth_queue = g_private_new( auth_queue_destroy );
+ }
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr
+ (reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ if ( !::gvfs::ContentProvider::getImplementationName_Static().compareToAscii( pImplName ) )
+ xFactory = ::gvfs::ContentProvider::createServiceFactory( xSMgr );
+
+ if ( xFactory.is() ) {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+
diff --git a/ucb/source/ucp/gvfs/gvfs_provider.hxx b/ucb/source/ucp/gvfs/gvfs_provider.hxx
new file mode 100644
index 000000000000..fd9e7dfd7876
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_provider.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _PROVIDER_HXX_
+#define _PROVIDER_HXX_
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/beans/Property.hpp>
+#include <ucbhelper/providerhelper.hxx>
+
+namespace gvfs {
+
+class ContentProvider : public ::ucbhelper::ContentProviderImplHelper
+{
+public:
+ ContentProvider( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+
+};
+
+} /* namespace gvfs */
+
+#endif /* _PROVIDER_HXX_ */
+
diff --git a/ucb/source/ucp/gvfs/gvfs_stream.cxx b/ucb/source/ucp/gvfs/gvfs_stream.cxx
new file mode 100644
index 000000000000..ab0c6ed90fc0
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_stream.cxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "gvfs_stream.hxx"
+#include <rtl/memory.h>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+
+#include <libgnomevfs/gnome-vfs-ops.h>
+
+using namespace cppu;
+using namespace rtl;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace gvfs;
+
+Stream::Stream( GnomeVFSHandle *handle,
+ const GnomeVFSFileInfo *aInfo ) :
+ m_eof (sal_False),
+ m_bInputStreamCalled( sal_False ),
+ m_bOutputStreamCalled( sal_False )
+{
+ m_handle = handle;
+ gnome_vfs_file_info_copy (&m_info, aInfo);
+}
+
+Stream::~Stream( void )
+{
+ if (m_handle) {
+ gnome_vfs_close (m_handle);
+ m_handle = NULL;
+ }
+}
+
+Any Stream::queryInterface( const Type &type )
+ throw( RuntimeException )
+{
+ Any aRet = ::cppu::queryInterface
+ ( type,
+ static_cast< XStream * >( this ),
+ static_cast< XInputStream * >( this ),
+ static_cast< XOutputStream * >( this ),
+ static_cast< XSeekable * >( this ),
+ static_cast< XTruncate * >( this ) );
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
+}
+
+// -------------------------------------------------------------------
+// XStream
+// -------------------------------------------------------------------
+
+com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
+Stream::getInputStream( )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = true;
+ }
+ return Reference< XInputStream >( this );
+}
+
+com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
+Stream::getOutputStream( )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = true;
+ }
+ return Reference< XOutputStream >( this );
+}
+
+// -------------------------------------------------------------------
+// XInputStream
+// -------------------------------------------------------------------
+
+sal_Int32 SAL_CALL Stream::readBytes(
+ Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException )
+{
+ GnomeVFSResult result;
+ GnomeVFSFileSize nBytesRead = 0;
+
+ if( ! m_handle )
+ throw IOException();
+
+ if( m_eof ) {
+ aData.realloc( 0 );
+ return 0;
+ }
+
+ try {
+ aData.realloc( nBytesToRead );
+ } catch ( const Exception &e ) {
+ throw BufferSizeExceededException();
+ }
+
+ do {
+ result = gnome_vfs_read( m_handle, aData.getArray(),
+ nBytesToRead, &nBytesRead );
+ } while( result == GNOME_VFS_ERROR_INTERRUPTED );
+
+ if (result != GNOME_VFS_OK &&
+ result != GNOME_VFS_ERROR_EOF)
+ throwOnError( result );
+
+ if (result == GNOME_VFS_ERROR_EOF)
+ m_eof = sal_True;
+
+ aData.realloc( sal::static_int_cast<sal_uInt32>(nBytesRead) );
+
+ return sal::static_int_cast<sal_Int32>(nBytesRead);
+}
+
+sal_Int32 SAL_CALL Stream::readSomeBytes(
+ Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw( NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException )
+{
+ // Again - having 2 methods here just sucks; cf. filinpstr.cxx
+ // This can never be an effective non-blocking API - so why bother ?
+ return readBytes( aData, nMaxBytesToRead );
+}
+
+void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException )
+{
+ GnomeVFSResult result;
+
+ if( ! m_handle )
+ throw IOException();
+
+ result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_CURRENT, nBytesToSkip );
+
+ if ( result == GNOME_VFS_ERROR_BAD_PARAMETERS ||
+ result == GNOME_VFS_ERROR_NOT_SUPPORTED )
+ g_warning ("FIXME: just read them in ...");
+
+ throwOnError( result );
+}
+
+sal_Int32 SAL_CALL Stream::available( )
+ throw( NotConnectedException,
+ IOException,
+ RuntimeException )
+{
+ return 0; // cf. filinpstr.cxx
+}
+
+void SAL_CALL Stream::closeInput( void )
+ throw( NotConnectedException,
+ IOException,
+ RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = false;
+
+ if( ! m_bOutputStreamCalled )
+ closeStream();
+}
+
+// -------------------------------------------------------------------
+// XSeekable
+// -------------------------------------------------------------------
+
+void SAL_CALL Stream::seek( sal_Int64 location )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ IOException,
+ RuntimeException )
+{
+ GnomeVFSResult result;
+
+ if( ! m_handle )
+ throw IOException();
+
+ if ( location < 0 )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ m_eof = sal_False;
+ result = gnome_vfs_seek( m_handle, GNOME_VFS_SEEK_START, location );
+
+ if (result == GNOME_VFS_ERROR_EOF)
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ throwOnError( result );
+}
+
+sal_Int64 SAL_CALL Stream::getPosition()
+ throw( IOException,
+ RuntimeException )
+{
+ GnomeVFSFileSize nBytesIn = 0;
+
+ if( ! m_handle )
+ throw IOException();
+
+ throwOnError( gnome_vfs_tell( m_handle, &nBytesIn ) );
+
+ return nBytesIn;
+}
+
+sal_Int64 SAL_CALL Stream::getLength()
+ throw( IOException, RuntimeException )
+{
+ // FIXME: so this sucks; it may be stale but ...
+ if (m_info.valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
+ return m_info.size;
+ else {
+ g_warning ("FIXME: No valid length");
+ return 0;
+ }
+}
+
+// -------------------------------------------------------------------
+// XTruncate
+// -------------------------------------------------------------------
+
+void SAL_CALL Stream::truncate( void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException )
+{
+ if( ! m_handle )
+ throw IOException();
+
+ throwOnError( gnome_vfs_truncate_handle( m_handle, 0 ) );
+}
+
+// -------------------------------------------------------------------
+// XOutputStream
+// -------------------------------------------------------------------
+
+void SAL_CALL Stream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException)
+{
+ GnomeVFSResult result = GNOME_VFS_OK;
+ GnomeVFSFileSize toWrite = aData.getLength();
+ const sal_Int8 *p = aData.getConstArray();
+
+ if( ! m_handle )
+ throw IOException();
+
+ while( toWrite > 0) {
+ GnomeVFSFileSize bytesWritten = 0;
+
+ result = gnome_vfs_write( m_handle, p, toWrite, &bytesWritten );
+ if( result == GNOME_VFS_ERROR_INTERRUPTED )
+ continue;
+ throwOnError( result );
+ g_assert( bytesWritten <= toWrite );
+ toWrite -= bytesWritten;
+ p += bytesWritten;
+ }
+}
+
+void SAL_CALL Stream::flush( void )
+ throw( NotConnectedException, BufferSizeExceededException,
+ IOException, RuntimeException )
+{
+}
+
+void SAL_CALL Stream::closeOutput( void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = false;
+
+ if( ! m_bInputStreamCalled )
+ closeStream();
+}
+
+// -------------------------------------------------------------------
+// Misc.
+// -------------------------------------------------------------------
+
+void Stream::closeStream( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ if (m_handle) {
+ gnome_vfs_close (m_handle);
+ m_handle = NULL;
+ } else
+ throw IOException();
+}
+
+void Stream::throwOnError( GnomeVFSResult result )
+ throw( NotConnectedException,
+ BufferSizeExceededException,
+ IOException,
+ RuntimeException )
+{
+ if( result != GNOME_VFS_OK ) {
+ ::rtl::OUString aMsg = ::rtl::OUString::createFromAscii
+ ( gnome_vfs_result_to_string( result ) );
+
+ g_warning( "Input Stream exceptional result '%s' (%d)",
+ gnome_vfs_result_to_string( result ), result );
+
+ throw IOException( aMsg, static_cast< cppu::OWeakObject * >( this ) );
+ }
+}
diff --git a/ucb/source/ucp/gvfs/gvfs_stream.hxx b/ucb/source/ucp/gvfs/gvfs_stream.hxx
new file mode 100644
index 000000000000..93815f6b2321
--- /dev/null
+++ b/ucb/source/ucp/gvfs/gvfs_stream.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _GVFSSTREAM_HXX_
+#define _GVFSSTREAM_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include <libgnomevfs/gnome-vfs-handle.h>
+
+namespace gvfs
+{
+
+class Stream : public ::com::sun::star::io::XStream,
+ public ::com::sun::star::io::XInputStream,
+ public ::com::sun::star::io::XOutputStream,
+ public ::com::sun::star::io::XTruncate,
+ public ::com::sun::star::io::XSeekable,
+ public ::cppu::OWeakObject
+{
+private:
+ GnomeVFSHandle *m_handle;
+ GnomeVFSFileInfo m_info;
+ osl::Mutex m_aMutex;
+ sal_Bool m_eof;
+ sal_Bool m_bInputStreamCalled;
+ sal_Bool m_bOutputStreamCalled;
+
+ void throwOnError( GnomeVFSResult result )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ void closeStream( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+public:
+ Stream ( GnomeVFSHandle *handle,
+ const GnomeVFSFileInfo *aInfo );
+ virtual ~Stream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & type )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire( void )
+ throw ()
+ { OWeakObject::acquire(); }
+ virtual void SAL_CALL release( void )
+ throw()
+ { OWeakObject::release(); }
+
+ // XStream
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL readSomeBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL available( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL closeInput( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getPosition()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL flush( void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+
+ virtual void SAL_CALL closeOutput( void )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTruncate
+ virtual void SAL_CALL truncate( void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+};
+
+} // namespace gvfs
+#endif // _GVFSSTREAM_HXX_
diff --git a/ucb/source/ucp/gvfs/makefile.mk b/ucb/source/ucp/gvfs/makefile.mk
new file mode 100644
index 000000000000..a0e8a0bda3bb
--- /dev/null
+++ b/ucb/source/ucp/gvfs/makefile.mk
@@ -0,0 +1,86 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+# Version
+UCPGVFS_MAJOR=1
+TARGET=ucpgvfs
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+UNIXTEXT=$(MISC)/$(TARGET)-ucd.txt
+
+.IF "$(ENABLE_GNOMEVFS)"!=""
+COMPILER_WARN_ALL=TRUE
+PKGCONFIG_MODULES=gnome-vfs-2.0
+.INCLUDE: pkg_config.mk
+
+.IF "$(OS)" == "SOLARIS"
+LINKFLAGS+=-z nodefs
+.ENDIF # "$(OS)" == "SOLARIS"
+
+.IF "$(OS)" == "LINUX"
+# hack for faked SO environment
+CFLAGS+=-gdwarf-2
+PKGCONFIG_LIBS!:=-Wl,--export-dynamic $(PKGCONFIG_LIBS:s/ -llinc//:s/ -lbonobo-activation//:s/ -lgconf-2//:s/ -lORBit-2//:s/ -lIDL-2//:s/ -lgmodule-2.0//:s/ -lgobject-2.0//:s/ -lgthread-2.0//)
+.ENDIF # "$(OS)" == "LINUX"
+
+# no "lib" prefix
+DLLPRE =
+
+SLOFILES=\
+ $(SLO)$/gvfs_content.obj \
+ $(SLO)$/gvfs_directory.obj \
+ $(SLO)$/gvfs_stream.obj \
+ $(SLO)$/gvfs_provider.obj
+
+SHL1NOCHECK=TRUE
+SHL1TARGET=$(TARGET)$(UCPGVFS_MAJOR).uno
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1IMPLIB=i$(TARGET)
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1STDLIBS+=$(PKGCONFIG_LIBS)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+.ENDIF # "$(ENABLE_GNOMEVFS)"!=""
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/gvfs/ucpgvfs-ucd.txt b/ucb/source/ucp/gvfs/ucpgvfs-ucd.txt
new file mode 100644
index 000000000000..e9ecce6effd2
--- /dev/null
+++ b/ucb/source/ucp/gvfs/ucpgvfs-ucd.txt
@@ -0,0 +1,6 @@
+[ComponentDescriptor]
+ImplementationName=com.sun.star.comp.GnomeVFSContentProvider
+ComponentName=ucpgvfs1.uno.so
+LoaderName=com.sun.star.loader.SharedLibrary
+[SupportedServices]
+com.sun.star.ucb.GnomeVFSContentProvider
diff --git a/ucb/source/ucp/gvfs/ucpgvfs.xml b/ucb/source/ucp/gvfs/ucpgvfs.xml
new file mode 100644
index 000000000000..e1f33708f525
--- /dev/null
+++ b/ucb/source/ucp/gvfs/ucpgvfs.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpgvfs
+ </module-name>
+
+ <component-description>
+ <author>
+ Michael Meeks
+ </author>
+ <name>
+ com.sun.star.comp.ucb.GnomeVFSProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to the Gnome Virtual file system
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.GnomeVFSContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.config.SpecialConfigManager
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationAccess
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.script.Converter
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.ucb.CachedDynamicResultSetStubFactory
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.ucb.Store
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.Property </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertySetInfoChange </type>
+ <type> com.sun.star.beans.PropertyState </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfo </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.frame.ConfigManager </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XActiveDataStreamer </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.io.XStream </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com/sun/star/sdbc/ColumnValue </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentAction </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.FileSystemNotation </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.ListAction </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NumberedSortingInfo </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentIdentifier </type>
+ <type> com.sun.star.ucb.XContentIdentifierFactory </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XFileIdentifierConverter </type>
+ <type> com.sun.star.ucb.XPropertySetRegistryFactory </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.uno.XWeak </type>
+</module-description>
diff --git a/ucb/source/ucp/hierarchy/dynamicresultset.cxx b/ucb/source/ucp/hierarchy/dynamicresultset.cxx
new file mode 100644
index 000000000000..0cb8fec28e17
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/dynamicresultset.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+#include "hierarchydatasupplier.hxx"
+#include "dynamicresultset.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new HierarchyResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new HierarchyResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/hierarchy/dynamicresultset.hxx b/ucb/source/ucp/hierarchy/dynamicresultset.hxx
new file mode 100644
index 000000000000..9553b299b0ad
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/dynamicresultset.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DYNAMICRESULTSET_HXX
+#define _DYNAMICRESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "hierarchycontent.hxx"
+
+namespace hierarchy_ucp {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< HierarchyContent > m_xContent;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand );
+};
+
+}
+
+#endif /* !_DYNAMICRESULTSET_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchycontent.cxx b/ucb/source/ucp/hierarchy/hierarchycontent.cxx
new file mode 100644
index 000000000000..2243692549e6
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontent.cxx
@@ -0,0 +1,2009 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - optimize transfer command. "Move" should be implementable much more
+ efficient!
+
+ **************************************************************************
+
+ - Root Folder vs. 'normal' Folder
+ - root doesn't support command 'delete'
+ - root doesn't support command 'insert'
+ - root needs not created via XContentCreator - queryContent with root
+ folder id ( HIERARCHY_ROOT_FOLDER_URL ) always returns a value != 0
+ - root has no parent.
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include "hierarchycontent.hxx"
+#include "hierarchyprovider.hxx"
+#include "dynamicresultset.hxx"
+#include "hierarchyuri.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContent Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static ( "virtual" ctor )
+HierarchyContent* HierarchyContent::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ // Fail, if content does not exist.
+ HierarchyContentProperties aProps;
+ if ( !loadData( rxSMgr, pProvider, Identifier, aProps ) )
+ return 0;
+
+ return new HierarchyContent( rxSMgr, pProvider, Identifier, aProps );
+}
+
+//=========================================================================
+// static ( "virtual" ctor )
+HierarchyContent* HierarchyContent::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+{
+ if ( !Info.Type.getLength() )
+ return 0;
+
+ if ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_FOLDER_CONTENT_TYPE ) ) &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_LINK_CONTENT_TYPE ) ) )
+ return 0;
+
+#if 0
+ // Fail, if content does exist.
+ if ( hasData( rxSMgr, pProvider, Identifier ) )
+ return 0;
+#endif
+
+ return new HierarchyContent( rxSMgr, pProvider, Identifier, Info );
+}
+
+//=========================================================================
+HierarchyContent::HierarchyContent(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const HierarchyContentProperties& rProps )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( rProps ),
+ m_eState( PERSISTENT ),
+ m_pProvider( pProvider ),
+ m_bCheckedReadOnly( false ),
+ m_bIsReadOnly( true )
+{
+ setKind( Identifier );
+}
+
+//=========================================================================
+HierarchyContent::HierarchyContent(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_FOLDER_CONTENT_TYPE ) )
+ ? HierarchyEntryData::FOLDER
+ : HierarchyEntryData::LINK ),
+ m_eState( TRANSIENT ),
+ m_pProvider( pProvider ),
+ m_bCheckedReadOnly( false ),
+ m_bIsReadOnly( true )
+{
+ setKind( Identifier );
+}
+
+//=========================================================================
+// virtual
+HierarchyContent::~HierarchyContent()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyContent::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyContent::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL HierarchyContent::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = ContentImplHelper::queryInterface( rType );
+
+ if ( !aRet.hasValue() )
+ {
+ // Note: isReadOnly may be relative expensive. So avoid calling it
+ // unless it is really necessary.
+ aRet = cppu::queryInterface(
+ rType, static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ {
+ if ( !isFolder() || isReadOnly() )
+ return uno::Any();
+ }
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( HierarchyContent );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL HierarchyContent::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( isFolder() && !isReadOnly() )
+ {
+ static cppu::OTypeCollection* pFolderTypes = 0;
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pFolderTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pDocumentTypes = 0;
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pDocumentTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL HierarchyContent::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL
+HierarchyContent::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+
+ if ( m_eKind == LINK )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_LINK_CONTENT_SERVICE_NAME );
+ else if ( m_eKind == FOLDER )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_FOLDER_CONTENT_SERVICE_NAME );
+ else
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME );
+
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL HierarchyContent::getContentType()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getContentType();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+HierarchyContent::getIdentifier()
+ throw( uno::RuntimeException )
+{
+ // Transient?
+ if ( m_eState == TRANSIENT )
+ {
+ // Transient contents have no identifier.
+ return uno::Reference< ucb::XContentIdentifier >();
+ }
+
+ return ContentImplHelper::getIdentifier();
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL HierarchyContent::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "No properties!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getPropertySetInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getCommandInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) && isFolder() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, aOpenCommand );
+ aRet <<= xSet;
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) &&
+ ( m_eKind != ROOT ) && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ // ( Not available at root folder )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::InsertCommandArgument aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ sal_Int32 nNameClash = aArg.ReplaceExisting
+ ? ucb::NameClash::OVERWRITE
+ : ucb::NameClash::ERROR;
+ insert( nNameClash, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) &&
+ ( m_eKind != ROOT ) && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ // ( Not available at root folder )
+ //////////////////////////////////////////////////////////////////
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+ destroy( bDeletePhysical, Environment );
+
+ // Remove own and all children's persistent data.
+ if ( !removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ Environment,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) &&
+ isFolder() && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer
+ // ( Not available at link objects )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::TransferInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ transfer( aInfo, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) &&
+ isFolder() && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent
+ // ( Not available at link objects )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::ContentInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= createNewContent( aInfo );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyContent::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ // @@@ Generally, no action takes much time...
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+HierarchyContent::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getCreatableContentsInfo();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+HierarchyContent::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ if ( isFolder() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !Info.Type.getLength() )
+ return uno::Reference< ucb::XContent >();
+
+ sal_Bool bCreateFolder =
+ Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_FOLDER_CONTENT_TYPE ) );
+
+ if ( !bCreateFolder &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_LINK_CONTENT_TYPE ) ) )
+ return uno::Reference< ucb::XContent >();
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.getLength() > 0,
+ "HierarchyContent::createNewContent - empty identifier!" );
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ if ( bCreateFolder )
+ aURL += rtl::OUString::createFromAscii( "New_Folder" );
+ else
+ aURL += rtl::OUString::createFromAscii( "New_Link" );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
+
+ return create( m_xSMgr, m_pProvider, xId, Info );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "createNewContent called on non-folder object!" );
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+// virtual
+rtl::OUString HierarchyContent::getParentURL()
+{
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ return aUri.getParentUri();
+}
+
+//=========================================================================
+//static
+sal_Bool HierarchyContent::hasData(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+
+ // Am I a root folder?
+ HierarchyUri aUri( aURL );
+ if ( aUri.isRootFolder() )
+ {
+ // hasData must always return 'true' for root folder
+ // even if no persistent data exist!!!
+ return sal_True;
+ }
+
+ return HierarchyEntry( rxSMgr, pProvider, aURL ).hasData();
+}
+
+//=========================================================================
+//static
+sal_Bool HierarchyContent::loadData(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ HierarchyContentProperties& rProps )
+{
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+
+ // Am I a root folder?
+ HierarchyUri aUri( aURL );
+ if ( aUri.isRootFolder() )
+ {
+ rProps = HierarchyContentProperties( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ HierarchyEntry aEntry( rxSMgr, pProvider, aURL );
+ HierarchyEntryData aData;
+ if ( !aEntry.getData( aData ) )
+ return sal_False;
+
+ rProps = HierarchyContentProperties( aData );
+ }
+ return sal_True;
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::storeData()
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
+ return aEntry.setData( m_aProps.getHierarchyEntryData(), sal_True );
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::renameData(
+ const uno::Reference< ucb::XContentIdentifier >& xOldId,
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, xOldId->getContentIdentifier() );
+ return aEntry.move( xNewId->getContentIdentifier(),
+ m_aProps.getHierarchyEntryData() );
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::removeData()
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
+ return aEntry.remove();
+}
+
+//=========================================================================
+void HierarchyContent::setKind(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ if ( m_aProps.getIsFolder() )
+ {
+ // Am I a root folder?
+ HierarchyUri aUri( Identifier->getContentIdentifier() );
+ if ( aUri.isRootFolder() )
+ m_eKind = ROOT;
+ else
+ m_eKind = FOLDER;
+ }
+ else
+ m_eKind = LINK;
+}
+
+//=========================================================================
+bool HierarchyContent::isReadOnly()
+{
+ if ( !m_bCheckedReadOnly )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_bCheckedReadOnly )
+ {
+ m_bCheckedReadOnly = true;
+ m_bIsReadOnly = true;
+
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv
+ = m_pProvider->getConfigProvider( aUri.getService() );
+ if ( xConfigProv.is() )
+ {
+ uno::Sequence< rtl::OUString > aNames
+ = xConfigProv->getAvailableServiceNames();
+ sal_Int32 nCount = aNames.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ if ( aNames[ n ].equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+ ) ) )
+ {
+ m_bIsReadOnly = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return m_bIsReadOnly;
+}
+
+//=========================================================================
+uno::Reference< ucb::XContentIdentifier >
+HierarchyContent::makeNewIdentifier( const rtl::OUString& rTitle )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Assemble new content identifier...
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ rtl::OUString aNewURL = aUri.getParentUri();
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+ aNewURL += ::ucb_impl::urihelper::encodeSegment( rTitle );
+
+ return uno::Reference< ucb::XContentIdentifier >(
+ new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL ) );
+}
+
+//=========================================================================
+void HierarchyContent::queryChildren( HierarchyContentRefList& rChildren )
+{
+ if ( ( m_eKind != FOLDER ) && ( m_eKind != ROOT ) )
+ return;
+
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( aURL.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aURL += rtl::OUString::createFromAscii( "/" );
+ }
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) ||
+ ( nPos == ( aChildURL.getLength() - 1 ) ) )
+ {
+ // No further slashes/ only a final slash. It's a child!
+ rChildren.push_back(
+ HierarchyContentRef(
+ static_cast< HierarchyContent * >( xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Already persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyContent::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ OSL_ENSURE( sal_False, "HierarchyContent::exchangeIdentity - "
+ "Not supported by root folder!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+ if ( !hasData( xNewId ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ if ( m_eKind == FOLDER )
+ {
+ // Process instanciated children...
+
+ HierarchyContentRefList aChildren;
+ queryChildren( aChildren );
+
+ HierarchyContentRefList::const_iterator it = aChildren.begin();
+ HierarchyContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ HierarchyContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier > xOldChildId
+ = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ }
+ return sal_True;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "HierarchyContent::exchangeIdentity - "
+ "Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > HierarchyContent::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const HierarchyContentProperties& rData,
+ HierarchyContentProvider* pProvider,
+ const rtl::OUString& rContentId )
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ uno::Reference< beans::XPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ // Process Core properties.
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ xRow->appendString ( rProp, rData.getContentType() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, rData.getTitle() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsDocument() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsFolder() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ xRow->appendObject(
+ rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "TargetURL" ) ) )
+ {
+ // TargetURL is only supported by links.
+
+ if ( rData.getIsDocument() )
+ xRow->appendString( rProp, rData.getTargetURL() );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ pProvider->getAdditionalPropertySet( rContentId,
+ sal_False ),
+ uno::UNO_QUERY );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ if ( !xRow->appendPropertySetValue(
+ xAdditionalPropSet,
+ rProp ) )
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ else
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ }
+ }
+ else
+ {
+ // Append all Core Properties.
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "ContentType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getContentType() );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ // @@@ Might actually be read-only!
+ beans::PropertyAttribute::BOUND ),
+ rData.getTitle() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsDocument() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsFolder() );
+
+ if ( rData.getIsDocument() )
+ xRow->appendString(
+ beans::Property( rtl::OUString::createFromAscii( "TargetURL" ),
+ -1,
+ getCppuType(
+ static_cast< const rtl::OUString * >( 0 ) ),
+ // @@@ Might actually be read-only!
+ beans::PropertyAttribute::BOUND ),
+ rData.getTargetURL() );
+ xRow->appendObject(
+ beans::Property(
+ rtl::OUString::createFromAscii( "CreatableContentsInfo" ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny( rData.getCreatableContentsInfo() ) );
+
+ // Append all Additional Core Properties.
+
+ uno::Reference< beans::XPropertySet > xSet(
+ pProvider->getAdditionalPropertySet( rContentId, sal_False ),
+ uno::UNO_QUERY );
+ xRow->appendPropertySet( xSet );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+//=========================================================================
+uno::Reference< sdbc::XRow > HierarchyContent::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return getPropertyValues( m_xSMgr,
+ rProperties,
+ m_aProps,
+ m_pProvider,
+ m_xIdentifier->getContentIdentifier() );
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > HierarchyContent::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+// aEvent.PropertyName =
+ aEvent.PropertyHandle = -1;
+// aEvent.OldValue =
+// aEvent.NewValue =
+
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+
+ uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ sal_Bool bExchange = sal_False;
+ rtl::OUString aOldTitle;
+ rtl::OUString aOldName;
+ sal_Int32 nTitlePos = -1;
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+
+ if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ if ( isReadOnly() )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty titles!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.getTitle() )
+ {
+ // modified title -> modified URL -> exchange !
+ if ( m_eState == PERSISTENT )
+ bExchange = sal_True;
+
+ aOldTitle = m_aProps.getTitle();
+ aOldName = m_aProps.getName();
+
+ m_aProps.setTitle( aNewValue );
+ m_aProps.setName(
+ ::ucb_impl::urihelper::encodeSegment(
+ aNewValue ) );
+
+ // property change event will be set later...
+
+ // remember position within sequence of values
+ // (for error handling).
+ nTitlePos = n;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "TargetURL" ) ) )
+ {
+ if ( isReadOnly() )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // TargetURL is only supported by links.
+
+ if ( m_eKind == LINK )
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty target URL's!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.getTargetURL() )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue
+ = uno::makeAny( m_aProps.getTargetURL() );
+ aEvent.NewValue
+ = uno::makeAny( aNewValue );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+
+ m_aProps.setTargetURL( aNewValue );
+ nChanged++;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty target URL not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "TargetURL only supported by links!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet = getAdditionalPropertySet( sal_False );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ try
+ {
+ uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
+ rValue.Name );
+ if ( aOldValue != rValue.Value )
+ {
+ xAdditionalPropSet->setPropertyValue(
+ rValue.Name, rValue.Value );
+
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = aOldValue;
+ aEvent.NewValue = rValue.Value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( beans::PropertyVetoException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::IllegalArgumentException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= uno::Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+
+ if ( bExchange )
+ {
+ uno::Reference< ucb::XContentIdentifier > xOldId
+ = m_xIdentifier;
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = makeNewIdentifier( m_aProps.getTitle() );
+
+ aGuard.clear();
+ if ( exchangeIdentity( xNewId ) )
+ {
+ // Adapt persistent data.
+ renameData( xOldId, xNewId );
+
+ // Adapt Additional Core Properties.
+ renameAdditionalPropertySet( xOldId->getContentIdentifier(),
+ xNewId->getContentIdentifier(),
+ sal_True );
+ }
+ else
+ {
+ // Roll-back.
+ m_aProps.setTitle( aOldTitle );
+ m_aProps.setName ( aOldName );
+
+ aOldTitle = aOldName = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= uno::Exception(
+ rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if ( aOldTitle.getLength() )
+ {
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( aOldTitle );
+ aEvent.NewValue = uno::makeAny( m_aProps.getTitle() );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+
+ if ( nChanged > 0 )
+ {
+ // Save changes, if content was already made persistent.
+ if ( !bExchange && ( m_eState == PERSISTENT ) )
+ {
+ if ( !storeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ aChanges.realloc( nChanged );
+
+ aGuard.clear();
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+void HierarchyContent::insert( sal_Int32 nNameClashResolve,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not supported by root folder!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Check, if all required properties were set.
+ if ( m_aProps.getTitle().getLength() == 0 )
+ {
+ uno::Sequence< rtl::OUString > aProps( 1 );
+ aProps[ 0 ] = rtl::OUString::createFromAscii( "Title" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingPropertiesException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aProps ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Assemble new content identifier...
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = makeNewIdentifier( m_aProps.getTitle() );
+
+ // Handle possible name clash...
+
+ switch ( nNameClashResolve )
+ {
+ // fail.
+ case ucb::NameClash::ERROR:
+ if ( hasData( xId ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_aProps.getTitle() ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+
+ // replace existing object.
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case ucb::NameClash::RENAME:
+ if ( hasData( xId ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ rtl::OUString aNewId = xId->getContentIdentifier();
+ aNewId += rtl::OUString::createFromAscii( "_" );
+ aNewId += rtl::OUString::valueOf( ++nTry );
+ xId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewId );
+ }
+ while ( hasData( xId ) && ( nTry < 1000 ) );
+
+ if ( nTry == 1000 )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clash!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ else
+ {
+ rtl::OUString aNewTitle( m_aProps.getTitle() );
+ aNewTitle += rtl::OUString::createFromAscii( "_" );
+ aNewTitle += rtl::OUString::valueOf( nTry );
+ m_aProps.setTitle( aNewTitle );
+ }
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ default:
+ if ( hasData( xId ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+ }
+
+ // Identifier changed?
+ sal_Bool bNewId = ( xId->getContentIdentifier()
+ != m_xIdentifier->getContentIdentifier() );
+ m_xIdentifier = xId;
+
+ if ( !storeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii( "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ m_eState = PERSISTENT;
+
+ if ( bNewId )
+ {
+ aGuard.clear();
+ inserted();
+ }
+}
+
+//=========================================================================
+void HierarchyContent::destroy( sal_Bool bDeletePhysical,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not supported by root folder!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ m_eState = DEAD;
+
+ aGuard.clear();
+ deleted();
+
+ if ( m_eKind == FOLDER )
+ {
+ // Process instanciated children...
+
+ HierarchyContentRefList aChildren;
+ queryChildren( aChildren );
+
+ HierarchyContentRefList::const_iterator it = aChildren.begin();
+ HierarchyContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical, xEnv );
+ ++it;
+ }
+ }
+}
+
+//=========================================================================
+void HierarchyContent::transfer(
+ const ucb::TransferInfo& rInfo,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source a hierarchy content?
+ if ( ( rInfo.SourceURL.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 2 ) ||
+ ( rInfo.SourceURL.compareToAscii( HIERARCHY_URL_SCHEME ":/",
+ HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ != 0 ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source not a parent of me / not me?
+ rtl::OUString aId = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nPos = aId.lastIndexOf( '/' );
+ if ( nPos != ( aId.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aId += rtl::OUString::createFromAscii( "/" );
+ }
+
+ if ( rInfo.SourceURL.getLength() <= aId.getLength() )
+ {
+ if ( aId.compareTo(
+ rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(rInfo.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_RECURSIVE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Target is equal to or is a child of source!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 0) Obtain content object for source.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the HierarchyContentProvider.
+ rtl::Reference< HierarchyContent > xSource;
+
+ try
+ {
+ xSource = static_cast< HierarchyContent * >(
+ m_xProvider->queryContent( xId ).get() );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xSource.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(xId->getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate source object!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 1) Create new child content.
+ //////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aType = xSource->isFolder()
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE );
+ ucb::ContentInfo aContentInfo;
+ aContentInfo.Type = aType;
+ aContentInfo.Attributes = 0;
+
+ // Note: The static cast is okay here, because its sure that
+ // createNewContent always creates a HierarchyContent.
+ rtl::Reference< HierarchyContent > xTarget
+ = static_cast< HierarchyContent * >(
+ createNewContent( aContentInfo ).get() );
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(aId),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "XContentCreator::createNewContent failed!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 2) Copy data from source content to child content.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > aSourceProps
+ = xSource->getPropertySetInfo( xEnv )->getProperties();
+ sal_Int32 nCount = aSourceProps.getLength();
+
+ if ( nCount )
+ {
+ sal_Bool bHadTitle = ( rInfo.NewTitle.getLength() == 0 );
+
+ // Get all source values.
+ uno::Reference< sdbc::XRow > xRow
+ = xSource->getPropertyValues( aSourceProps );
+
+ uno::Sequence< beans::PropertyValue > aValues( nCount );
+ beans::PropertyValue* pValues = aValues.getArray();
+
+ const beans::Property* pProps = aSourceProps.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+ beans::PropertyValue& rValue = pValues[ n ];
+
+ rValue.Name = rProp.Name;
+ rValue.Handle = rProp.Handle;
+
+ if ( !bHadTitle && rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ // Set new title instead of original.
+ bHadTitle = sal_True;
+ rValue.Value <<= rInfo.NewTitle;
+ }
+ else
+ rValue.Value = xRow->getObject(
+ n + 1,
+ uno::Reference< container::XNameAccess >() );
+
+ rValue.State = beans::PropertyState_DIRECT_VALUE;
+
+ if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
+ {
+ // Add Additional Core Property.
+ try
+ {
+ xTarget->addProperty( rProp.Name,
+ rProp.Attributes,
+ rValue.Value );
+ }
+ catch ( beans::PropertyExistException const & )
+ {
+ }
+ catch ( beans::IllegalTypeException const & )
+ {
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ }
+ }
+ }
+
+ // Set target values.
+ xTarget->setPropertyValues( aValues, xEnv );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 3) Commit (insert) child.
+ //////////////////////////////////////////////////////////////////////
+
+ xTarget->insert( rInfo.NameClash, xEnv );
+
+ //////////////////////////////////////////////////////////////////////
+ // 4) Transfer (copy) children of source.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xSource->isFolder() )
+ {
+ HierarchyEntry aFolder(
+ m_xSMgr, m_pProvider, xId->getContentIdentifier() );
+ HierarchyEntry::iterator it;
+
+ while ( aFolder.next( it ) )
+ {
+ const HierarchyEntryData& rResult = *it;
+
+ rtl::OUString aChildId = xId->getContentIdentifier();
+ if ( ( aChildId.lastIndexOf( '/' ) + 1 ) != aChildId.getLength() )
+ aChildId += rtl::OUString::createFromAscii( "/" );
+
+ aChildId += rResult.getName();
+
+ ucb::TransferInfo aInfo;
+ aInfo.MoveData = sal_False;
+ aInfo.NewTitle = rtl::OUString();
+ aInfo.SourceURL = aChildId;
+ aInfo.NameClash = rInfo.NameClash;
+
+ // Transfer child to target.
+ xTarget->transfer( aInfo, xEnv );
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 5) Destroy source ( when moving only ) .
+ //////////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ xSource->destroy( sal_True, xEnv );
+
+ // Remove all persistent data of source and its children.
+ if ( !xSource->removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(
+ xSource->m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ xSource->removeAdditionalPropertySet( sal_True );
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+uno::Sequence< ucb::ContentInfo >
+HierarchyContentProperties::getCreatableContentsInfo() const
+{
+ if ( getIsFolder() )
+ {
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+
+ uno::Sequence< beans::Property > aFolderProps( 1 );
+ aFolderProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aSeq.getArray()[ 0 ].Properties = aFolderProps;
+
+ // Link.
+ aSeq.getArray()[ 1 ].Type
+ = rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_LINK;
+
+ uno::Sequence< beans::Property > aLinkProps( 2 );
+ aLinkProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aLinkProps.getArray()[ 1 ] = beans::Property(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aSeq.getArray()[ 1 ].Properties = aLinkProps;
+
+ return aSeq;
+ }
+ else
+ {
+ return uno::Sequence< ucb::ContentInfo >( 0 );
+ }
+}
diff --git a/ucb/source/ucp/hierarchy/hierarchycontent.hxx b/ucb/source/ucp/hierarchy/hierarchycontent.hxx
new file mode 100644
index 000000000000..5b7360a87719
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontent.hxx
@@ -0,0 +1,311 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYCONTENT_HXX
+#define _HIERARCHYCONTENT_HXX
+
+#include <list>
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+#include "hierarchydata.hxx"
+#include "hierarchyprovider.hxx"
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+ struct PropertyValue;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class XRow;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ struct TransferInfo;
+} } } }
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+
+#define HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyRootFolderContent"
+#define HIERARCHY_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyFolderContent"
+#define HIERARCHY_LINK_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyLinkContent"
+
+//=========================================================================
+
+class HierarchyContentProperties
+{
+public:
+ HierarchyContentProperties() {};
+
+ HierarchyContentProperties( const HierarchyEntryData::Type & rType )
+ : m_aData( rType ),
+ m_aContentType( rType == HierarchyEntryData::FOLDER
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) ) {}
+
+ HierarchyContentProperties( const HierarchyEntryData & rData )
+ : m_aData( rData ),
+ m_aContentType( rData.getType() == HierarchyEntryData::FOLDER
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) ) {}
+
+ const rtl::OUString & getName() const { return m_aData.getName(); }
+ void setName( const rtl::OUString & rName ) { m_aData.setName( rName ); };
+
+ const rtl::OUString & getTitle() const { return m_aData.getTitle(); }
+ void setTitle( const rtl::OUString & rTitle )
+ { m_aData.setTitle( rTitle ); };
+
+ const rtl::OUString & getTargetURL() const
+ { return m_aData.getTargetURL(); }
+ void setTargetURL( const rtl::OUString & rURL )
+ { m_aData.setTargetURL( rURL ); };
+
+ const rtl::OUString & getContentType() const { return m_aContentType; }
+
+ sal_Bool getIsFolder() const
+ { return m_aData.getType() == HierarchyEntryData::FOLDER; }
+
+ sal_Bool getIsDocument() const { return !getIsFolder(); }
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ getCreatableContentsInfo() const;
+
+ const HierarchyEntryData & getHierarchyEntryData() const { return m_aData; }
+
+private:
+ HierarchyEntryData m_aData;
+ rtl::OUString m_aContentType;
+};
+
+//=========================================================================
+
+class HierarchyContentProvider;
+
+class HierarchyContent : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ContentKind { LINK, FOLDER, ROOT };
+ enum ContentState { TRANSIENT, // created via CreateNewContent,
+ // but did not process "insert" yet
+ PERSISTENT, // processed "insert"
+ DEAD // processed "delete"
+ };
+
+ HierarchyContentProperties m_aProps;
+ ContentKind m_eKind;
+ ContentState m_eState;
+ HierarchyContentProvider* m_pProvider;
+ bool m_bCheckedReadOnly;
+ bool m_bIsReadOnly;
+
+private:
+ HierarchyContent(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const HierarchyContentProperties& rProps );
+ HierarchyContent(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ static sal_Bool hasData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+ sal_Bool hasData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ { return hasData( m_xSMgr, m_pProvider, Identifier ); }
+ static sal_Bool loadData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ HierarchyContentProperties& rProps );
+ sal_Bool storeData();
+ sal_Bool renameData( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xOldId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xNewId );
+ sal_Bool removeData();
+
+ void setKind( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ bool isReadOnly();
+
+ sal_Bool isFolder() const { return ( m_eKind > LINK ); }
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >
+ makeNewIdentifier( const rtl::OUString& rTitle );
+
+ typedef rtl::Reference< HierarchyContent > HierarchyContentRef;
+ typedef std::list< HierarchyContentRef > HierarchyContentRefList;
+ void queryChildren( HierarchyContentRefList& rChildren );
+
+ sal_Bool exchangeIdentity(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void insert( sal_Int32 nNameClashResolve,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void destroy( sal_Bool bDeletePhysical,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void transfer( const ::com::sun::star::ucb::TransferInfo& rInfo,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+public:
+ // Create existing content. Fail, if not already exists.
+ static HierarchyContent* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ // Create new content. Fail, if already exists.
+ static HierarchyContent* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual ~HierarchyContent();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ getIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const HierarchyContentProperties& rData,
+ HierarchyContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYCONTENT_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx b/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx
new file mode 100644
index 000000000000..a5371c213f1c
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx
@@ -0,0 +1,765 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ **************************************************************************
+
+ Props/Commands:
+
+ root folder folder link link
+ (new) (new)
+ ----------------------------------------------------------------
+ ContentType x x x x x
+ IsDocument x x x x x
+ IsFolder x x x x x
+ Title x x x x x
+ TargetURL x x
+ CreatableContentsInfo x x x x x
+
+ getCommandInfo x x x x x
+ getPropertySetInfo x x x x x
+ getPropertyValues x x x x x
+ setPropertyValues x x x x x
+ createNewContent x x
+ insert x x
+ delete x x
+ open x x
+ transfer x x
+
+ *************************************************************************/
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "hierarchycontent.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//
+// HierarchyContent implementation.
+//
+//=========================================================================
+
+#define MAKEPROPSEQUENCE( a ) \
+ uno::Sequence< beans::Property >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+#define MAKECMDSEQUENCE( a ) \
+ uno::Sequence< ucb::CommandInfo >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+//=========================================================================
+//
+// IMPORTENT: If any property data ( name / type / ... ) are changed, then
+// HierarchyContent::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > HierarchyContent::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_eKind == LINK )
+ {
+ //=================================================================
+ //
+ // Link: Supported properties
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static beans::Property aLinkPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aLinkPropertyInfoTable );
+ }
+ else
+ {
+ static beans::Property aLinkPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aLinkPropertyInfoTable );
+ }
+ }
+ else if ( m_eKind == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported properties
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aFolderPropertyInfoTable );
+ }
+ else
+ {
+ static beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aFolderPropertyInfoTable );
+ }
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported properties
+ //
+ //=================================================================
+
+ // Currently no difference between reonly /read-write
+ // -> all props ar read-only
+
+ static beans::Property aRootFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY )
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aRootFolderPropertyInfoTable );
+ }
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > HierarchyContent::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_eKind == LINK )
+ {
+ //=================================================================
+ //
+ // Link: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aLinkCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aLinkCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aLinkCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aLinkCommandInfoTable );
+ }
+ }
+ else if ( m_eKind == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aFolderCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aFolderCommandInfoTable );
+ }
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aRootFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aRootFolderCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aRootFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aRootFolderCommandInfoTable );
+ }
+ }
+}
diff --git a/ucb/source/ucp/hierarchy/hierarchydata.cxx b/ucb/source/ucp/hierarchy/hierarchydata.cxx
new file mode 100644
index 000000000000..d2e8f5031527
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydata.cxx
@@ -0,0 +1,1266 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - HierarchyEntry::move
+ --> Rewrite to use XNamed ( once this is supported by config db api ).
+
+ *************************************************************************/
+#include "hierarchydata.hxx"
+
+#include <vector>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#ifndef _COM_SUN_STAR_UTIL_XOFFICEINSTALLTIONDIRECTORIES_HPP_
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#endif
+#include "hierarchyprovider.hxx"
+#include "hierarchyuri.hxx"
+
+using namespace com::sun::star;
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+struct HierarchyEntry::iterator_Impl
+{
+ HierarchyEntryData entry;
+ uno::Reference< container::XHierarchicalNameAccess > dir;
+ uno::Reference< util::XOfficeInstallationDirectories > officeDirs;
+ uno::Sequence< rtl::OUString> names;
+ sal_Int32 pos;
+ iterator_Impl()
+ : officeDirs( 0 ), pos( -1 /* before first */ ) {};
+};
+
+//=========================================================================
+void makeXMLName( const rtl::OUString & rIn, rtl::OUStringBuffer & rBuffer )
+{
+ sal_Int32 nCount = rIn.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = rIn.getStr()[ n ];
+ switch ( c )
+ {
+ case '&':
+ rBuffer.appendAscii( "&amp;" );
+ break;
+
+ case '"':
+ rBuffer.appendAscii( "&quot;" );
+ break;
+
+ case '\'':
+ rBuffer.appendAscii( "&apos;" );
+ break;
+
+ case '<':
+ rBuffer.appendAscii( "&lt;" );
+ break;
+
+ case '>':
+ rBuffer.appendAscii( "&gt;" );
+ break;
+
+ default:
+ rBuffer.append( c );
+ break;
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyEntry Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+#define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
+#define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+
+// describe path of cfg entry
+#define CFGPROPERTY_NODEPATH "nodepath"
+
+//=========================================================================
+HierarchyEntry::HierarchyEntry(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ HierarchyContentProvider* pProvider,
+ const rtl::OUString& rURL )
+: m_xSMgr( rSMgr ),
+ m_xOfficeInstDirs( pProvider->getOfficeInstallationDirectories() ),
+ m_bTriedToGetRootReadAccess( sal_False )
+{
+ HierarchyUri aUri( rURL );
+ m_aServiceSpecifier = aUri.getService();
+
+ if ( pProvider )
+ {
+ m_xConfigProvider
+ = pProvider->getConfigProvider( m_aServiceSpecifier );
+ m_xRootReadAccess
+ = pProvider->getRootConfigReadNameAccess( m_aServiceSpecifier );
+ }
+
+ // Note: do not init m_aPath in init list. createPathFromHierarchyURL
+ // needs m_xSMgr and m_aMutex.
+ m_aPath = createPathFromHierarchyURL( aUri );
+
+ // Extract language independent name from URL.
+ sal_Int32 nPos = rURL.lastIndexOf( '/' );
+ if ( nPos > HIERARCHY_URL_SCHEME_LENGTH )
+ m_aName = rURL.copy( nPos + 1 );
+ else
+ OSL_ENSURE( sal_False, "HierarchyEntry - Invalid URL!" );
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::hasData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
+ = getRootReadAccess();
+
+ OSL_ENSURE( xRootReadAccess.is(), "HierarchyEntry::hasData - No root!" );
+
+ if ( xRootReadAccess.is() )
+ return xRootReadAccess->hasByHierarchicalName( m_aPath );
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::getData( HierarchyEntryData& rData )
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
+ = getRootReadAccess();
+
+ OSL_ENSURE( xRootReadAccess.is(),
+ "HierarchyEntry::getData - No root!" );
+
+ if ( xRootReadAccess.is() )
+ {
+ rtl::OUString aTitlePath = m_aPath;
+ aTitlePath += rtl::OUString::createFromAscii( "/Title" );
+
+ // Note: Avoid NoSuchElementExceptions, because exceptions are
+ // relatively 'expensive'. Checking for availability of
+ // title value is sufficient here, because if it is
+ // there, the other values will be available too.
+ if ( !xRootReadAccess->hasByHierarchicalName( aTitlePath ) )
+ return sal_False;
+
+ rtl::OUString aValue;
+
+ // Get Title value.
+ if ( !( xRootReadAccess->getByHierarchicalName( aTitlePath )
+ >>= aValue ) )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Got no Title value!" );
+ return sal_False;
+ }
+
+ rData.setTitle( aValue );
+
+ // Get TargetURL value.
+ rtl::OUString aTargetURLPath = m_aPath;
+ aTargetURLPath += rtl::OUString::createFromAscii( "/TargetURL" );
+ if ( !( xRootReadAccess->getByHierarchicalName( aTargetURLPath )
+ >>= aValue ) )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Got no TargetURL value!" );
+ return sal_False;
+ }
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion directory must
+ // never be stored directly. A placeholder is used instead. Replace
+ // it by actual installation directory.
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_xOfficeInstDirs->makeAbsoluteURL( aValue );
+ rData.setTargetURL( aValue );
+
+ rtl::OUString aTypePath = m_aPath;
+ aTypePath += rtl::OUString::createFromAscii( "/Type" );
+ if ( xRootReadAccess->hasByHierarchicalName( aTypePath ) )
+ {
+ // Might not be present since it was introduced long after
+ // Title and TargetURL (#82433#)... So not getting it is
+ // not an error.
+
+ // Get Type value.
+ sal_Int32 nType = 0;
+ if ( xRootReadAccess->getByHierarchicalName( aTypePath )
+ >>= nType )
+ {
+ if ( nType == 0 )
+ {
+ rData.setType( HierarchyEntryData::LINK );
+ }
+ else if ( nType == 1 )
+ {
+ rData.setType( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Unknown Type value!" );
+ return sal_False;
+ }
+ }
+ }
+
+ rData.setName( m_aName );
+ return sal_True;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - caught NoSuchElementException!" );
+ }
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::setData(
+ const HierarchyEntryData& rData, sal_Bool bCreate )
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create parent's key. It must exist!
+
+ rtl::OUString aParentPath;
+ sal_Bool bRoot = sal_True;
+
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1,
+ "HierarchyEntry::setData - Wrong path!" );
+
+ aParentPath += m_aPath.copy( 0, nPos );
+ bRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< util::XChangesBatch > xBatch(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "HierarchyEntry::setData - No batch!" );
+
+ uno::Reference< container::XNameAccess > xParentNameAccess(
+ xBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNameAccess.is(),
+ "HierarchyEntry::setData - No name access!" );
+
+ if ( xBatch.is() && xParentNameAccess.is() )
+ {
+ // Try to create own key. It must not exist!
+
+ sal_Bool bExists = sal_True;
+ uno::Any aMyKey;
+
+ try
+ {
+ uno::Reference< container::XNameAccess > xNameAccess;
+
+ if ( bRoot )
+ {
+ xNameAccess = xParentNameAccess;
+ }
+ else
+ {
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xNameAccess;
+ }
+
+ if ( xNameAccess->hasByName( m_aName ) )
+ aMyKey = xNameAccess->getByName( m_aName );
+ else
+ bExists = sal_False;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ bExists = sal_False;
+ }
+
+ uno::Reference< container::XNameReplace > xNameReplace;
+ uno::Reference< container::XNameContainer > xContainer;
+
+ if ( bExists )
+ {
+ // Key exists. Replace values.
+
+ aMyKey >>= xNameReplace;
+
+ OSL_ENSURE( xNameReplace.is(),
+ "HierarchyEntry::setData - No name replace!" );
+ }
+ else
+ {
+ if ( !bCreate )
+ return sal_True;
+
+ // Key does not exist. Create / fill / insert it.
+
+ uno::Reference< lang::XSingleServiceFactory > xFac;
+
+ if ( bRoot )
+ {
+ // Special handling for children of root,
+ // which is not an entry. It's only a set
+ // of entries.
+ xFac = uno::Reference< lang::XSingleServiceFactory >(
+ xParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ // Append new entry to parents child list,
+ // which is a set of entries.
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii(
+ "Children" ) ) >>= xFac;
+ }
+
+ OSL_ENSURE( xFac.is(),
+ "HierarchyEntry::setData - No factory!" );
+
+ if ( xFac.is() )
+ {
+ xNameReplace
+ = uno::Reference< container::XNameReplace >(
+ xFac->createInstance(), uno::UNO_QUERY );
+
+ OSL_ENSURE( xNameReplace.is(),
+ "HierarchyEntry::setData - No name replace!" );
+
+ if ( xNameReplace.is() )
+ {
+ xContainer
+ = uno::Reference< container::XNameContainer >(
+ xFac, uno::UNO_QUERY );
+
+ OSL_ENSURE( xContainer.is(),
+ "HierarchyEntry::setData - No container!" );
+ }
+ }
+ }
+
+ if ( xNameReplace.is() )
+ {
+ // Set Title value.
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Title" ),
+ uno::makeAny( rData.getTitle() ) );
+
+ // Set TargetURL value.
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion
+ // directory must never be stored directly. Use a
+ // placeholder instead.
+ rtl::OUString aValue( rData.getTargetURL() );
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue
+ = m_xOfficeInstDirs->makeRelocatableURL( aValue );
+
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ uno::makeAny( aValue ) );
+
+ // Set Type value.
+ sal_Int32 nType
+ = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Type" ),
+ uno::makeAny( nType ) );
+
+ if ( xContainer.is() )
+ xContainer->insertByName(
+ m_aName, uno::makeAny( xNameReplace ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+ return sal_True;
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // replaceByName, insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught IllegalArgumentException!" );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // replaceByName, getByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught NoSuchElementException!" );
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught ElementExistException!" );
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // replaceByName, insertByName, getByName, commitChanges
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught WrappedTargetException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught Exception!" );
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::move(
+ const rtl::OUString& rNewURL, const HierarchyEntryData& rData )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ rtl::OUString aNewPath = createPathFromHierarchyURL( rNewURL );
+
+ if ( aNewPath == m_aPath )
+ return sal_True;
+
+#if 0
+ // In the "near future"... ( not yet implemented in config db )
+
+ - get update access for m_aPath
+ - update access -> XNamed
+ - xNamed::setName( newName )
+ - updateaccess commit
+#else
+
+ sal_Bool bOldRoot = sal_True;
+ uno::Reference< util::XChangesBatch > xOldParentBatch;
+
+ rtl::OUString aNewKey;
+ sal_Int32 nURLPos = rNewURL.lastIndexOf( '/' );
+ if ( nURLPos > HIERARCHY_URL_SCHEME_LENGTH )
+ aNewKey = rNewURL.copy( nURLPos + 1 );
+ else
+ {
+ OSL_ENSURE( sal_False, "HierarchyEntry::move - Invalid URL!" );
+ return sal_False;
+ }
+
+ sal_Bool bNewRoot = sal_True;
+ uno::Reference< util::XChangesBatch > xNewParentBatch;
+
+ sal_Bool bDifferentParents = sal_True;
+
+ try
+ {
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( !m_xConfigProvider.is() )
+ return sal_False;
+
+ rtl::OUString aOldParentPath;
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
+
+ aOldParentPath += m_aPath.copy( 0, nPos );
+ bOldRoot = sal_False;
+ }
+
+ rtl::OUString aNewParentPath;
+ nPos = aNewPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = aNewPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
+
+ aNewParentPath += aNewPath.copy( 0, nPos );
+ bNewRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aOldParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ xOldParentBatch = uno::Reference< util::XChangesBatch >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xOldParentBatch.is(), "HierarchyEntry::move - No batch!" );
+
+ if ( !xOldParentBatch.is() )
+ return sal_False;
+
+ if ( aOldParentPath == aNewParentPath )
+ {
+ bDifferentParents = sal_False;
+ xNewParentBatch = xOldParentBatch;
+ }
+ else
+ {
+ bDifferentParents = sal_True;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aNewParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ xNewParentBatch = uno::Reference< util::XChangesBatch >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE(
+ xNewParentBatch.is(), "HierarchyEntry::move - No batch!" );
+
+ if ( !xNewParentBatch.is() )
+ return sal_False;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False, "HierarchyEntry::move - caught Exception!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (1) Get entry...
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Any aEntry;
+ uno::Reference< container::XNameAccess > xOldParentNameAccess;
+ uno::Reference< container::XNameContainer > xOldNameContainer;
+
+ try
+ {
+ xOldParentNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xOldParentBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xOldParentNameAccess.is(),
+ "HierarchyEntry::move - No name access!" );
+
+ if ( !xOldParentNameAccess.is() )
+ return sal_False;
+
+ if ( bOldRoot )
+ {
+ xOldNameContainer = uno::Reference< container::XNameContainer >(
+ xOldParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ xOldParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xOldNameContainer;
+ }
+
+ aEntry = xOldNameContainer->getByName( m_aName );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (2) Remove entry... Note: Insert BEFORE remove does not work!
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ xOldNameContainer->removeByName( m_aName );
+ xOldParentBatch->commitChanges();
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName, removeByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (3) Insert entry at new parent...
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ uno::Reference< container::XNameReplace > xNewNameReplace;
+ aEntry >>= xNewNameReplace;
+
+ OSL_ENSURE( xNewNameReplace.is(),
+ "HierarchyEntry::move - No name replace!" );
+
+ if ( !xNewNameReplace.is() )
+ return sal_False;
+
+ uno::Reference< container::XNameAccess > xNewParentNameAccess;
+ if ( bDifferentParents )
+ xNewParentNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xNewParentBatch, uno::UNO_QUERY );
+ else
+ xNewParentNameAccess = xOldParentNameAccess;
+
+ OSL_ENSURE( xNewParentNameAccess.is(),
+ "HierarchyEntry::move - No name access!" );
+
+ if ( !xNewParentNameAccess.is() )
+ return sal_False;
+
+ uno::Reference< container::XNameContainer > xNewNameContainer;
+ if ( bDifferentParents )
+ {
+ if ( bNewRoot )
+ {
+ xNewNameContainer
+ = uno::Reference< container::XNameContainer >(
+ xNewParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ xNewParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xNewNameContainer;
+ }
+ }
+ else
+ xNewNameContainer = xOldNameContainer;
+
+ if ( !xNewNameContainer.is() )
+ return sal_False;
+
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Title" ),
+ uno::makeAny( rData.getTitle() ) );
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion
+ // directory must never be stored directly. Use a placeholder
+ // instead.
+ rtl::OUString aValue( rData.getTargetURL() );
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_xOfficeInstDirs->makeRelocatableURL( aValue );
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ uno::makeAny( aValue ) );
+ sal_Int32 nType = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Type" ),
+ uno::makeAny( nType ) );
+
+ xNewNameContainer->insertByName( aNewKey, aEntry );
+ xNewParentBatch->commitChanges();
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // replaceByName, insertByName, getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // replaceByName, insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::move - caught IllegalArgumentException!" );
+ return sal_False;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught ElementExistException!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // replaceByName, insertByName, getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+
+#if 0
+ //////////////////////////////////////////////////////////////////////
+ // (4) Commit changes...
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ xNewParentBatch->commitChanges();
+
+ if ( bDifferentParents )
+ xOldParentBatch->commitChanges();
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // commitChanges
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+#endif
+
+ return sal_True;
+#endif
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::remove()
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create parent's key. It must exist!
+
+ rtl::OUString aParentPath;
+ sal_Bool bRoot = sal_True;
+
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1,
+ "HierarchyEntry::remove - Wrong path!" );
+
+ aParentPath += m_aPath.copy( 0, nPos );
+ bRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< util::XChangesBatch > xBatch(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "HierarchyEntry::remove - No batch!" );
+
+ uno::Reference< container::XNameAccess > xParentNameAccess(
+ xBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNameAccess.is(),
+ "HierarchyEntry::remove - No name access!" );
+
+ if ( xBatch.is() && xParentNameAccess.is() )
+ {
+ uno::Reference< container::XNameContainer > xContainer;
+
+ if ( bRoot )
+ {
+ // Special handling for children of root,
+ // which is not an entry. It's only a set
+ // of entries.
+ xContainer = uno::Reference< container::XNameContainer >(
+ xParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ // Append new entry to parents child list,
+ // which is a set of entries.
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xContainer;
+ }
+
+ OSL_ENSURE( xContainer.is(),
+ "HierarchyEntry::remove - No container!" );
+
+ if ( xContainer.is() )
+ {
+ xContainer->removeByName( m_aName );
+ xBatch->commitChanges();
+ return sal_True;
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName, removeByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::remove - caught NoSuchElementException!" );
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // getByName, commitChanges
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::remove - caught WrappedTargetException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::remove - caught Exception!" );
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::first( iterator& it )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( it.m_pImpl->pos == -1 )
+ {
+ // Init...
+
+ try
+ {
+ uno::Reference< container::XHierarchicalNameAccess >
+ xRootHierNameAccess = getRootReadAccess();
+
+ if ( xRootHierNameAccess.is() )
+ {
+ uno::Reference< container::XNameAccess > xNameAccess;
+
+ if ( m_aPath.getLength() > 0 )
+ {
+ rtl::OUString aPath = m_aPath;
+ aPath += rtl::OUString::createFromAscii( "/Children" );
+
+ xRootHierNameAccess->getByHierarchicalName( aPath )
+ >>= xNameAccess;
+ }
+ else
+ xNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xRootHierNameAccess, uno::UNO_QUERY );
+
+ OSL_ENSURE( xNameAccess.is(),
+ "HierarchyEntry::first - No name access!" );
+
+ if ( xNameAccess.is() )
+ it.m_pImpl->names = xNameAccess->getElementNames();
+
+ uno::Reference< container::XHierarchicalNameAccess >
+ xHierNameAccess( xNameAccess, uno::UNO_QUERY );
+
+ OSL_ENSURE( xHierNameAccess.is(),
+ "HierarchyEntry::first - No hier. name access!" );
+
+ it.m_pImpl->dir = xHierNameAccess;
+
+ it.m_pImpl->officeDirs = m_xOfficeInstDirs;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::first - caught NoSuchElementException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::first - caught Exception!" );
+ }
+ }
+
+ if ( it.m_pImpl->names.getLength() == 0 )
+ return sal_False;
+
+ it.m_pImpl->pos = 0;
+ return sal_True;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::next( iterator& it )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( it.m_pImpl->pos == -1 )
+ return first( it );
+
+ ++(it.m_pImpl->pos);
+
+ return ( it.m_pImpl->pos < it.m_pImpl->names.getLength() );
+}
+
+//=========================================================================
+rtl::OUString HierarchyEntry::createPathFromHierarchyURL(
+ const HierarchyUri& rURI )
+{
+ // Transform path....
+ // folder/subfolder/subsubfolder
+ // --> ['folder']/Children/['subfolder']/Children/['subsubfolder']
+
+ const rtl::OUString aPath = rURI.getPath().copy( 1 ); // skip leading slash.
+ sal_Int32 nLen = aPath.getLength();
+
+ if ( nLen )
+ {
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.appendAscii( "['" );
+
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = aPath.indexOf( '/' );
+
+ do
+ {
+ if ( nEnd == -1 )
+ nEnd = nLen;
+
+ rtl::OUString aToken = aPath.copy( nStart, nEnd - nStart );
+ makeXMLName( aToken, aNewPath );
+
+ if ( nEnd != nLen )
+ {
+ aNewPath.appendAscii( "']/Children/['" );
+ nStart = nEnd + 1;
+ nEnd = aPath.indexOf( '/', nStart );
+ }
+ else
+ aNewPath.appendAscii( "']" );
+ }
+ while ( nEnd != nLen );
+
+ return aNewPath.makeStringAndClear();
+ }
+
+ return aPath;
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess >
+HierarchyEntry::getRootReadAccess()
+{
+ if ( !m_xRootReadAccess.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_xRootReadAccess.is() )
+ {
+ if ( m_bTriedToGetRootReadAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getRootReadAccess - "
+ "Unable to read any config data! -> #82494#" );
+ return uno::Reference< container::XHierarchicalNameAccess >();
+ }
+
+ try
+ {
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create Root object.
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= rtl::OUString(); // root path
+ aArguments[ 0 ] <<= aProperty;
+
+ m_bTriedToGetRootReadAccess = sal_True;
+
+ m_xRootReadAccess
+ = uno::Reference< container::XHierarchicalNameAccess >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ READ_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getRootReadAccess - "
+ "caught Exception!" );
+ }
+ }
+ }
+ return m_xRootReadAccess;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyEntry::iterator Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyEntry::iterator::iterator()
+{
+ m_pImpl = new iterator_Impl;
+}
+
+//=========================================================================
+HierarchyEntry::iterator::~iterator()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+const HierarchyEntryData& HierarchyEntry::iterator::operator*() const
+{
+ if ( ( m_pImpl->pos != -1 )
+ && ( m_pImpl->dir.is() )
+ && ( m_pImpl->pos < m_pImpl->names.getLength() ) )
+ {
+ try
+ {
+ rtl::OUStringBuffer aKey;
+ aKey.appendAscii( "['" );
+ makeXMLName( m_pImpl->names.getConstArray()[ m_pImpl->pos ], aKey );
+ aKey.appendAscii( "']" );
+
+ rtl::OUString aTitle = aKey.makeStringAndClear();
+ rtl::OUString aTargetURL = aTitle;
+ rtl::OUString aType = aTitle;
+
+ aTitle += rtl::OUString::createFromAscii( "/Title" );
+ aTargetURL += rtl::OUString::createFromAscii( "/TargetURL" );
+ aType += rtl::OUString::createFromAscii( "/Type" );
+
+ rtl::OUString aValue;
+ m_pImpl->dir->getByHierarchicalName( aTitle ) >>= aValue;
+ m_pImpl->entry.setTitle( aValue );
+
+ m_pImpl->dir->getByHierarchicalName( aTargetURL ) >>= aValue;
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion directory must
+ // never be stored directly. A placeholder is used instead. Replace
+ // it by actual installation directory.
+ if ( m_pImpl->officeDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_pImpl->officeDirs->makeAbsoluteURL( aValue );
+ m_pImpl->entry.setTargetURL( aValue );
+
+ if ( m_pImpl->dir->hasByHierarchicalName( aType ) )
+ {
+ // Might not be present since it was introduced long
+ // after Title and TargetURL (#82433#)... So not getting
+ // it is not an error.
+
+ // Get Type value.
+ sal_Int32 nType = 0;
+ if ( m_pImpl->dir->getByHierarchicalName( aType ) >>= nType )
+ {
+ if ( nType == 0 )
+ {
+ m_pImpl->entry.setType( HierarchyEntryData::LINK );
+ }
+ else if ( nType == 1 )
+ {
+ m_pImpl->entry.setType( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Unknown Type value!" );
+ }
+ }
+ }
+
+ m_pImpl->entry.setName(
+ m_pImpl->names.getConstArray()[ m_pImpl->pos ] );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ m_pImpl->entry = HierarchyEntryData();
+ }
+ }
+
+ return m_pImpl->entry;
+}
+
+} // namespace hierarchy_ucp
diff --git a/ucb/source/ucp/hierarchy/hierarchydata.hxx b/ucb/source/ucp/hierarchy/hierarchydata.hxx
new file mode 100644
index 000000000000..769611342baf
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydata.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYDATA_HXX
+#define _HIERARCHYDATA_HXX
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace util {
+ class XOfficeInstallationDirectories;
+ }
+} } }
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+
+class HierarchyEntryData
+{
+public:
+ enum Type { NONE, LINK, FOLDER };
+
+ HierarchyEntryData() : m_aType( NONE ) {}
+ HierarchyEntryData( const Type & rType ) : m_aType( rType ) {}
+
+ const rtl::OUString & getName() const { return m_aName; }
+ void setName( const rtl::OUString & rName ) { m_aName = rName; }
+
+ const rtl::OUString & getTitle() const { return m_aTitle; }
+ void setTitle( const rtl::OUString & rTitle ) { m_aTitle = rTitle; }
+
+ const rtl::OUString & getTargetURL() const { return m_aTargetURL; }
+ void setTargetURL( const rtl::OUString & rURL ) { m_aTargetURL = rURL; }
+
+ Type getType() const
+ { return ( m_aType != NONE ) ? m_aType
+ : m_aTargetURL.getLength()
+ ? LINK
+ : FOLDER; }
+ void setType( const Type & rType ) { m_aType = rType; }
+
+private:
+ rtl::OUString m_aName; // Name (language independent)
+ rtl::OUString m_aTitle; // Title (language dependent)
+ rtl::OUString m_aTargetURL; // Target URL ( links only )
+ Type m_aType; // Type
+};
+
+//=========================================================================
+
+class HierarchyContentProvider;
+class HierarchyUri;
+
+class HierarchyEntry
+{
+ ::rtl::OUString m_aServiceSpecifier;
+ ::rtl::OUString m_aName;
+ ::rtl::OUString m_aPath;
+ ::osl::Mutex m_aMutex;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess >
+ m_xRootReadAccess;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::util::XOfficeInstallationDirectories >
+ m_xOfficeInstDirs;
+ sal_Bool m_bTriedToGetRootReadAccess; // #82494#
+
+private:
+ ::rtl::OUString createPathFromHierarchyURL( const HierarchyUri & rURI );
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess >
+ getRootReadAccess();
+
+public:
+ HierarchyEntry( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ HierarchyContentProvider* pProvider,
+ const ::rtl::OUString& rURL );
+
+ sal_Bool hasData();
+
+ sal_Bool getData( HierarchyEntryData& rData );
+
+ sal_Bool setData( const HierarchyEntryData& rData, sal_Bool bCreate );
+
+ sal_Bool move( const ::rtl::OUString& rNewURL,
+ const HierarchyEntryData& rData );
+
+ sal_Bool remove();
+
+ // Iteration.
+
+ struct iterator_Impl;
+
+ class iterator
+ {
+ friend class HierarchyEntry;
+
+ iterator_Impl* m_pImpl;
+
+ public:
+ iterator();
+ ~iterator();
+
+ const HierarchyEntryData& operator*() const;
+ };
+
+ sal_Bool first( iterator& it );
+ sal_Bool next ( iterator& it );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYDATA_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasource.cxx b/ucb/source/ucp/hierarchy/hierarchydatasource.cxx
new file mode 100644
index 000000000000..467259caf0eb
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasource.cxx
@@ -0,0 +1,1116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ Note: Configuration Management classes do not support XAggregation.
+ So I have to wrap the interesting interfaces manually.
+
+ *************************************************************************/
+#include "hierarchydatasource.hxx"
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+
+// describe path of cfg entry
+#define CFGPROPERTY_NODEPATH "nodepath"
+// true->async. update; false->sync. update
+#define CFGPROPERTY_LAZYWRITE "lazywrite"
+
+#define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
+#define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+
+#define CONFIG_PROVIDER_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationProvider"
+#define CONFIG_READ_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationAccess"
+#define CONFIG_READWRITE_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationUpdateAccess"
+#define CONFIG_DATA_ROOT_KEY \
+ "/org.openoffice.ucb.Hierarchy/Root"
+
+//=========================================================================
+
+namespace hcp_impl
+{
+
+//=========================================================================
+//
+// HierarchyDataReadAccess Implementation.
+//
+//=========================================================================
+
+class HierarchyDataAccess : public cppu::OWeakObject,
+ public lang::XServiceInfo,
+ public lang::XTypeProvider,
+ public lang::XComponent,
+ public lang::XSingleServiceFactory,
+ public container::XHierarchicalNameAccess,
+ public container::XNameContainer,
+ public util::XChangesNotifier,
+ public util::XChangesBatch
+{
+ osl::Mutex m_aMutex;
+ uno::Reference< uno::XInterface > m_xConfigAccess;
+ uno::Reference< lang::XComponent > m_xCfgC;
+ uno::Reference< lang::XSingleServiceFactory > m_xCfgSSF;
+ uno::Reference< container::XHierarchicalNameAccess > m_xCfgHNA;
+ uno::Reference< container::XNameContainer > m_xCfgNC;
+ uno::Reference< container::XNameReplace > m_xCfgNR;
+ uno::Reference< container::XNameAccess > m_xCfgNA;
+ uno::Reference< container::XElementAccess > m_xCfgEA;
+ uno::Reference< util::XChangesNotifier > m_xCfgCN;
+ uno::Reference< util::XChangesBatch > m_xCfgCB;
+ bool m_bReadOnly;
+
+public:
+ HierarchyDataAccess( const uno::Reference<
+ uno::XInterface > & xConfigAccess,
+ bool bReadOnly );
+ virtual ~HierarchyDataAccess();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose()
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const uno::Reference< lang::XEventListener > & xListener )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const uno::Reference<
+ lang::XEventListener > & aListener )
+ throw ( uno::RuntimeException );
+
+ // XSingleServiceFactory
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstance()
+ throw ( uno::Exception, uno::RuntimeException );
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const uno::Sequence< uno::Any > & aArguments )
+ throw ( uno::Exception, uno::RuntimeException );
+
+ // XHierarchicalNameAccess
+ virtual uno::Any SAL_CALL
+ getByHierarchicalName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException, uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByHierarchicalName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException );
+
+ // XNameContainer
+ virtual void SAL_CALL
+ insertByName( const rtl::OUString & aName, const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::ElementExistException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+ virtual void SAL_CALL
+ removeByName( const rtl::OUString & Name )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+
+ // XNameReplace ( base of XNameContainer )
+ virtual void SAL_CALL
+ replaceByName( const rtl::OUString & aName, const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+
+ // XNameAccess ( base of XNameReplace )
+ virtual uno::Any SAL_CALL
+ getByName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames()
+ throw ( uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException );
+
+ // XElementAccess ( base of XNameAccess )
+ virtual uno::Type SAL_CALL
+ getElementType()
+ throw ( uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasElements()
+ throw ( uno::RuntimeException );
+
+ // XChangesNotifier
+ virtual void SAL_CALL
+ addChangesListener( const uno::Reference<
+ util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ removeChangesListener( const uno::Reference<
+ util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException );
+
+ // XChangesBatch
+ virtual void SAL_CALL
+ commitChanges()
+ throw ( lang::WrappedTargetException, uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasPendingChanges()
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< util::ElementChange > SAL_CALL
+ getPendingChanges()
+ throw ( uno::RuntimeException );
+};
+
+} // namespace hcp_impl
+
+using namespace hcp_impl;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyDataSource Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyDataSource::HierarchyDataSource(
+ const uno::Reference< lang::XMultiServiceFactory > & rxServiceMgr )
+: m_xSMgr( rxServiceMgr ),
+ m_pDisposeEventListeners( 0 )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyDataSource::~HierarchyDataSource()
+{
+ delete m_pDisposeEventListeners;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( HierarchyDataSource,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ lang::XComponent,
+ lang::XMultiServiceFactory );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( HierarchyDataSource,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ lang::XComponent,
+ lang::XMultiServiceFactory );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_0( HierarchyDataSource,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyDataSource" ) )
+{
+ uno::Sequence< rtl::OUString > aSNS( 2 );
+ aSNS[ 0 ] = rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.DefaultHierarchyDataSource" );
+ aSNS[ 1 ] = rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.HierarchyDataSource" );
+ return aSNS;
+}
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyDataSource );
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataSource::dispose()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ lang::EventObject aEvt;
+ aEvt.Source = static_cast< lang::XComponent * >( this );
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataSource::addEventListener(
+ const uno::Reference< lang::XEventListener > & Listener )
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners
+ = new cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataSource::removeEventListener(
+ const uno::Reference< lang::XEventListener > & Listener )
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+//=========================================================================
+//
+// XMultiServiceFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstance( const rtl::OUString & aServiceSpecifier )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ // Create view to root node.
+
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
+ aProp.Value <<=
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ aArguments[ 0 ] <<= aProp;
+
+ return createInstanceWithArguments( aServiceSpecifier, aArguments, false );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstanceWithArguments(
+ const rtl::OUString & ServiceSpecifier,
+ const uno::Sequence< uno::Any > & Arguments )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ return createInstanceWithArguments( ServiceSpecifier, Arguments, true );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL
+HierarchyDataSource::getAvailableServiceNames()
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aNames( 2 );
+ aNames[ 0 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
+ aNames[ 1 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
+ return aNames;
+}
+
+//=========================================================================
+//
+// Non-interface methods
+//
+//=========================================================================
+
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstanceWithArguments(
+ const rtl::OUString & ServiceSpecifier,
+ const uno::Sequence< uno::Any > & Arguments,
+ bool bCheckArgs )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Check service specifier.
+ bool bReadOnly = !!ServiceSpecifier.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( READ_SERVICE_NAME ) );
+ bool bReadWrite = !bReadOnly &&
+ ServiceSpecifier.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( READWRITE_SERVICE_NAME ) );
+
+ if ( !bReadOnly && !bReadWrite )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Unsupported service specifier!" );
+ return uno::Reference< uno::XInterface >();
+ }
+
+ uno::Sequence< uno::Any > aNewArgs( Arguments );
+
+ bool bHasLazyWriteProp = bReadOnly; // property must be added only if
+ // a writable view is requested.
+ if ( bCheckArgs )
+ {
+ // Check arguments.
+ bool bHasNodePath = false;
+ sal_Int32 nCount = Arguments.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ beans::PropertyValue aProp;
+ if ( Arguments[ n ] >>= aProp )
+ {
+ if ( aProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( CFGPROPERTY_NODEPATH ) ) )
+ {
+ rtl::OUString aPath;
+ if ( aProp.Value >>= aPath )
+ {
+ bHasNodePath = true;
+
+ // Create path to data inside the configuration.
+ rtl::OUString aConfigPath;
+ if ( !createConfigPath( aPath, aConfigPath ) )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::"
+ "createInstanceWithArguments - "
+ "Invalid node path!" );
+ return uno::Reference< uno::XInterface >();
+ }
+
+ aProp.Value <<= aConfigPath;
+
+ // Set new path in arguments.
+ aNewArgs[ n ] <<= aProp;
+
+ if ( bHasLazyWriteProp )
+ break;
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Invalid type for property 'nodepath'!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+ else if ( aProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ CFGPROPERTY_LAZYWRITE ) ) )
+ {
+ if ( aProp.Value.getValueType() == getCppuBooleanType() )
+ {
+ bHasLazyWriteProp = true;
+
+ if ( bHasNodePath )
+ break;
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Invalid type for property 'lazywrite'!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+ }
+ }
+
+ if ( !bHasNodePath )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "No 'nodepath' property!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+
+ // Create Configuration Provider.
+ uno::Reference< lang::XMultiServiceFactory > xProv = getConfigProvider();
+ if ( !xProv.is() )
+ return uno::Reference< uno::XInterface >();
+
+ uno::Reference< uno::XInterface > xConfigAccess;
+ try
+ {
+ if ( bReadOnly )
+ {
+ // Create configuration read-only access object.
+ xConfigAccess = xProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_READ_SERVICE_NAME ) ),
+ aNewArgs );
+ }
+ else
+ {
+ // Append 'lazywrite' property value, if not already present.
+ if ( !bHasLazyWriteProp )
+ {
+ sal_Int32 nLen = aNewArgs.getLength();
+ aNewArgs.realloc( nLen + 1 );
+
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_LAZYWRITE ) );
+ aProp.Value <<= sal_True;
+ aNewArgs[ nLen ] <<= aProp;
+ }
+
+ // Create configuration read-write access object.
+ xConfigAccess = xProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_READWRITE_SERVICE_NAME ) ),
+ aNewArgs );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Cannot instanciate configuration access!" );
+ throw;
+ }
+
+ if ( !xConfigAccess.is() )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Cannot instanciate configuration access!" );
+ return xConfigAccess;
+ }
+
+ return uno::Reference< uno::XInterface >(
+ static_cast< cppu::OWeakObject * >(
+ new HierarchyDataAccess( xConfigAccess, bReadOnly ) ) );
+}
+
+//=========================================================================
+uno::Reference< lang::XMultiServiceFactory >
+HierarchyDataSource::getConfigProvider()
+{
+ if ( !m_xConfigProvider.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_xConfigProvider.is() )
+ {
+ try
+ {
+ m_xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_PROVIDER_SERVICE_NAME ) ) ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( m_xConfigProvider.is(),
+ "HierarchyDataSource::getConfigProvider - "
+ "No configuration provider!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::getConfigProvider - "
+ "caught exception!" );
+ }
+ }
+ }
+
+ return m_xConfigProvider;
+}
+
+//=========================================================================
+bool HierarchyDataSource::createConfigPath(
+ const rtl::OUString & rInPath, rtl::OUString & rOutPath )
+{
+ if ( rInPath.getLength() )
+ {
+ if ( rInPath.indexOf( '/' ) == 0 )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createConfigPath - "
+ "Leading slash in node path!" );
+ return false;
+ }
+
+ if ( rInPath.lastIndexOf( '/' ) == rInPath.getLength() - 1 )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createConfigPath - "
+ "Trailing slash in node path!" );
+ return false;
+ }
+
+ rtl::OUString aOutPath(
+ RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY "/" ) );
+ aOutPath += rInPath;
+ rOutPath = aOutPath;
+ }
+ else
+ {
+ rOutPath = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
+ }
+
+ return true;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyDataAccess Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+#define ENSURE_ORIG_INTERFACE( interface_name, member_name ) \
+ m_xCfg##member_name; \
+ if ( !m_xCfg##member_name.is() ) \
+ { \
+ osl::Guard< osl::Mutex > aGuard( m_aMutex ); \
+ if ( !m_xCfg##member_name.is() ) \
+ m_xCfg##member_name \
+ = uno::Reference< interface_name >( \
+ m_xConfigAccess, uno::UNO_QUERY ); \
+ xOrig = m_xCfg##member_name; \
+ }
+
+//=========================================================================
+HierarchyDataAccess::HierarchyDataAccess( const uno::Reference<
+ uno::XInterface > & xConfigAccess,
+ bool bReadOnly )
+: m_xConfigAccess( xConfigAccess ),
+ m_bReadOnly( bReadOnly )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyDataAccess::~HierarchyDataAccess()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_COMMON_IMPL( HierarchyDataAccess );
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::queryInterface( const uno::Type & aType )
+ throw ( uno::RuntimeException )
+{
+ // Interfaces supported in read-only and read-write mode.
+ uno::Any aRet = cppu::queryInterface( aType,
+ static_cast< lang::XTypeProvider * >( this ),
+ static_cast< lang::XServiceInfo * >( this ),
+ static_cast< lang::XComponent * >( this ),
+ static_cast< container::XHierarchicalNameAccess * >( this ),
+ static_cast< container::XNameAccess * >( this ),
+ static_cast< container::XElementAccess * >( this ),
+ static_cast< util::XChangesNotifier * >( this ) );
+
+ // Interfaces supported only in read-write mode.
+ if ( !aRet.hasValue() && !m_bReadOnly )
+ {
+ aRet = cppu::queryInterface( aType,
+ static_cast< lang::XSingleServiceFactory * >( this ),
+ static_cast< container::XNameContainer * >( this ),
+ static_cast< container::XNameReplace * >( this ),
+ static_cast< util::XChangesBatch * >( this ) );
+ }
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( aType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( HierarchyDataAccess );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL HierarchyDataAccess::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( m_bReadOnly )
+ {
+ static cppu::OTypeCollection* pReadOnlyTypes = 0;
+
+ pCollection = pReadOnlyTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pReadOnlyTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
+ CPPU_TYPE_REF( container::XNameAccess ),
+ CPPU_TYPE_REF( util::XChangesNotifier ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pReadOnlyTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pReadWriteTypes = 0;
+
+ pCollection = pReadWriteTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pReadWriteTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( lang::XSingleServiceFactory ),
+ CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
+ CPPU_TYPE_REF( container::XNameContainer ),
+ CPPU_TYPE_REF( util::XChangesBatch ),
+ CPPU_TYPE_REF( util::XChangesNotifier ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pReadWriteTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_NOFACTORY_IMPL_0(
+ HierarchyDataAccess,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.HierarchyDataAccess" ) ) )
+{
+ uno::Sequence< rtl::OUString > aSNS( 2 );
+ aSNS[ 0 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
+ aSNS[ 1 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::dispose()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->dispose();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::removeEventListener(
+ const uno::Reference< lang::XEventListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// XHierarchicalNameAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::getByHierarchicalName(
+ const rtl::OUString & aName )
+ throw ( container::NoSuchElementException, uno::RuntimeException )
+{
+ uno::Reference< container::XHierarchicalNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : "
+ "Data source is not an XHierarchicalNameAccess!" );
+ return xOrig->getByHierarchicalName( aName );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasByHierarchicalName(
+ const rtl::OUString & aName )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XHierarchicalNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : "
+ "Data source is not an XHierarchicalNameAccess!" );
+ return xOrig->hasByHierarchicalName( aName );
+}
+
+//=========================================================================
+//
+// XNameAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::getByName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->getByName( aName );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL HierarchyDataAccess::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->getElementNames();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasByName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->hasByName( aName );
+}
+
+//=========================================================================
+//
+// XElementAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Type SAL_CALL HierarchyDataAccess::getElementType()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XElementAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XElementAccess!" );
+ return xOrig->getElementType();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasElements()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XElementAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XElementAccess!" );
+ return xOrig->hasElements();
+}
+
+//=========================================================================
+//
+// XChangesNotifier methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::addChangesListener(
+ const uno::Reference< util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesNotifier > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
+ xOrig->addChangesListener( aListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::removeChangesListener(
+ const uno::Reference< util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesNotifier > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
+ xOrig->removeChangesListener( aListener );
+}
+
+//=========================================================================
+//
+// XSingleServiceFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL HierarchyDataAccess::createInstance()
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ uno::Reference< lang::XSingleServiceFactory > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
+ return xOrig->createInstance();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataAccess::createInstanceWithArguments(
+ const uno::Sequence< uno::Any > & aArguments )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ uno::Reference< lang::XSingleServiceFactory > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
+ return xOrig->createInstanceWithArguments( aArguments );
+}
+
+//=========================================================================
+//
+// XNameContainer methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+HierarchyDataAccess::insertByName( const rtl::OUString & aName,
+ const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::ElementExistException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameContainer > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameContainer!" );
+ xOrig->insertByName( aName, aElement );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+HierarchyDataAccess::removeByName( const rtl::OUString & Name )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameContainer > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameContainer!" );
+ xOrig->removeByName( Name );
+}
+
+//=========================================================================
+//
+// XNameReplace methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::replaceByName( const rtl::OUString & aName,
+ const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameReplace > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameReplace, NR );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameReplace!" );
+ xOrig->replaceByName( aName, aElement );
+}
+
+//=========================================================================
+//
+// XChangesBatch methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::commitChanges()
+ throw ( lang::WrappedTargetException, uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ xOrig->commitChanges();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasPendingChanges()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ return xOrig->hasPendingChanges();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< util::ElementChange > SAL_CALL
+HierarchyDataAccess::getPendingChanges()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ return xOrig->getPendingChanges();
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasource.hxx b/ucb/source/ucp/hierarchy/hierarchydatasource.hxx
new file mode 100644
index 000000000000..329011e142db
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasource.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYDATASOURCE_HXX
+#define _HIERARCHYDATASOURCE_HXX
+
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+
+namespace cppu { class OInterfaceContainerHelper; }
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+class HierarchyDataSource : public cppu::OWeakObject,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::lang::XMultiServiceFactory
+{
+ osl::Mutex m_aMutex;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider;
+ cppu::OInterfaceContainerHelper * m_pDisposeEventListeners;
+
+public:
+ HierarchyDataSource( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &
+ rxServiceMgr );
+ virtual ~HierarchyDataSource();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > & xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > & aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XMultiServiceFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstance( const rtl::OUString & aServiceSpecifier )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const rtl::OUString & ServiceSpecifier,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any > & Arguments )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getAvailableServiceNames()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // Non-Interface methods
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const rtl::OUString & ServiceSpecifier,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any > & Arguments,
+ bool bCheckArgs )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >
+ getConfigProvider();
+
+ bool
+ createConfigPath( const rtl::OUString & rInPath, rtl::OUString & rOutPath );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYDATASOURCE_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx b/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx
new file mode 100644
index 000000000000..8cd53a4a6201
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+#include <ucbhelper/contentidentifier.hxx>
+#include "hierarchydatasupplier.hxx"
+#include "hierarchyprovider.hxx"
+#include "hierarchycontent.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aId;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+ HierarchyEntryData aData;
+
+ ResultListEntry( const HierarchyEntryData& rEntry ) : aData( rEntry ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< HierarchyContent > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ HierarchyEntry m_aFolder;
+ HierarchyEntry::iterator m_aIterator;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_aFolder( rxSMgr,
+ static_cast< HierarchyContentProvider * >(
+ rContent->getProvider().get() ),
+ rContent->getIdentifier()->getContentIdentifier() ),
+ m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyResultSetDataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
+ sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ rtl::OUString aId
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+
+ if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ aId += m_pImpl->m_aResults[ nIndex ]->aData.getName();
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+HierarchyResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent >
+HierarchyResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool HierarchyResultSetDataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ sal_Bool bFound = sal_False;
+ sal_uInt32 nPos = nOldCount;
+
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ {
+ const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
+ if ( checkResult( rResult ) )
+ {
+ m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
+
+ if ( nPos == nIndex )
+ {
+ // Result obtained.
+ bFound = sal_True;
+ break;
+ }
+ }
+ nPos++;
+ }
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 HierarchyResultSetDataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ {
+ const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
+ if ( checkResult( rResult ) )
+ m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
+ }
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool HierarchyResultSetDataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow >
+HierarchyResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow
+ = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ static rtl::OUString aFolderType(
+ rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE ) );
+ static rtl::OUString aLinkType(
+ rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) );
+
+ HierarchyContentProperties aData(
+ m_pImpl->m_aResults[ nIndex ]->aData );
+
+ uno::Reference< sdbc::XRow > xRow
+ = HierarchyContent::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ aData,
+ static_cast< HierarchyContentProvider * >(
+ m_pImpl->m_xContent->getProvider().get() ),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void HierarchyResultSetDataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void HierarchyResultSetDataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+}
+
+//=========================================================================
+sal_Bool HierarchyResultSetDataSupplier::checkResult(
+ const HierarchyEntryData& rResult )
+{
+ switch ( m_pImpl->m_nOpenMode )
+ {
+ case ucb::OpenMode::FOLDERS:
+ if ( rResult.getType() == HierarchyEntryData::LINK )
+ {
+ // Entry is a link.
+ return sal_False;
+ }
+ break;
+
+ case ucb::OpenMode::DOCUMENTS:
+ if ( rResult.getType() == HierarchyEntryData::FOLDER )
+ {
+ // Entry is a folder.
+ return sal_False;
+ }
+ break;
+
+ case ucb::OpenMode::ALL:
+ default:
+ break;
+ }
+
+ return sal_True;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx b/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx
new file mode 100644
index 000000000000..87218e0729d0
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYDATASUPPLIER_HXX
+#define _HIERARCHYDATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/resultset.hxx>
+
+namespace hierarchy_ucp {
+
+class HierarchyEntryData;
+struct DataSupplier_Impl;
+class HierarchyContent;
+
+class HierarchyResultSetDataSupplier :
+ public ::ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+private:
+ sal_Bool checkResult( const HierarchyEntryData& rResult );
+
+public:
+ HierarchyResultSetDataSupplier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode = com::sun::star::ucb::OpenMode::ALL );
+ virtual ~HierarchyResultSetDataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYDATASUPPLIER_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchyprovider.cxx b/ucb/source/ucp/hierarchy/hierarchyprovider.cxx
new file mode 100644
index 000000000000..5ce8ea891f51
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyprovider.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - XInitialization::initialize does not work any longer!
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include "hierarchyprovider.hxx"
+#include "hierarchycontent.hxx"
+#include "hierarchyuri.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyContentProvider::HierarchyContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rXSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rXSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyContentProvider::~HierarchyContentProvider()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( HierarchyContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ lang::XInitialization );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( HierarchyContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ lang::XInitialization );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( HierarchyContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyContentProvider" ),
+ rtl::OUString::createFromAscii(
+ HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+HierarchyContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ HierarchyUri aUri( Identifier->getContentIdentifier() );
+ if ( !aUri.isValid() )
+ throw ucb::IllegalIdentifierException();
+
+ // Encode URL and create new Id. This may "correct" user-typed-in URL's.
+ uno::Reference< ucb::XContentIdentifier > xCanonicId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr,
+ ::ucb_impl::urihelper::encodeURI(
+ aUri.getUri() ) );
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xCanonicId ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ // Create a new content.
+ xContent = HierarchyContent::create( m_xSMgr, this, xCanonicId );
+ registerNewContent( xContent );
+
+ if ( xContent.is() && !xContent->getIdentifier().is() )
+ throw ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
+//=========================================================================
+//
+// XInitialization methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyContentProvider::initialize(
+ const uno::Sequence< uno::Any >& aArguments )
+ throw( uno::Exception, uno::RuntimeException )
+{
+#if 0
+ if ( aArguments.getLength() > 0 )
+ {
+ // Extract config provider from service init args.
+ aArguments[ 0 ] >>= m_xConfigProvider;
+
+ OSL_ENSURE( m_xConfigProvider.is(),
+ "HierarchyContentProvider::initialize - "
+ "No config provider!" );
+ }
+#else
+ if ( aArguments.getLength() > 0 )
+ OSL_ENSURE( false,
+ "HierarchyContentProvider::initialize : not supported!" );
+#endif
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+uno::Reference< lang::XMultiServiceFactory >
+HierarchyContentProvider::getConfigProvider(
+ const rtl::OUString & rServiceSpecifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
+ rServiceSpecifier );
+ if ( it == m_aConfigProviderMap.end() )
+ {
+ try
+ {
+ ConfigProviderMapEntry aEntry;
+ aEntry.xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( rServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( aEntry.xConfigProvider.is() )
+ {
+ m_aConfigProviderMap[ rServiceSpecifier ] = aEntry;
+ return aEntry.xConfigProvider;
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+// OSL_ENSURE( sal_False,
+// "HierarchyContentProvider::getConfigProvider - "
+// "caught exception!" );
+ }
+
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getConfigProvider - "
+ "No config provider!" );
+
+ return uno::Reference< lang::XMultiServiceFactory >();
+ }
+
+ return (*it).second.xConfigProvider;
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess >
+HierarchyContentProvider::getRootConfigReadNameAccess(
+ const rtl::OUString & rServiceSpecifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
+ rServiceSpecifier );
+ if ( it != m_aConfigProviderMap.end() )
+ {
+ if ( !( (*it).second.xRootReadAccess.is() ) )
+ {
+ if ( (*it).second.bTriedToGetRootReadAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getRootConfigReadNameAccess - "
+ "Unable to read any config data! -> #82494#" );
+ return uno::Reference< container::XHierarchicalNameAccess >();
+ }
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv
+ = getConfigProvider( rServiceSpecifier );
+
+ if ( xConfigProv.is() )
+ {
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name
+ = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aProperty.Value <<= rtl::OUString(); // root path
+ aArguments[ 0 ] <<= aProperty;
+
+ (*it).second.bTriedToGetRootReadAccess = true;
+
+ (*it).second.xRootReadAccess
+ = uno::Reference< container::XHierarchicalNameAccess >(
+ xConfigProv->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb."
+ "HierarchyDataReadAccess" ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getRootConfigReadNameAccess - "
+ "caught Exception!" );
+ }
+ }
+ }
+
+ return (*it).second.xRootReadAccess;
+}
+
+//=========================================================================
+uno::Reference< util::XOfficeInstallationDirectories >
+HierarchyContentProvider::getOfficeInstallationDirectories()
+{
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ OSL_ENSURE( m_xSMgr.is(), "No service manager!" );
+
+ uno::Reference< uno::XComponentContext > xCtx;
+ uno::Reference< beans::XPropertySet > xPropSet(
+ m_xSMgr, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
+ >>= xCtx;
+ }
+
+ OSL_ENSURE( xCtx.is(),
+ "Unable to obtain component context from "
+ "service manager!" );
+
+ if ( xCtx.is() )
+ {
+ xCtx->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/"
+ "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
+ >>= m_xOfficeInstDirs;
+
+// Be silent. singleton only available in an Office environment.
+// OSL_ENSURE( m_xOfficeInstDirs.is(),
+// "Unable to obtain office directories singleton!" );
+ }
+ }
+ }
+ return m_xOfficeInstDirs;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyprovider.hxx b/ucb/source/ucp/hierarchy/hierarchyprovider.hxx
new file mode 100644
index 000000000000..9212aadf417e
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyprovider.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYPROVIDER_HXX
+#define _HIERARCHYPROVIDER_HXX
+
+#include <hash_map>
+#include <ucbhelper/providerhelper.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace util {
+ class XOfficeInstallationDirectories;
+ }
+} } }
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+#define HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyContentProvider"
+#define HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 41
+
+#define HIERARCHY_URL_SCHEME \
+ "vnd.sun.star.hier"
+#define HIERARCHY_URL_SCHEME_LENGTH 17
+
+#define HIERARCHY_FOLDER_CONTENT_TYPE \
+ "application/" HIERARCHY_URL_SCHEME "-folder"
+#define HIERARCHY_LINK_CONTENT_TYPE \
+ "application/" HIERARCHY_URL_SCHEME "-link"
+
+//=========================================================================
+
+struct ConfigProviderMapEntry
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > xConfigProvider;
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > xRootReadAccess;
+ bool bTriedToGetRootReadAccess; // #82494#
+
+ ConfigProviderMapEntry() : bTriedToGetRootReadAccess( false ) {}
+};
+
+struct equalString
+{
+ bool operator()(
+ const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
+ {
+ return !!( rKey1 == rKey2 );
+ }
+};
+
+struct hashString
+{
+ size_t operator()( const rtl::OUString & rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+typedef std::hash_map
+<
+ rtl::OUString, // servcie specifier
+ ConfigProviderMapEntry,
+ hashString,
+ equalString
+>
+ConfigProviderMap;
+
+//=========================================================================
+
+class HierarchyContentProvider : public ::ucbhelper::ContentProviderImplHelper,
+ public com::sun::star::lang::XInitialization
+{
+ ConfigProviderMap m_aConfigProviderMap;
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+public:
+ HierarchyContentProvider(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~HierarchyContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Any >& aArguments )
+ throw( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ // Non-Interface methods
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >
+ getConfigProvider( const rtl::OUString & rServiceSpecifier );
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >
+ getRootConfigReadNameAccess( const rtl::OUString & rServiceSpecifier );
+
+ // Note: may retrun an empty reference.
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XOfficeInstallationDirectories >
+ getOfficeInstallationDirectories();
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYPROVIDER_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchyservices.cxx b/ucb/source/ucp/hierarchy/hierarchyservices.cxx
new file mode 100644
index 000000000000..e645e006032e
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyservices.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "hierarchyprovider.hxx"
+#include "hierarchydatasource.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ HierarchyContentProvider::getImplementationName_Static(),
+ HierarchyContentProvider::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Data Source.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ HierarchyDataSource::getImplementationName_Static(),
+ HierarchyDataSource::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >(
+ pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( HierarchyContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = HierarchyContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Data Source.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( HierarchyDataSource::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = HierarchyDataSource::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyuri.cxx b/ucb/source/ucp/hierarchy/hierarchyuri.cxx
new file mode 100644
index 000000000000..0621db72d5bb
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyuri.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+#include "osl/diagnose.h"
+
+#include "hierarchyuri.hxx"
+
+using namespace hierarchy_ucp;
+
+//=========================================================================
+
+#define DEFAULT_DATA_SOURCE_SERVICE \
+ "com.sun.star.ucb.DefaultHierarchyDataSource"
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyUri Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+void HierarchyUri::init() const
+{
+ // Already inited?
+ if ( m_aUri.getLength() && !m_aPath.getLength() )
+ {
+ // Note: Maybe it's a re-init, setUri only resets m_aPath!
+ m_aService = m_aParentUri = m_aName = rtl::OUString();
+
+ // URI must match at least: <sheme>:
+ if ( ( m_aUri.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 1 ) )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Scheme is case insensitive.
+ rtl::OUString aScheme
+ = m_aUri.copy( 0, HIERARCHY_URL_SCHEME_LENGTH ).toAsciiLowerCase();
+ if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_URL_SCHEME ) ) )
+ {
+ m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme );
+
+ sal_Int32 nPos = 0;
+
+ // If the URI has no service specifier, insert default service.
+ // This is for backward compatibility and for convenience.
+
+ if ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 1 )
+ {
+ // root folder URI without path and service specifier.
+ m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "//" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos = m_aUri.getLength() - 1;
+ }
+ else if ( ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ &&
+ ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 1 ]
+ == sal_Unicode( '/' ) ) )
+ {
+ // root folder URI without service specifier.
+ m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos = m_aUri.getLength() - 1;
+ }
+ else if ( ( m_aUri.getLength() > HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ &&
+ ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 2 ]
+ != sal_Unicode( '/' ) ) )
+ {
+ // other (no root folder) URI without service specifier.
+ m_aUri = m_aUri.replaceAt(
+ HIERARCHY_URL_SCHEME_LENGTH + 2,
+ 0,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos
+ = HIERARCHY_URL_SCHEME_LENGTH + 3 + m_aService.getLength();
+ }
+ else
+ {
+ // URI with service specifier.
+ sal_Int32 nStart = HIERARCHY_URL_SCHEME_LENGTH + 3;
+
+ // Here: - m_aUri has at least the form "<scheme>://"
+ // - nStart points to char after <scheme>://
+
+ // Only <scheme>:// ?
+ if ( nStart == m_aUri.getLength() )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Empty path segments?
+ if ( m_aUri.indexOf(
+ rtl::OUString::createFromAscii( "//" ),
+ nStart ) != -1 )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ sal_Int32 nEnd = m_aUri.indexOf( '/', nStart );
+
+ // Only <scheme>:/// ?
+ if ( nEnd == nStart )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ if ( nEnd == -1 )
+ {
+ // Trailing slash missing.
+ nEnd = m_aUri.getLength();
+ m_aUri += rtl::OUString::createFromAscii( "/" );
+ }
+
+ m_aService = m_aUri.copy( nStart, nEnd - nStart );
+
+ nPos = nEnd;
+ }
+
+ // Here: - m_aUri has at least the form "<scheme>://<service>/"
+ // - m_aService was set
+ // - m_aPath, m_aParentPath, m_aName not yet set
+ // - nPos points to slash after service specifier
+
+ // Remove trailing slash, if not a root folder URI.
+ sal_Int32 nEnd = m_aUri.lastIndexOf( '/' );
+ if ( ( nEnd > nPos ) && ( nEnd == ( m_aUri.getLength() - 1 ) ) )
+ m_aUri = m_aUri.copy( 0, nEnd );
+
+ // Path (includes leading slash)
+ m_aPath = m_aUri.copy( nPos );
+
+ // parent URI + name
+ sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' );
+ if ( ( nLastSlash != -1 ) &&
+ ( nLastSlash != m_aUri.getLength() - 1 ) ) // root
+ {
+ m_aParentUri = m_aUri.copy( 0, nLastSlash );
+ m_aName = m_aUri.copy( nLastSlash + 1 );
+ }
+
+ // success
+ m_bValid = true;
+ }
+ else
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ }
+ }
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyuri.hxx b/ucb/source/ucp/hierarchy/hierarchyuri.hxx
new file mode 100644
index 000000000000..012d59bb4cf2
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyuri.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _HIERARCHYURI_HXX
+#define _HIERARCHYURI_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+#define HIERARCHY_URL_SCHEME "vnd.sun.star.hier"
+#define HIERARCHY_URL_SCHEME_LENGTH 17
+
+//=========================================================================
+
+class HierarchyUri
+{
+ mutable ::rtl::OUString m_aUri;
+ mutable ::rtl::OUString m_aParentUri;
+ mutable ::rtl::OUString m_aService;
+ mutable ::rtl::OUString m_aPath;
+ mutable ::rtl::OUString m_aName;
+ mutable bool m_bValid;
+
+private:
+ void init() const;
+
+public:
+ HierarchyUri() : m_bValid( false ) {}
+ HierarchyUri( const ::rtl::OUString & rUri )
+ : m_aUri( rUri ), m_bValid( false ) {}
+
+ sal_Bool isValid() const
+ { init(); return m_bValid; }
+
+ const ::rtl::OUString & getUri() const
+ { init(); return m_aUri; }
+
+ void setUri( const ::rtl::OUString & rUri )
+ { m_aPath = ::rtl::OUString(); m_aUri = rUri; m_bValid = false; }
+
+ const ::rtl::OUString & getParentUri() const
+ { init(); return m_aParentUri; }
+
+ const ::rtl::OUString & getService() const
+ { init(); return m_aService; }
+
+ const ::rtl::OUString & getPath() const
+ { init(); return m_aPath; }
+
+ const ::rtl::OUString & getName() const
+ { init(); return m_aName; }
+
+ inline sal_Bool isRootFolder() const;
+};
+
+inline sal_Bool HierarchyUri::isRootFolder() const
+{
+ init();
+ return ( ( m_aPath.getLength() == 1 ) &&
+ ( m_aPath.getStr()[ 0 ] == sal_Unicode( '/' ) ) );
+}
+}
+
+#endif
diff --git a/ucb/source/ucp/hierarchy/makefile.mk b/ucb/source/ucp/hierarchy/makefile.mk
new file mode 100644
index 000000000000..00b481b5e7a1
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+TARGET=ucphier
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCPHIER_MAJOR=1
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/hierarchyservices.obj \
+ $(SLO)$/hierarchydata.obj \
+ $(SLO)$/hierarchyprovider.obj \
+ $(SLO)$/hierarchycontent.obj \
+ $(SLO)$/hierarchycontentcaps.obj \
+ $(SLO)$/hierarchydatasupplier.obj \
+ $(SLO)$/dynamicresultset.obj \
+ $(SLO)$/hierarchydatasource.obj \
+ $(SLO)$/hierarchyuri.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCPHIER_MAJOR)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+# --- Targets ----------------------------------------------------------
+
+.ENDIF # L10N_framework
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/hierarchy/ucphier.xml b/ucb/source/ucp/hierarchy/ucphier.xml
new file mode 100644
index 000000000000..1c63cbcbd7ee
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/ucphier.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucphier
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.HierarchyContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to a persistent hierarchy of
+ folders and links.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.HierarchyContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.DefaultHierarchyDataSource
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.util.OfficeeInstallationDirectories
+ </service-dependency>
+ </component-description>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.HierarchyDataSource
+ </name>
+ <description>
+ This component implements a default data source for the Hierarchy
+ Content Provider. The data are accessed using the service
+ com.sun.star.configuration.ConfigurationProvider.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.DefaultHierarchyDataSource
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsuppertedNameClashException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandInfoChangeNotifier </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.util.XChangesBatch </type>
+ <type> com.sun.star.util.XChangesNotifier </type>
+ <type> com.sun.star.util.XOfficeInstallationDirectories </type>
+</module-description>
diff --git a/ucb/source/ucp/inc/urihelper.hxx b/ucb/source/ucp/inc/urihelper.hxx
new file mode 100644
index 000000000000..a67fbe0564c1
--- /dev/null
+++ b/ucb/source/ucp/inc/urihelper.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_URIHELPER_HXX
+#define INCLUDED_URIHELPER_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+
+//=========================================================================
+
+namespace ucb_impl { namespace urihelper {
+
+ inline ::rtl::OUString encodeSegment( const ::rtl::OUString & rSegment )
+ {
+ return rtl::Uri::encode( rSegment,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ }
+
+ inline ::rtl::OUString decodeSegment( const rtl::OUString& rSegment )
+ {
+ return rtl::Uri::decode( rSegment,
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 );
+ }
+
+ inline ::rtl::OUString encodeURI( const ::rtl::OUString & rURI )
+ {
+ rtl::OUString aFragment;
+ rtl::OUString aParams;
+ rtl::OUString aURI;
+
+ sal_Int32 nFragment = rURI.lastIndexOf( sal_Unicode( '#' ) );
+ if ( nFragment != -1 )
+ aFragment = rURI.copy( nFragment + 1 );
+
+ sal_Int32 nParams = ( nFragment == -1 )
+ ? rURI.lastIndexOf( sal_Unicode( '?' ) )
+ : rURI.lastIndexOf( sal_Unicode( '?' ), nFragment );
+ if ( nParams != -1 )
+ aParams = ( nFragment == -1 )
+ ? rURI.copy( nParams + 1 )
+ : rURI.copy( nParams + 1, nFragment - nParams - 1 );
+
+ aURI = ( nParams != -1 )
+ ? rURI.copy( 0, nParams )
+ : ( nFragment != -1 )
+ ? rURI.copy( 0, nFragment )
+ : rURI;
+
+ if ( aFragment.getLength() > 1 )
+ aFragment =
+ rtl::Uri::encode( aFragment,
+ rtl_UriCharClassUric,
+ rtl_UriEncodeKeepEscapes, /* #i81690# */
+ RTL_TEXTENCODING_UTF8 );
+
+ if ( aParams.getLength() > 1 )
+ aParams =
+ rtl::Uri::encode( aParams,
+ rtl_UriCharClassUric,
+ rtl_UriEncodeKeepEscapes, /* #i81690# */
+ RTL_TEXTENCODING_UTF8 );
+
+ rtl::OUStringBuffer aResult;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aResult.append(
+ rtl::Uri::encode( aURI.getToken( 0, '/', nIndex ),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeKeepEscapes, /* #i81690# */
+ RTL_TEXTENCODING_UTF8 ) );
+ if ( nIndex >= 0 )
+ aResult.append( sal_Unicode( '/' ) );
+ }
+ while ( nIndex >= 0 );
+
+ if ( aParams.getLength() > 0 )
+ {
+ aResult.append( sal_Unicode( '?' ) );
+ aResult.append( aParams );
+ }
+
+ if ( aFragment.getLength() > 0 )
+ {
+ aResult.append( sal_Unicode( '#' ) );
+ aResult.append( aFragment );
+ }
+
+ return aResult.makeStringAndClear();
+ }
+
+} } // namespace
+
+#endif /* !INCLUDED_URIHELPER_HXX */
diff --git a/ucb/source/ucp/odma/makefile.mk b/ucb/source/ucp/odma/makefile.mk
new file mode 100644
index 000000000000..14a7d3d45c3d
--- /dev/null
+++ b/ucb/source/ucp/odma/makefile.mk
@@ -0,0 +1,97 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UCP_VERSION=1
+UCP_NAME=odma
+
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+
+TARGET=ucp$(UCP_NAME)
+TARGET2=s$(UCP_NAME)
+
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+TARGET2TYPE=CUI
+LIBTARGET=NO
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/odma_lib.obj \
+ $(SLO)$/odma_services.obj \
+ $(SLO)$/odma_provider.obj \
+ $(SLO)$/odma_content.obj \
+ $(SLO)$/odma_resultset.obj \
+ $(SLO)$/odma_datasupplier.obj \
+ $(SLO)$/odma_inputstream.obj \
+ $(SLO)$/odma_contentcaps.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCP_VERSION)
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+# --- SODMA executable -------------------------------------------------
+OBJFILES= $(OBJ)$/odma_main.obj
+
+APP2TARGET= $(TARGET2)
+APP2OBJS= $(OBJFILES)
+APP2STDLIBS=$(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)
+
+DEF2DES=UCB ODMA URL converter
+
+# --- Targets ----------------------------------------------------------
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/odma/odma.h b/ucb/source/ucp/odma/odma.h
new file mode 100644
index 000000000000..8a5ed94b4f65
--- /dev/null
+++ b/ucb/source/ucp/odma/odma.h
@@ -0,0 +1,315 @@
+/* odma.h - Definitions, prototypes, etc. for Open Document Managment API
+ (ODMA) version 2.0.
+
+ COPYRIGHT (C) 1994, 1995
+ AIIM International
+ All Right Reserved
+*/
+
+#ifndef ODMA_H
+#define ODMA_H
+
+/* Type definitions */
+typedef LPVOID ODMHANDLE;
+typedef LPSTR (*ODMSAVEASCALLBACK)(DWORD dwEnvData, LPSTR lpszFormat, LPVOID pInstanceData);
+typedef int ODMSTATUS;
+
+/* Constants */
+#define ODM_API_VERSION 200 /* Version of the API */
+
+#ifdef WIN32
+ #define ODM_DOCID_MAX 255 /* Win32 */
+
+#elif defined( _WINDOWS_ ) || defined( _MSDOS )
+ #define ODM_DOCID_MAX 80 /* Windows 3.x */
+
+#else
+ #define ODM_DOCID_MAX 255 /* Other platforms */
+#endif
+
+#define ODM_DMSID_MAX 9 /* Max length of a DMS ID including the
+ /* terminating NULL character. */
+
+#define ODM_APPID_MAX 16 /* Max length of a application ID including
+ /* the terminating NULL character. */
+
+// ODMA 2.0
+#define ODM_QUERYID_MAX 255 // Max length of a query ID including
+ // the terminating NULL character.
+
+#define ODM_FORMAT_MAX 81 // Max length of a format including
+ // the terminating NULL character.
+
+// Maximum length of a filename returned by ODMA including the terminating
+// NULL character. Platform dependent.
+
+#ifdef WIN32
+ #define ODM_FILENAME_MAX 255 /* Win32 */
+
+#elif defined( _WINDOWS_ ) || defined( _MSDOS )
+ #define ODM_FILENAME_MAX 128 /* Windows 3.x */
+
+#elif defined( unix ) || defined( _UNIX )
+ #define ODM_FILENAME_MAX 1024 /* Unix */
+
+#else
+ #define ODM_FILENAME_MAX 255 /* Other platforms */
+#endif
+
+
+/* Common format type names */
+#define ODM_FORMAT_TEXT "Text"
+#define ODM_FORMAT_RTF "Rich text format"
+#define ODM_FORMAT_DCA "DCA RFT" /* IBM DCA Rich Format Text */
+#define ODM_FORMAT_TIFF "Tiff"
+#define ODM_FORMAT_GIF "Gif" /* Compuserve Graphics Interchange Format */
+#define ODM_FORMAT_BMP "Windows bitmap"
+#define ODM_FORMAT_PCX "PCX"
+#define ODM_FORMAT_CGM "CGM" /* Computer Graphics Metafile */
+#define ODM_FORMAT_EXE "Executable file"
+#define ODM_FORMAT_PCL "PCL" /* HP Printer Control Language */
+#define ODM_FORMAT_PS "PostScript"
+
+
+/* Error returns */
+#define ODM_SUCCESS 0 // Success!
+#define ODM_E_FAIL 1 /* Unspecified failure */
+#define ODM_E_CANCEL 2 /* Action was cancelled at user's request */
+#define ODM_E_NODMS 3 /* DMS not registered */
+#define ODM_E_CANTINIT 4 /* DMS failed to initalize */
+#define ODM_E_VERSION 5 /* DMS doesn't support the requested
+ version of ODMA */
+#define ODM_E_APPSELECT 6 /* User has indicated that he wants to use
+ the application's file selection
+ capabilities rather than those of the
+ DMS. */
+#define ODM_E_USERINT 7 /* Requested action cannot be performed
+ without user interaction, but silent
+ mode was specified. */
+#define ODM_E_HANDLE 8 /* The DMHANDLE argument was invalid. */
+#define ODM_E_ACCESS 9 /* User does not have requested access
+ rights to specified document. */
+#define ODM_E_INUSE 10 /* Document is currently in use and cannot
+ be accessed in specified mode. */
+#define ODM_E_DOCID 11 /* Invalid document ID */
+#define ODM_E_OPENMODE 12 /* The specified action is incompatible
+ with the mode in which the document was
+ opened. */
+#define ODM_E_NOOPEN 13 /* The specified document is not open. */
+#define ODM_E_ITEM 14 /* Invalid item specifier. */
+#define ODM_E_OTHERAPP 15 /* Selected document was for another app. */
+#define ODM_E_NOMOREDATA 16 /* No more data is available */
+#define ODM_E_PARTIALSUCCESS 17 /* */
+// Additional Error code from ODMA 2.0
+#define ODM_E_REQARG 18 /* */
+#define ODM_E_NOSUPPORT 19 /* */
+#define ODM_E_TRUNCATED 20 /* */
+#define ODM_E_INVARG 21
+#define ODM_E_OFFLINE 22 /* */
+
+
+// ODMOpenDoc modes
+#define ODM_MODIFYMODE 1 /* Open document in a modifiable mode. */
+#define ODM_VIEWMODE 2 /* Open document in non-modifiable mode. */
+// ODMA 2.0
+#define ODM_REFCOPY 3
+
+
+// Actions for ODMActivate
+#define ODM_NONE 0 /* No specific action is requested. */
+#define ODM_DELETE 1 /* Delete the specified document. */
+#define ODM_SHOWATTRIBUTES 2 /* Display the specified document's profile
+ or attributes. */
+#define ODM_EDITATTRIBUTES 3 /* Edit the specified document's profile or
+ attributes. */
+#define ODM_VIEWDOC 4 /* Display the specified document in a
+ viewer window. */
+#define ODM_OPENDOC 5 /* Open the specified document in its
+ native application. */
+// ODMA 2.0
+#define ODM_NEWDOC 6
+#define ODM_CHECKOUT 7
+#define ODM_CANCELCHECKOUT 8
+#define ODM_CHECKIN 9
+#define ODM_SHOWHISTORY 10
+
+
+// Item selectors for ODMGetDocInfo and ODMSetDocInfo
+#define ODM_AUTHOR 1 /* Author of the document. */
+#define ODM_NAME 2 /* Descriptive name of the document. */
+#define ODM_TYPE 3 /* Type of the document. */
+#define ODM_TITLETEXT 4 /* Suggested text to display in the
+ document window's title bar. */
+#define ODM_DMS_DEFINED 5 /* DMS defined data. */
+#define ODM_CONTENTFORMAT 6 /* String describing document's format */
+// ODMA 2.0
+#define ODM_ALTERNATE_RENDERINGS 7
+#define ODM_CHECKEDOUTBY 8
+#define ODM_CHECKOUTCOMMENT 9
+#define ODM_CHECKOUTDATE 10
+#define ODM_CREATEDBY 11
+#define ODM_CREATEDDATE 12
+#define ODM_DOCID_LATEST 13
+#define ODM_DOCID_RELEASED 14
+#define ODM_DOCVERSION 15
+#define ODM_DOCVERSION_LATEST 16
+#define ODM_DOCVERSION_RELEASED 17
+#define ODM_LOCATION 18
+#define ODM_KEYWORDS 19
+#define ODM_LASTCHECKINBY 20
+#define ODM_LASTCHECKINDATE 21
+#define ODM_MODIFYDATE 22
+#define ODM_MODIFYDATE_LATEST 23
+#define ODM_MODIFYDATE_RELEASED 24
+#define ODM_OWNER 25
+#define ODM_SUBJECT 26
+#define ODM_TITLETEXT_RO 27
+#define ODM_URL 28
+
+
+// Item selectors for ODMQueryCapability ODMA 2.0
+#define ODM_QC_ACTIVATE 1
+#define ODM_QC_CLOSEDOC 2
+#define ODM_QC_CLOSEDOCEX 3
+#define ODM_QC_GETALTERNATECONTENT 4
+#define ODM_QC_GETDMSINFO 5
+#define ODM_QC_GETDOCINFO 6
+#define ODM_QC_GETDOCRELATION 7
+#define ODM_QC_GETLEADMONIKER 8
+#define ODM_QC_NEWDOC 9
+#define ODM_QC_OPENDOC 10
+#define ODM_QC_QUERYCLOSE 11
+#define ODM_QC_QUERYEXECUTE 12
+#define ODM_QC_QUERYGETRESULTS 13
+#define ODM_QC_SAVEAS 14
+#define ODM_QC_SAVEASEX 15
+#define ODM_QC_SAVEDOC 16
+#define ODM_QC_SAVEDOCEX 17
+#define ODM_QC_SELECTDOC 18
+#define ODM_QC_SELECTDOCEX 19
+#define ODM_QC_SETALTERNATECONTENT 20
+#define ODM_QC_SETDOCEVENT 21
+#define ODM_QC_SETDOCRELATION 22
+#define ODM_QC_SETDOCINFO 23
+
+
+// Misc. modes, flags
+#define ODM_SILENT 16 /* Don't interact with the user while
+ fulfilling this request. */
+//ODMA 2.0
+#define ODM_VERSION_SAME 1
+#define ODM_VERSION_MAJOR 2
+#define ODM_VERSION_MINOR 4
+#define ODM_VERSION_CHANGED 8
+#define ODM_ALT_DELETE 32
+
+//ODMA 2.0 DMS Info Flags
+#define ODM_EXT_QUERY 1
+#define ODM_EXT_WORKFLOW 2
+
+// Flags for Query Interface
+#define ODM_ALL 1 // All DMS's should be searched
+#define ODM_SPECIFIC 2 // Only specific DMS's should be searched
+
+
+// Function prototypes
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ODMSTATUS WINAPI ODMRegisterApp(ODMHANDLE FAR *pOdmHandle, WORD version,
+ LPSTR lpszAppId, DWORD dwEnvData, LPVOID pReserved);
+
+void WINAPI ODMUnRegisterApp(ODMHANDLE odmHandle);
+
+ODMSTATUS WINAPI ODMSelectDoc(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags);
+
+ODMSTATUS WINAPI ODMOpenDoc(ODMHANDLE odmHandle, DWORD flags,
+ LPSTR lpszDocId, LPSTR lpszDocLocation);
+
+ODMSTATUS WINAPI ODMSaveDoc(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPSTR lpszNewDocId);
+
+ODMSTATUS WINAPI ODMCloseDoc(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ DWORD activeTime, DWORD pagesPrinted, LPVOID sessionData, WORD dataLen);
+
+ODMSTATUS WINAPI ODMNewDoc(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ DWORD dwFlags, LPSTR lpszFormat, LPSTR lpszDocLocation);
+
+ODMSTATUS WINAPI ODMSaveAs(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPSTR lpszNewDocId, LPSTR lpszFormat, ODMSAVEASCALLBACK pcbCallBack,
+ LPVOID pInstanceData);
+
+ODMSTATUS WINAPI ODMActivate(ODMHANDLE odmHandle, WORD action,
+ LPSTR lpszDocId);
+
+ODMSTATUS WINAPI ODMGetDocInfo(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ WORD item, LPSTR lpszData, WORD dataLen);
+
+ODMSTATUS WINAPI ODMSetDocInfo(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ WORD item, LPSTR lpszData);
+
+ODMSTATUS WINAPI ODMGetDMSInfo(ODMHANDLE odmHandle, LPSTR lpszDmsId,
+ LPWORD pwVerNo, LPDWORD pdwExtensions);
+
+/* Query Enhancements */
+WORD WINAPI ODMGetDMSCount();
+
+WORD WINAPI ODMGetDMSList( LPSTR buffer, WORD buffer_size );
+
+ODMSTATUS WINAPI ODMGetDMS( LPCSTR lpszAppId, LPSTR lpszDMSId );
+
+ODMSTATUS WINAPI ODMSetDMS( LPCSTR lpszAppId, LPCSTR lpszDMSId );
+
+ODMSTATUS WINAPI ODMQueryExecute(ODMHANDLE odmHandle, LPCSTR lpszQuery,
+ DWORD flags, LPCSTR lpszDMSList, LPSTR queryId );
+
+ODMSTATUS WINAPI ODMQueryGetResults(ODMHANDLE odmHandle, LPCSTR queryId,
+ LPSTR lpszDocId, LPSTR lpszDocName, WORD docNameLen,
+ WORD *docCount );
+
+ODMSTATUS WINAPI ODMQueryClose(ODMHANDLE odmHandle, LPCSTR queryId );
+
+/* ODMA 2.0 Enhancements */
+ODMSTATUS WINAPI ODMCloseDocEx(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags, DWORD activeTime, DWORD pagesPrinted,
+ LPVOID sessionData, WORD dataLen);
+
+ODMSTATUS WINAPI ODMSaveAsEx(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPSTR lpszNewDocId, LPSTR lpszFormat, ODMSAVEASCALLBACK pcbCallBack,
+ LPVOID pInstanceData, LPDWORD pdwFlags);
+
+ODMSTATUS WINAPI ODMSaveDocEx(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPSTR lpszNewDocId, LPDWORD pdwFlags);
+
+ODMSTATUS WINAPI ODMSelectDocEx(ODMHANDLE odmHandle, LPSTR lpszDocIds,
+ LPWORD pwDocIdsLen, LPWORD pwDocCount, LPDWORD pdwFlags,
+ LPSTR lpszFormatFilter);
+
+ODMSTATUS WINAPI ODMQueryCapability(ODMHANDLE odmHandle, LPCSTR lpszDmsId,
+ DWORD function, DWORD item, DWORD flags);
+
+ODMSTATUS WINAPI ODMSetDocEvent(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ DWORD flags, DWORD event, LPVOID lpData, DWORD dwDataLen,
+ LPSTR lpszComment);
+
+ODMSTATUS WINAPI ODMGetAlternateContent(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags, LPSTR lpszFormat, LPSTR lpszDocLocation);
+
+ODMSTATUS WINAPI ODMSetAlternateContent(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags, LPSTR lpszFormat, LPSTR lpszDocLocation);
+
+ODMSTATUS WINAPI ODMGetDocRelation(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags, LPSTR lpszLinkedId, LPSTR lpszFormat,
+ LPSTR lpszPreviousId);
+
+ODMSTATUS WINAPI ODMSetDocRelation(ODMHANDLE odmHandle, LPSTR lpszDocId,
+ LPDWORD pdwFlags, LPSTR lpszLinkedId, LPSTR lpszFormat,
+ LPSTR lpszPreviousId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ucb/source/ucp/odma/odma_content.cxx b/ucb/source/ucp/odma/odma_content.cxx
new file mode 100644
index 000000000000..ae3c3ede60e7
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_content.cxx
@@ -0,0 +1,1215 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include "odma_contentprops.hxx"
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include "odma_content.hxx"
+#include "odma_provider.hxx"
+#include "odma_resultset.hxx"
+#include "odma_inputstream.hxx"
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <rtl/ref.hxx>
+#include <osl/file.hxx>
+
+using namespace com::sun::star;
+using namespace odma;
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ::rtl::Reference<ContentProperties>& _rProps)
+ : ContentImplHelper( rxSMgr, pProvider, Identifier )
+ ,m_aProps(_rProps)
+ ,m_pProvider(pProvider)
+ ,m_pContent(NULL)
+{
+ OSL_ENSURE(m_aProps.is(),"No valid ContentPropeties!");
+}
+
+//=========================================================================
+// virtual
+Content::~Content()
+{
+ delete m_pContent;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Content::acquire() throw()
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::release() throw()
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ // @@@ Add support for additional interfaces.
+#if 0
+ aRet = cppu::queryInterface( rType,
+ static_cast< yyy::Xxxxxxxxx * >( this ) );
+#endif
+
+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ // @@@ Add own interfaces.
+
+ static cppu::OTypeCollection* pCollection = 0;
+
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+ pCollection = &aCollection;
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ // @@@ Adjust implementation name. Keep the prefix "com.sun.star.comp."!
+ return rtl::OUString::createFromAscii( "com.sun.star.comp.odma.Content" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ // @@@ Adjust macro name.
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString::createFromAscii( ODMA_CONTENT_SERVICE_NAME );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ // @@@ Adjust macro name ( def in odma_provider.hxx ).
+ return rtl::OUString::createFromAscii( ODMA_CONTENT_TYPE );
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ OSL_ENSURE( sal_False, "No properties!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getPropertySetInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getCommandInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
+ {
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ sal_Bool bOpenFolder =
+ ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) ||
+ ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
+ ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) );
+
+ if ( bOpenFolder)
+ {
+ // open as folder - return result set
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr,
+ this,
+ aOpenCommand,
+ Environment );
+ aRet <<= xSet;
+ }
+
+ if ( aOpenCommand.Sink.is() )
+ {
+ // Open document - supply document data stream.
+
+ // Check open mode
+ if ( ( aOpenCommand.Mode
+ == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( aOpenCommand.Mode
+ == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+ {
+ // Unsupported.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( aOpenCommand.Mode ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ rtl::OUString sFileURL = openDoc();
+ delete m_pContent;
+ m_pContent = new ::ucbhelper::Content(sFileURL,NULL);
+ if(!m_pContent->isDocument())
+ {
+ rtl::OUString sErrorMsg(RTL_CONSTASCII_USTRINGPARAM("File: "));
+ sErrorMsg += sFileURL;
+ sErrorMsg += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" could not be found."));
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( io::IOException(
+ sErrorMsg,
+ static_cast< cppu::OWeakObject * >( this )) ),
+ Environment );
+ }
+
+ uno::Reference< io::XOutputStream > xOut
+ = uno::Reference< io::XOutputStream >(
+ aOpenCommand.Sink, uno::UNO_QUERY );
+ if ( xOut.is() )
+ {
+ // @@@ PUSH: write data into xOut
+ m_pContent->openStream(xOut);
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataSink > xDataSink
+ = uno::Reference< io::XActiveDataSink >(
+ aOpenCommand.Sink, uno::UNO_QUERY );
+ if ( xDataSink.is() )
+ {
+ // @@@ PULL: wait for client read
+ uno::Reference< io::XInputStream > xIn;
+ try
+ {
+ xIn = m_pContent->openStream();
+ }
+ catch(uno::Exception&)
+ {
+ OSL_ENSURE(0,"Exception occured while creating the file content!");
+ }
+ xDataSink->setInputStream( xIn );
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataStreamer > activeDataStreamer( aOpenCommand.Sink,uno::UNO_QUERY );
+ if(activeDataStreamer.is())
+ {
+ activeDataStreamer->setStream(new OOdmaStream(m_pContent,getContentProvider(),m_aProps));
+ m_pContent = NULL; // don't delete here because the stream is now the owner
+ }
+ else
+ {
+ // Note: aOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aOpenCommand.Sink ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+ }
+ }
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "close" ) ) )
+ {
+ getContentProvider()->closeDocument(m_aProps->m_sDocumentId);
+ }
+ else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ //////////////////////////////////////////////////////////////////
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ // Remove own and all childrens(!) persistent data.
+ if(!getContentProvider()->deleteDocument(m_aProps))
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ //////////////////////////////////////////////////////////////////
+
+ ucb::InsertCommandArgument arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ insert( arg.Data, arg.ReplaceExisting, Environment );
+ }
+ else if( ! aCommand.Name.compareToAscii( "transfer" ) )
+ {
+ ucb::TransferInfo aTransferInfo;
+ if( ! ( aCommand.Argument >>= aTransferInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ ::rtl::Reference<ContentProperties> aProp = m_aProps;
+ if(aProp->m_bIsFolder)
+ {
+ aProp = getContentProvider()->getContentPropertyWithTitle(aTransferInfo.NewTitle);
+ if(!aProp.is())
+ aProp = getContentProvider()->getContentPropertyWithSavedAsName(aTransferInfo.NewTitle);
+ sal_Bool bError = !aProp.is();
+ if(bError)
+ {
+ sal_Char* pExtension = NULL;
+ ::rtl::OString sExt;
+ sal_Int32 nPos = aTransferInfo.NewTitle.lastIndexOf('.');
+ if(nPos != -1)
+ {
+ sExt = ::rtl::OUStringToOString(aTransferInfo.NewTitle.copy(nPos+1),RTL_TEXTENCODING_ASCII_US);
+ if(sExt.equalsIgnoreAsciiCase("txt"))
+ pExtension = ODM_FORMAT_TEXT;
+ else if(sExt.equalsIgnoreAsciiCase("rtf"))
+ pExtension = ODM_FORMAT_RTF;
+ else if(sExt.equalsIgnoreAsciiCase("ps"))
+ pExtension = ODM_FORMAT_PS;
+ else
+ pExtension = const_cast<sal_Char*>(sExt.getStr());
+ }
+ else
+ pExtension = ODM_FORMAT_TEXT;
+
+ sal_Char* lpszNewDocId = new sal_Char[ODM_DOCID_MAX];
+ void *pData = NULL;
+ DWORD dwFlags = ODM_SILENT;
+ ODMSTATUS odm = NODMSaveAsEx(ContentProvider::getHandle(),
+ NULL, // means it is saved the first time
+ lpszNewDocId,
+ pExtension,
+ NULL, // no callback function here
+ pData,
+ &dwFlags);
+
+ // check if we have to call the DMS dialog
+ if(odm == ODM_E_USERINT)
+ {
+ dwFlags = 0;
+ odm = NODMSaveAsEx(ContentProvider::getHandle(),
+ NULL, // means it is saved the first time
+ lpszNewDocId,
+ pExtension,
+ NULL, // no callback function here
+ pData,
+ &dwFlags);
+ }
+ bError = odm != ODM_SUCCESS;
+ if(!bError)
+ {
+ aProp = new ContentProperties();
+ aProp->m_sDocumentId = ::rtl::OString(lpszNewDocId);
+ aProp->m_sContentType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
+ aProp->m_sSavedAsName = aTransferInfo.NewTitle;
+ getContentProvider()->append(aProp);
+
+ // now set the title
+ WORD nDocInfo = ODM_NAME;
+ ::rtl::OUString sFileName = aTransferInfo.NewTitle;
+ sal_Int32 nIndex = aTransferInfo.NewTitle.lastIndexOf( sal_Unicode('.') );
+ if(nIndex != -1)
+ sFileName = aTransferInfo.NewTitle.copy(0,nIndex);
+
+ ::rtl::OString sDocInfoValue = ::rtl::OUStringToOString(sFileName,RTL_TEXTENCODING_ASCII_US);
+ odm = NODMSetDocInfo( ContentProvider::getHandle(),
+ lpszNewDocId,
+ nDocInfo,
+ const_cast<sal_Char*>(sDocInfoValue.getStr())
+ );
+
+ }
+ else if ( odm == ODM_E_CANCEL)
+ NODMActivate(ContentProvider::getHandle(),
+ ODM_DELETE,
+ lpszNewDocId);
+
+ delete [] lpszNewDocId;
+ }
+ if(bError)
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ }
+ rtl::OUString sFileURL = ContentProvider::openDoc(aProp);
+
+ sal_Int32 nLastIndex = sFileURL.lastIndexOf( sal_Unicode('/') );
+ ::ucbhelper::Content aContent(sFileURL.copy(0,nLastIndex),NULL);
+ // aTransferInfo.NameClash = ucb::NameClash::OVERWRITE;
+ aTransferInfo.NewTitle = sFileURL.copy( 1 + nLastIndex );
+ aContent.executeCommand(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("transfer")),uno::makeAny(aTransferInfo));
+ getContentProvider()->saveDocument(aProp->m_sDocumentId);
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ OSL_ENSURE( sal_False, "Content::execute - unsupported command!" );
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ // @@@ Implement logic to abort running commands, if this makes
+ // sense for your content.
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+// virtual
+::rtl::OUString Content::getParentURL()
+{
+ ::rtl::OUString sURL = m_xIdentifier->getContentIdentifier();
+
+ // @@@ Extract URL of parent from aURL and return it...
+ static ::rtl::OUString sScheme1(RTL_CONSTASCII_USTRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT "/"));
+ static ::rtl::OUString sScheme2(RTL_CONSTASCII_USTRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT));
+ if(sURL == sScheme1 || sURL == sScheme2)
+ sURL = ::rtl::OUString();
+ else
+ sURL = sScheme1;
+
+ return sURL;
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const rtl::Reference<ContentProperties>& rData,
+ const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
+ const rtl::OUString& rContentId )
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ uno::Reference< beans::XPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ // Process Core properties.
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ xRow->appendString ( rProp, rData->m_sContentType );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, rData->m_sTitle );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData->m_bIsDocument );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData->m_bIsFolder );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
+ {
+ xRow->appendTimestamp( rProp, rData->m_aDateCreated );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
+ {
+ xRow->appendTimestamp( rProp, rData->m_aDateModified );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData->m_bIsReadOnly );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Author" ) ) )
+ {
+ xRow->appendString ( rProp, rData->m_sAuthor );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Subject" ) ) )
+ {
+ xRow->appendString ( rProp, rData->m_sSubject );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Keywords" ) ) )
+ {
+ xRow->appendString ( rProp, rData->m_sKeywords );
+ }
+ else
+ {
+ // @@@ Note: If your data source supports adding/removing
+ // properties, you should implement the interface
+ // XPropertyContainer by yourself and supply your own
+ // logic here. The base class uses the service
+ // "com.sun.star.ucb.Store" to maintain Additional Core
+ // properties. But using server functionality is preferred!
+
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ rProvider->getAdditionalPropertySet( rContentId,
+ sal_False ),
+ uno::UNO_QUERY );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ if ( !xRow->appendPropertySetValue(
+ xAdditionalPropSet,
+ rProp ) )
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ else
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ }
+ }
+ else
+ {
+ // Append all Core Properties.
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "ContentType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_sContentType );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData->m_sTitle );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_bIsDocument );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_bIsFolder );
+
+ // @@@ Append other properties supported directly.
+ xRow->appendTimestamp(
+ beans::Property( rtl::OUString::createFromAscii( "DateCreated" ),
+ -1,
+ getCppuType(static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_aDateCreated );
+ xRow->appendTimestamp(
+ beans::Property( rtl::OUString::createFromAscii( "DateModified" ),
+ -1,
+ getCppuType(static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_aDateModified );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsReadOnly" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData->m_bIsReadOnly );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Author" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData->m_sAuthor );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Subject" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData->m_sSubject );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Keywords" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData->m_sKeywords );
+
+ // @@@ Note: If your data source supports adding/removing
+ // properties, you should implement the interface
+ // XPropertyContainer by yourself and supply your own
+ // logic here. The base class uses the service
+ // "com.sun.star.ucb.Store" to maintain Additional Core
+ // properties. But using server functionality is preferred!
+
+ // Append all Additional Core Properties.
+
+ uno::Reference< beans::XPropertySet > xSet(
+ rProvider->getAdditionalPropertySet( rContentId, sal_False ),
+ uno::UNO_QUERY );
+ xRow->appendPropertySet( xSet );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+//=========================================================================
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties,
+ const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return getPropertyValues( m_xSMgr,
+ rProperties,
+ m_aProps,
+ rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >(
+ m_xProvider.get() ),
+ m_xIdentifier->getContentIdentifier() );
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+// aEvent.PropertyName =
+ aEvent.PropertyHandle = -1;
+// aEvent.OldValue =
+// aEvent.NewValue =
+
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+
+ uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+
+ if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ changePropertyValue(rValue,n,m_aProps->m_sTitle,nChanged,aRet,aChanges);
+ }
+ else if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "Author") ) )
+ {
+ changePropertyValue(rValue,n,m_aProps->m_sAuthor,nChanged,aRet,aChanges);
+ }
+ else if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "Keywords") ) )
+ {
+ changePropertyValue(rValue,n,m_aProps->m_sKeywords,nChanged,aRet,aChanges);
+ }
+ else if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "Subject") ) )
+ {
+ changePropertyValue(rValue,n,m_aProps->m_sSubject,nChanged,aRet,aChanges);
+ }
+ else if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
+ rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
+ rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
+ rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ||
+ rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ||
+ rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Property is read-only!") ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // @@@ Note: If your data source supports adding/removing
+ // properties, you should implement the interface
+ // XPropertyContainer by yourself and supply your own
+ // logic here. The base class uses the service
+ // "com.sun.star.ucb.Store" to maintain Additional Core
+ // properties. But using server functionality is preferred!
+
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet = getAdditionalPropertySet( sal_False );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ try
+ {
+ uno::Any aOldValue
+ = xAdditionalPropSet->getPropertyValue( rValue.Name );
+ if ( aOldValue != rValue.Value )
+ {
+ xAdditionalPropSet->setPropertyValue(
+ rValue.Name, rValue.Value );
+
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = aOldValue;
+ aEvent.NewValue = rValue.Value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ else
+ {
+ // Old value equals new value. No error!
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( beans::PropertyVetoException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::IllegalArgumentException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= uno::Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+
+ if ( nChanged > 0 )
+ {
+ // @@@ Save changes.
+// storeData();
+
+ aGuard.clear();
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+#if 0
+//=========================================================================
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ // @@@ Adapt method to your URL scheme...
+
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ OUString aURL = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
+
+ if ( nPos != ( aURL.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aURL += OUString::createFromAscii( "/" );
+ }
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ OUString aChildURL = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) ||
+ ( nPos == ( aChildURL.getLength() - 1 ) ) )
+ {
+ // No further slashes / only a final slash. It's a child!
+ rChildren.push_back(
+ ContentRef(
+ static_cast< Content * >( xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+#endif
+//=========================================================================
+void Content::insert(
+ const uno::Reference< io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Check, if all required properties were set.
+ if ( !m_aProps->m_sTitle.getLength())
+ {
+ OSL_ENSURE( sal_False, "Content::insert - property value missing!" );
+
+ uno::Sequence< rtl::OUString > aProps( 1 );
+ aProps[ 0 ] = rtl::OUString::createFromAscii( "zzzz" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingPropertiesException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aProps ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !xInputStream.is() )
+ {
+ OSL_ENSURE( sal_False, "Content::insert - No data stream!" );
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingInputStreamException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ // Assemble new content identifier...
+
+ // uno::Reference< ucb::XContentIdentifier > xId = ...;
+
+ // Fail, if a resource with given id already exists.
+ if ( !bReplaceExisting ) // && hasData( m_xIdentifier ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+// ucbhelper::cancelCommandExecution(
+// ucb::IOErrorCode_ALREADY_EXISTING,
+// Environment,
+// uno::makeAny(static_cast< cppu::OWeakObject * >( this ))
+// );
+ // Unreachable
+ }
+
+ // m_xIdentifier = xId;
+
+// @@@
+// storeData();
+
+ aGuard.clear();
+ inserted();
+}
+#if 0
+//=========================================================================
+void Content::destroy( sal_Bool bDeletePhysical )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ deleted();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical );
+ ++it;
+ }
+}
+#endif
+
+// -----------------------------------------------------------------------------
+::rtl::OUString Content::openDoc()
+{
+ OSL_ENSURE(m_aProps.is(),"No valid content properties!");
+ return ContentProvider::openDoc(m_aProps);
+}
+// -----------------------------------------------------------------------------
+void Content::changePropertyValue(const beans::PropertyValue& _rValue,
+ sal_Int32 _rnCurrentPos,
+ ::rtl::OUString& _rsMemberValue,
+ sal_Int32& _rnChanged,
+ uno::Sequence< uno::Any >& _rRet,
+ uno::Sequence< beans::PropertyChangeEvent >& _rChanges) throw (beans::IllegalTypeException)
+{
+ rtl::OUString sNewValue;
+ sal_Bool bError = sal_False;
+ if ( _rValue.Value >>= sNewValue )
+ {
+ if ( sNewValue != _rsMemberValue )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ // first we have to check if we could change the property inside the DMS
+ ::rtl::OString sDocInfoValue = ::rtl::OUStringToOString(sNewValue,RTL_TEXTENCODING_ASCII_US);
+ WORD nDocInfo = 0;
+ if(&_rsMemberValue == &m_aProps->m_sTitle)
+ nDocInfo = ODM_TITLETEXT;
+ else if(&_rsMemberValue == &m_aProps->m_sAuthor)
+ nDocInfo = ODM_AUTHOR;
+ else if(&_rsMemberValue == &m_aProps->m_sSubject)
+ nDocInfo = ODM_SUBJECT;
+ else if(&_rsMemberValue == &m_aProps->m_sKeywords)
+ nDocInfo = ODM_KEYWORDS;
+ else
+ bError = sal_True;
+
+ if(!bError)
+ {
+ ODMSTATUS odm = NODMSetDocInfo( ContentProvider::getHandle(),
+ const_cast<sal_Char*>(m_aProps->m_sDocumentId.getStr()),
+ nDocInfo,
+ const_cast<sal_Char*>(sDocInfoValue.getStr())
+ );
+ if(odm == ODM_SUCCESS)
+ {
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = -1;
+ aEvent.PropertyName = _rValue.Name;
+ aEvent.OldValue = uno::makeAny( _rsMemberValue );
+ aEvent.NewValue = uno::makeAny( sNewValue );
+
+ _rChanges.getArray()[ _rnChanged ] = aEvent;
+
+ _rsMemberValue = sNewValue;
+ ++_rnChanged;
+ }
+ }
+ }
+ else
+ {
+ // Old value equals new value. No error!
+ }
+ }
+ else
+ bError = sal_True;
+
+ if(bError)
+ {
+ _rRet[ _rnCurrentPos ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+}
+// -----------------------------------------------------------------------------
+
diff --git a/ucb/source/ucp/odma/odma_content.hxx b/ucb/source/ucp/odma/odma_content.hxx
new file mode 100644
index 000000000000..30422a82e284
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_content.hxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef ODMA_CONTENT_HXX
+#define ODMA_CONTENT_HXX
+
+#include <list>
+#include <ucbhelper/contenthelper.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace beans {
+ struct Property;
+ struct PropertyValue;
+ }
+ namespace sdbc {
+ class XRow;
+ }
+ namespace io {
+ class XInputStream;
+ }
+}}}
+namespace ucbhelper
+{
+ class Content;
+}
+
+
+// @@@ Adjust namespace name.
+namespace odma
+{
+
+//=========================================================================
+
+// @@@ Adjust service name.
+
+// UNO service name for the content.
+#define ODMA_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.OdmaContent"
+
+//=========================================================================
+class ContentProvider;
+class ContentProperties;
+class Content : public ::ucbhelper::ContentImplHelper
+{
+ ::rtl::Reference<ContentProperties> m_aProps;
+ ContentProvider* m_pProvider;
+ ::ucbhelper::Content* m_pContent;
+
+private:
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+ /** openDoc returns the file URL for the DOC ID
+ @return the url of the temporary file
+ */
+ ::rtl::OUString openDoc();
+
+ /** changePropertyValue sets the property referenced by _sMemberValue to the new value
+ @param _rValue the new value to set
+ @param _rnCurrentPos the current position inside the Any sequence _rRet
+ @param _sMemberValue the place where to set the property
+ @param _rnChanged will be incremented when property changed
+ @param _rRet collect the exceptions
+ @param _rChanges contains the changes done
+ */
+ void changePropertyValue(const ::com::sun::star::beans::PropertyValue& _rValue,
+ sal_Int32 _rnCurrentPos,
+ ::rtl::OUString& _rsMemberValue,
+ sal_Int32& _rnChanged,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rRet,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& _rChanges) throw (::com::sun::star::beans::IllegalTypeException);
+
+// typedef rtl::Reference< Content > ContentRef;
+// typedef std::list< ContentRef > ContentRefList;
+// void queryChildren( ContentRefList& rChildren );
+
+ // Command "insert"
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+// // Command "delete"
+// void destroy( sal_Bool bDeletePhysical )
+// throw( ::com::sun::star::uno::Exception );
+
+public:
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const ::rtl::Reference<ContentProperties>& _rProps);
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // @@@ Add additional interfaces ( like com::sun:.star::ucb::XContentCreator ).
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ // Called from resultset data supplier.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ::rtl::Reference<ContentProperties>& rData,
+ const ::rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >& rProvider,
+ const ::rtl::OUString& rContentId );
+
+ ContentProvider* getContentProvider() const { return m_pProvider; }
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/odma/odma_contentcaps.cxx b/ucb/source/ucp/odma/odma_contentcaps.cxx
new file mode 100644
index 000000000000..8bc0b5cd51dc
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_contentcaps.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include "odma_content.hxx"
+
+using namespace com::sun::star;
+using namespace odma;
+
+//=========================================================================
+//
+// Content implementation.
+//
+//=========================================================================
+
+//=========================================================================
+//
+// IMPORTENT: If any property data ( name / type / ... ) are changed, then
+// Content::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ // @@@ Add additional properties...
+
+ // @@@ Note: If your data source supports adding/removing properties,
+ // you should implement the interface XPropertyContainer
+ // by yourself and supply your own logic here. The base class
+ // uses the service "com.sun.star.ucb.Store" to maintain
+ // Additional Core properties. But using server functionality
+ // is preferred! In fact you should return a table conatining
+ // even that dynamicly added properties.
+
+// osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ //=================================================================
+ //
+ // Supported properties
+ //
+ //=================================================================
+
+ #define PROPERTY_COUNT 10
+
+ static beans::Property aPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
+ -1,
+ getCppuType(static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
+ -1,
+ getCppuType(static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Subject" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Keywords" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ )
+ };
+ return uno::Sequence<
+ beans::Property >( aPropertyInfoTable, PROPERTY_COUNT );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ // @@@ Add additional commands...
+
+// osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ //=================================================================
+ //
+ // Supported commands
+ //
+ //=================================================================
+
+ #define COMMAND_COUNT 8
+
+ static ucb::CommandInfo aCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
+/*
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+*/
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::InsertCommandArgument * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType( static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "close" ) ),
+ -1,
+ getCppuVoidType( )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ )
+
+ ///////////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////////
+ };
+
+ return uno::Sequence<
+ ucb::CommandInfo >( aCommandInfoTable, COMMAND_COUNT );
+}
+
diff --git a/ucb/source/ucp/odma/odma_contentprops.hxx b/ucb/source/ucp/odma/odma_contentprops.hxx
new file mode 100644
index 000000000000..602c1d3d8354
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_contentprops.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef ODMA_CONTENTPROPS_HXX
+#define ODMA_CONTENTPROPS_HXX
+
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include <rtl/ustring.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <functional>
+
+namespace odma
+{
+ class ContentProperties : public salhelper::SimpleReferenceObject
+ {
+ public:
+ com::sun::star::util::DateTime m_aDateCreated; // when was the document created
+ com::sun::star::util::DateTime m_aDateModified; // when was the document last modified
+ ::rtl::OUString m_sTitle; // Title
+ ::rtl::OUString m_sContentType; // ContentType
+ ::rtl::OString m_sDocumentId; // the document id given from the DMS
+ ::rtl::OUString m_sDocumentName;// document name
+ ::rtl::OUString m_sFileURL; // the temporary file location
+ ::rtl::OUString m_sAuthor; // the Author of the document
+ ::rtl::OUString m_sSubject; // the subject of the document
+ ::rtl::OUString m_sKeywords; // the keywords of the document
+ ::rtl::OUString m_sSavedAsName; // the name which was used to save it
+ sal_Bool m_bIsDocument; // IsDocument
+ sal_Bool m_bIsFolder; // IsFolder
+ sal_Bool m_bIsOpen; // is true when OpenDoc was called
+ sal_Bool m_bIsReadOnly; // true when the document is read-only
+
+ // @@@ Add other properties supported by your content.
+
+ ContentProperties()
+ :m_bIsDocument( sal_True )
+ ,m_bIsFolder( sal_False )
+ ,m_bIsOpen( sal_False )
+ ,m_bIsReadOnly( sal_False )
+ {}
+
+ inline ::rtl::OUString getTitle() const { return m_sTitle; }
+ inline ::rtl::OUString getSavedAsName() const { return m_sSavedAsName; }
+ };
+ typedef ::std::binary_function< ::rtl::Reference<ContentProperties>, ::rtl::OUString,bool> TContentPropertiesFunctorBase;
+ /// binary_function Functor object for class ContentProperties return type is bool
+ class ContentPropertiesMemberFunctor : public TContentPropertiesFunctorBase
+ {
+ ::std::const_mem_fun_t< ::rtl::OUString,ContentProperties> m_aFunction;
+ public:
+ ContentPropertiesMemberFunctor(const ::std::const_mem_fun_t< ::rtl::OUString,ContentProperties>& _rFunc)
+ : m_aFunction(_rFunc){}
+
+ inline bool operator()(const ::rtl::Reference<ContentProperties>& lhs,const ::rtl::OUString& rhs) const
+ {
+ return !!(m_aFunction(lhs.get()) == rhs);
+ }
+ };
+}
+#endif // ODMA_CONTENTPROPS_HXX
+
diff --git a/ucb/source/ucp/odma/odma_datasupplier.cxx b/ucb/source/ucp/odma/odma_datasupplier.cxx
new file mode 100644
index 000000000000..aab2a3d8663c
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_datasupplier.cxx
@@ -0,0 +1,455 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+#include "odma_datasupplier.hxx"
+#include "odma_content.hxx"
+#include "odma_contentprops.hxx"
+#include "odma_provider.hxx"
+#include "odma_lib.hxx"
+
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdbc;
+
+using namespace odma;
+
+namespace odma
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ ::rtl::OUString aId;
+ Reference< XContentIdentifier > xId;
+ Reference< XContent > xContent;
+ Reference< XRow > xRow;
+ ::rtl::Reference<ContentProperties> rData;
+
+ ResultListEntry( const ::rtl::Reference<ContentProperties>& rEntry ) : rData( rEntry ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ Reference< XMultiServiceFactory > m_xSMgr;
+// @@@ The data source and an iterator for it
+// Entry m_aFolder;
+// Entry::iterator m_aIterator;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+
+ DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+// m_aFolder( rxSMgr, rContent->getIdentifier()->getContentIdentifier() ),
+ m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DataSupplier::DataSupplier( const Reference<XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< ::odma::Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+DataSupplier::~DataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ ::rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ ::rtl::OUString aId
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+
+ aId += m_pImpl->m_aResults[ nIndex ]->rData->m_sTitle;
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+ return ::rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+Reference< XContentIdentifier > DataSupplier::queryContentIdentifier(
+ sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ ::rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ Reference< XContentIdentifier > xId
+ = new ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return Reference< XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+Reference< XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ Reference< XContentIdentifier > xId = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ Reference< XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( IllegalIdentifierException& )
+ {
+ }
+ }
+ return Reference< XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ sal_Bool bFound = sal_False;
+// sal_uInt32 nPos = nOldCount;
+
+ // @@@ Obtain data and put it into result list...
+/*
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ {
+ m_pImpl->m_aResults.push_back(
+ new ResultListEntry( *m_pImpl->m_aIterator ) );
+
+ if ( nPos == nIndex )
+ {
+ // Result obtained.
+ bFound = sal_True;
+ break;
+ }
+
+ nPos++;
+ }
+*/
+ // now query for all documents in the DMS
+ OSL_ENSURE(ContentProvider::getHandle(),"No Handle!");
+ sal_Char* pQueryId = new sal_Char[ODM_QUERYID_MAX];
+ sal_Char* lpszDMSList = new sal_Char[ODM_DMSID_MAX];
+
+ ODMSTATUS odm = NODMGetDMS(ODMA_ODMA_REGNAME, lpszDMSList);
+ lpszDMSList[strlen(lpszDMSList)+1] = '\0';
+
+ ::rtl::OString sQuery("SELECT ODM_DOCID, ODM_NAME");
+
+ DWORD dwFlags = ODM_SPECIFIC;
+ odm = NODMQueryExecute(ContentProvider::getHandle(), sQuery,dwFlags, lpszDMSList, pQueryId );
+ if(odm != ODM_SUCCESS)
+ return sal_False;
+
+ sal_uInt16 nCount = 10;
+ sal_uInt16 nMaxCount = 10;
+ sal_Char* lpszDocId = new sal_Char[ODM_DOCID_MAX * nMaxCount];
+ sal_Char* lpszDocName = new sal_Char[ODM_NAME_MAX * nMaxCount];
+
+
+ ::rtl::OUString sContentType(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
+ sal_uInt32 nCurrentCount = 0;
+ do
+ {
+ if(nCount >= nMaxCount)
+ {
+ nCount = nMaxCount;
+ odm = NODMQueryGetResults(ContentProvider::getHandle(), pQueryId,lpszDocId, lpszDocName, ODM_NAME_MAX, (WORD*)&nCount);
+ nCurrentCount += nCount;
+ }
+ if(odm == ODM_SUCCESS && nIndex < nCurrentCount)
+ {
+ bFound = sal_True;
+ for(sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ ::rtl::Reference<ContentProperties> rProps = new ContentProperties();
+ rProps->m_sDocumentId = ::rtl::OString(&lpszDocId[ODM_DOCID_MAX*i]);
+ rProps->m_sContentType = sContentType;
+ m_pImpl->m_xContent->getContentProvider()->append(rProps);
+ m_pImpl->m_aResults.push_back( new ResultListEntry(rProps));
+ }
+ }
+ }
+ while(nCount > nMaxCount);
+
+
+ // now close the query
+ odm = NODMQueryClose(ContentProvider::getHandle(), pQueryId);
+
+ delete [] lpszDMSList;
+ delete [] pQueryId;
+ delete [] lpszDocId;
+ delete [] lpszDocName;
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ // @@@ Obtain data and put it into result list...
+/*
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ m_pImpl->m_aResults.push_back(
+ new ResultListEntry( *m_pImpl->m_aIterator ) );
+*/
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ Reference< XRow > xRow = Content::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ m_pImpl->m_aResults[ nIndex ]->rData,
+ m_pImpl->m_xContent->getProvider(),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return Reference< XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::validate()
+ throw( ResultSetException )
+{
+}
diff --git a/ucb/source/ucp/odma/odma_datasupplier.hxx b/ucb/source/ucp/odma/odma_datasupplier.hxx
new file mode 100644
index 000000000000..a37ecebf0e39
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_datasupplier.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef ODMA_DATASUPPLIER_HXX
+#define ODMA_DATASUPPLIER_HXX
+
+#include <ucbhelper/resultset.hxx>
+
+namespace odma {
+
+struct DataSupplier_Impl;
+class Content;
+
+class DataSupplier : public ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+public:
+ DataSupplier( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode );
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/odma/odma_inputstream.cxx b/ucb/source/ucp/odma/odma_inputstream.cxx
new file mode 100644
index 000000000000..65491c34829b
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_inputstream.cxx
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "odma_inputstream.hxx"
+#include "com/sun/star/io/IOException.hpp"
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include "odma_contentprops.hxx"
+#include "odma_provider.hxx"
+
+using namespace odma;
+using namespace com::sun::star;
+
+class OActiveDataStreamer : public ::cppu::WeakImplHelper1< io::XActiveDataStreamer>
+{
+ uno::Reference< io::XStream > m_xStream;
+public:
+ OActiveDataStreamer(){}
+ virtual void SAL_CALL setStream( const uno::Reference< io::XStream >& _rStream ) throw (uno::RuntimeException)
+ {
+ m_xStream = _rStream;
+ }
+ virtual uno::Reference< io::XStream > SAL_CALL getStream( ) throw (uno::RuntimeException)
+ {
+ return m_xStream;
+ }
+};
+// -----------------------------------------------------------------------------
+OOdmaStream::OOdmaStream(::ucbhelper::Content* _pContent,
+ ContentProvider* _pProvider,
+ const ::rtl::Reference<ContentProperties>& _rProp)
+ :m_pContent(_pContent)
+ ,m_bInputStreamCalled(sal_False)
+ ,m_bOutputStreamCalled(sal_False)
+ ,m_bModified(sal_False)
+ ,m_pProvider(_pProvider)
+ ,m_aProp(_rProp)
+{
+}
+// -----------------------------------------------------------------------------
+OOdmaStream::~OOdmaStream()
+{
+ try
+ {
+ closeStream();
+ delete m_pContent;
+ }
+ catch (io::IOException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+ catch (uno::RuntimeException const &)
+ {
+ OSL_ENSURE(false, "unexpected situation");
+ }
+}
+// -----------------------------------------------------------------------------
+uno::Reference< io::XInputStream > SAL_CALL OOdmaStream::getInputStream( ) throw( uno::RuntimeException)
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = sal_True;
+ }
+ return uno::Reference< io::XInputStream >( this );
+}
+// -----------------------------------------------------------------------------
+uno::Reference< io::XOutputStream > SAL_CALL OOdmaStream::getOutputStream( ) throw( uno::RuntimeException )
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = sal_True;
+ }
+ return uno::Reference< io::XOutputStream >( this );
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL OOdmaStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ ensureInputStream();
+
+ return m_xInput->readBytes(aData,nBytesToRead);
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL OOdmaStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ return readBytes( aData,nMaxBytesToRead );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ensureInputStream();
+ m_xInput->skipBytes(nBytesToSkip );
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL OOdmaStream::available()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ ensureInputStream();
+ return m_xInput->available();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException)
+{
+ ensureOutputStream();
+ m_xOutput->writeBytes(aData);
+ m_bModified = sal_True;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::closeStream() throw( io::NotConnectedException,io::IOException,uno::RuntimeException )
+{
+ if( m_xInput.is() )
+ {
+ m_xInput->closeInput();
+ m_xInput = NULL;
+ m_xInputSeek = NULL;
+ }
+ if(m_xOutput.is())
+ {
+ m_xOutput->closeOutput();
+ m_xOutput = NULL;
+ m_xTruncate = NULL;
+ if(m_bModified)
+ m_pProvider->saveDocument(m_aProp->m_sDocumentId);
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::closeInput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bInputStreamCalled = sal_False;
+
+ if( ! m_bOutputStreamCalled )
+ closeStream();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::closeOutput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_bOutputStreamCalled = sal_False;
+
+ if( ! m_bInputStreamCalled )
+ closeStream();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OOdmaStream::flush()
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ensureOutputStream();
+ m_xOutput->flush();
+}
+// -----------------------------------------------------------------------------
+void OOdmaStream::ensureInputStream() throw( io::IOException )
+{
+ try
+ {
+ if(!m_xInput.is())
+ {
+ m_xInput = m_pContent->openStream();
+ m_xInputSeek = uno::Reference< io::XSeekable>(m_xInput,uno::UNO_QUERY);
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ if(!m_xInput.is())
+ throw io::IOException();
+}
+// -----------------------------------------------------------------------------
+void OOdmaStream::ensureOutputStream() throw( io::IOException )
+{
+ try
+ {
+ if(!m_xOutput.is())
+ {
+ ucb::OpenCommandArgument2 aCommand;
+ aCommand.Mode = ucb::OpenMode::DOCUMENT;
+ uno::Reference< io::XActiveDataStreamer > xActiveStreamer = new OActiveDataStreamer();
+ aCommand.Sink = xActiveStreamer;
+ m_pContent->executeCommand(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("open")),uno::makeAny(aCommand));
+ if(xActiveStreamer.is())
+ {
+ uno::Reference< io::XStream> xStream = xActiveStreamer->getStream();
+ if(xStream.is())
+ m_xOutput = xStream->getOutputStream();
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ if(!m_xOutput.is())
+ throw io::IOException();
+ m_xTruncate = uno::Reference< io::XTruncate>(m_xOutput,uno::UNO_QUERY);
+}
+// -----------------------------------------------------------------------------
+// XTruncate
+void SAL_CALL OOdmaStream::truncate( void )
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ if(m_xTruncate.is())
+ m_xTruncate->truncate();
+}
+// -----------------------------------------------------------------------------
+// XSeekable
+void SAL_CALL OOdmaStream::seek(sal_Int64 location )
+ throw( lang::IllegalArgumentException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ ensureInputStream();
+ if(m_xInputSeek.is())
+ m_xInputSeek->seek(location);
+}
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL OOdmaStream::getPosition()
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ ensureInputStream();
+ return m_xInputSeek.is() ? m_xInputSeek->getPosition() : sal_Int64(0);
+}
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL OOdmaStream::getLength()
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ ensureInputStream();
+ return m_xInputSeek.is() ? m_xInputSeek->getLength() : sal_Int64(0);
+}
+// -----------------------------------------------------------------------------
diff --git a/ucb/source/ucp/odma/odma_inputstream.hxx b/ucb/source/ucp/odma/odma_inputstream.hxx
new file mode 100644
index 000000000000..c751b81989b8
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_inputstream.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef ODMA_INPUTSTREAM_HXX
+#define ODMA_INPUTSTREAM_HXX
+
+#include <osl/mutex.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <cppuhelper/implbase5.hxx>
+
+#include "rtl/ref.hxx"
+
+namespace ucbhelper
+{
+ class Content;
+}
+namespace odma
+{
+ typedef ::cppu::WeakImplHelper5< ::com::sun::star::io::XInputStream,
+ ::com::sun::star::io::XStream,
+ ::com::sun::star::io::XTruncate,
+ ::com::sun::star::io::XSeekable,
+ ::com::sun::star::io::XOutputStream> OOdmaStreamBase;
+
+ class ContentProvider;
+ class ContentProperties;
+ class OOdmaStream : public OOdmaStreamBase
+ {
+ ::osl::Mutex m_aMutex;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream> m_xOutput;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XTruncate> m_xTruncate;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream> m_xInput;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable> m_xInputSeek;
+
+ ::rtl::Reference<ContentProperties> m_aProp;
+ ::ucbhelper::Content* m_pContent;
+ ContentProvider* m_pProvider;
+ sal_Bool m_bInputStreamCalled;
+ sal_Bool m_bOutputStreamCalled;
+ sal_Bool m_bModified;
+
+ void ensureInputStream() throw( ::com::sun::star::io::IOException );
+ void ensureOutputStream() throw( ::com::sun::star::io::IOException );
+ void SAL_CALL closeStream() throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+ public:
+ OOdmaStream(::ucbhelper::Content* _pContent,
+ ContentProvider* _pProvider,
+ const ::rtl::Reference<ContentProperties>& _rProp);
+ virtual ~OOdmaStream();
+ // com::sun::star::io::XInputStream
+ virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL available( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL closeInput( )
+ throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::io::XStream
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw( com::sun::star::uno::RuntimeException );
+
+ // com::sun::star::io::XOutputStream
+ void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ void SAL_CALL flush()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+ void SAL_CALL closeOutput()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ // XTruncate
+ virtual void SAL_CALL truncate( void )
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ // XSeekable
+ void SAL_CALL seek(sal_Int64 location )
+ throw( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Int64 SAL_CALL getPosition()
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ sal_Int64 SAL_CALL getLength()
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ };
+}
+#endif // ODMA_INPUTSTREAM_HXX
diff --git a/ucb/source/ucp/odma/odma_lib.cxx b/ucb/source/ucp/odma/odma_lib.cxx
new file mode 100644
index 000000000000..774bcf5f6323
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_lib.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+//#ifndef _OSL_PROCESS_H_
+//#include <osl/process.h>
+//#endif
+#include <osl/module.h>
+#include <rtl/ustring.hxx>
+#include "odma_lib.hxx"
+
+
+namespace odma
+{
+
+ TODMRegisterApp pODMRegisterApp;
+ TODMUnRegisterApp pODMUnRegisterApp;
+ TODMSelectDoc pODMSelectDoc;
+ TODMOpenDoc pODMOpenDoc;
+ TODMSaveDoc pODMSaveDoc;
+ TODMCloseDoc pODMCloseDoc;
+ TODMNewDoc pODMNewDoc;
+ TODMSaveAs pODMSaveAs;
+ TODMActivate pODMActivate;
+ TODMGetDocInfo pODMGetDocInfo;
+ TODMSetDocInfo pODMSetDocInfo;
+ TODMGetDMSInfo pODMGetDMSInfo;
+ TODMGetDMSCount pODMGetDMSCount;
+ TODMGetDMSList pODMGetDMSList;
+ TODMGetDMS pODMGetDMS;
+ TODMSetDMS pODMSetDMS;
+ TODMQueryExecute pODMQueryExecute;
+ TODMQueryGetResults pODMQueryGetResults;
+ TODMQueryClose pODMQueryClose;
+ TODMCloseDocEx pODMCloseDocEx;
+ TODMSaveAsEx pODMSaveAsEx;
+ TODMSaveDocEx pODMSaveDocEx;
+ TODMSelectDocEx pODMSelectDocEx;
+ TODMQueryCapability pODMQueryCapability;
+ TODMSetDocEvent pODMSetDocEvent;
+ TODMGetAlternateContent pODMGetAlternateContent;
+ TODMSetAlternateContent pODMSetAlternateContent;
+ TODMGetDocRelation pODMGetDocRelation;
+ TODMSetDocRelation pODMSetDocRelation;
+
+ sal_Bool LoadFunctions(oslModule _pODMA);
+
+ sal_Bool LoadLibrary()
+ {
+ static sal_Bool bLoaded = sal_False;
+ static oslModule pODMA = NULL;
+
+ if (bLoaded)
+ return sal_True;
+ ::rtl::OUString sPath;
+ #ifdef WIN
+ sPath = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMA.DLL"));
+
+ #endif
+ #ifdef WNT
+ sPath = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMA32.DLL"));
+ #endif
+ #ifdef UNX
+ sPath = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("libodma.so"));
+ #endif
+
+ pODMA = osl_loadModule( sPath.pData,SAL_LOADMODULE_NOW );
+ if( !pODMA)
+ return sal_False;
+
+ return bLoaded = LoadFunctions(pODMA);
+ }
+ // -------------------------------------------------------------------------
+
+ sal_Bool LoadFunctions(oslModule pODMA)
+ {
+ if ( ( pODMRegisterApp = (TODMRegisterApp)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMRegisterApp")).pData)) == NULL ) return sal_False;
+ if ( ( pODMUnRegisterApp = (TODMUnRegisterApp)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMUnRegisterApp")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSelectDoc = (TODMSelectDoc)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSelectDoc")).pData)) == NULL ) return sal_False;
+ if ( ( pODMOpenDoc = (TODMOpenDoc)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMOpenDoc")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSaveDoc = (TODMSaveDoc)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSaveDoc")).pData)) == NULL ) return sal_False;
+ if ( ( pODMCloseDoc = (TODMCloseDoc)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMCloseDoc")).pData)) == NULL ) return sal_False;
+ if ( ( pODMNewDoc = (TODMNewDoc)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMNewDoc")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSaveAs = (TODMSaveAs)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSaveAs")).pData)) == NULL ) return sal_False;
+ if ( ( pODMActivate = (TODMActivate)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMActivate")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDocInfo = (TODMGetDocInfo)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDocInfo")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSetDocInfo = (TODMSetDocInfo)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSetDocInfo")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDMSInfo = (TODMGetDMSInfo)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDMSInfo")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDMSCount = (TODMGetDMSCount)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDMSCount")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDMSList = (TODMGetDMSList)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDMSList")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDMS = (TODMGetDMS)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDMS")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSetDMS = (TODMSetDMS)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSetDMS")).pData)) == NULL ) return sal_False;
+ if ( ( pODMQueryExecute = (TODMQueryExecute)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMQueryExecute")).pData)) == NULL ) return sal_False;
+ if ( ( pODMQueryGetResults = (TODMQueryGetResults)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMQueryGetResults")).pData)) == NULL ) return sal_False;
+ if ( ( pODMQueryClose = (TODMQueryClose)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMQueryClose")).pData)) == NULL ) return sal_False;
+ if ( ( pODMCloseDocEx = (TODMCloseDocEx)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMCloseDocEx")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSaveAsEx = (TODMSaveAsEx)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSaveAsEx")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSaveDocEx = (TODMSaveDocEx)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSaveDocEx")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSelectDocEx = (TODMSelectDocEx)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSelectDocEx")).pData)) == NULL ) return sal_False;
+ if ( ( pODMQueryCapability = (TODMQueryCapability)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMQueryCapability")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSetDocEvent = (TODMSetDocEvent)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSetDocEvent")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetAlternateContent = (TODMGetAlternateContent)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetAlternateContent")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSetAlternateContent = (TODMSetAlternateContent)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSetAlternateContent")).pData)) == NULL ) return sal_False;
+ if ( ( pODMGetDocRelation = (TODMGetDocRelation)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMGetDocRelation")).pData)) == NULL ) return sal_False;
+ if ( ( pODMSetDocRelation = (TODMSetDocRelation)osl_getSymbol(pODMA,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ODMSetDocRelation")).pData)) == NULL ) return sal_False;
+ return sal_True;
+ }
+}
diff --git a/ucb/source/ucp/odma/odma_lib.hxx b/ucb/source/ucp/odma/odma_lib.hxx
new file mode 100644
index 000000000000..f4229572dbab
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_lib.hxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef ODMA_LIB_HXX
+#define ODMA_LIB_HXX
+
+typedef void *LPVOID;
+typedef char *LPSTR,
+ *PSTR;
+typedef const char *LPCSTR;
+typedef unsigned long DWORD;
+typedef unsigned short WORD;
+typedef unsigned short *LPWORD;
+typedef DWORD *LPDWORD;
+
+#define WINAPI __stdcall
+#define FAR
+
+#include "odma.h"
+
+namespace odma
+{
+ typedef ODMSTATUS (WINAPI *TODMRegisterApp) ( ODMHANDLE FAR *pOdmHandle,
+ WORD version,
+ LPSTR lpszAppId,
+ DWORD dwEnvData,
+ LPVOID pReserved);
+
+ typedef void (WINAPI *TODMUnRegisterApp)(ODMHANDLE odmHandle);
+
+
+ typedef ODMSTATUS (WINAPI *TODMSelectDoc)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags);
+
+
+ typedef ODMSTATUS (WINAPI *TODMOpenDoc)( ODMHANDLE odmHandle,
+ DWORD flags,
+ LPSTR lpszDocId,
+ LPSTR lpszDocLocation);
+
+ typedef ODMSTATUS (WINAPI *TODMSaveDoc)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPSTR lpszNewDocId);
+
+ typedef ODMSTATUS (WINAPI *TODMCloseDoc)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ DWORD activeTime,
+ DWORD pagesPrinted,
+ LPVOID sessionData,
+ WORD dataLen);
+
+ typedef ODMSTATUS (WINAPI *TODMNewDoc)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ DWORD dwFlags,
+ LPSTR lpszFormat,
+ LPSTR lpszDocLocation);
+
+ typedef ODMSTATUS (WINAPI *TODMSaveAs)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPSTR lpszNewDocId,
+ LPSTR lpszFormat,
+ ODMSAVEASCALLBACK pcbCallBack,
+ LPVOID pInstanceData);
+
+ typedef ODMSTATUS (WINAPI *TODMActivate)( ODMHANDLE odmHandle,
+ WORD action,
+ LPSTR lpszDocId);
+
+ typedef ODMSTATUS (WINAPI *TODMGetDocInfo)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ WORD item,
+ LPSTR lpszData,
+ WORD dataLen);
+
+ typedef ODMSTATUS (WINAPI *TODMSetDocInfo)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ WORD item,
+ LPSTR lpszData);
+
+ typedef ODMSTATUS (WINAPI *TODMGetDMSInfo)( ODMHANDLE odmHandle,
+ LPSTR lpszDmsId,
+ LPWORD pwVerNo,
+ LPDWORD pdwExtensions);
+
+ /* Query Enhancements */
+ typedef WORD (WINAPI *TODMGetDMSCount)();
+
+ typedef WORD (WINAPI *TODMGetDMSList)( LPSTR buffer,
+ WORD buffer_size );
+
+ typedef ODMSTATUS (WINAPI *TODMGetDMS)( LPCSTR lpszAppId,
+ LPSTR lpszDMSId );
+
+ typedef ODMSTATUS (WINAPI *TODMSetDMS)( LPCSTR lpszAppId,
+ LPCSTR lpszDMSId );
+
+ typedef ODMSTATUS (WINAPI *TODMQueryExecute)( ODMHANDLE odmHandle,
+ LPCSTR lpszQuery,
+ DWORD flags,
+ LPCSTR lpszDMSList,
+ LPSTR queryId );
+
+ typedef ODMSTATUS (WINAPI *TODMQueryGetResults)(ODMHANDLE odmHandle,
+ LPCSTR queryId,
+ LPSTR lpszDocId,
+ LPSTR lpszDocName,
+ WORD docNameLen,
+ WORD *docCount );
+
+ typedef ODMSTATUS (WINAPI *TODMQueryClose)( ODMHANDLE odmHandle,
+ LPCSTR queryId );
+
+ /* ODMA 2.0 Enhancements */
+ typedef ODMSTATUS (WINAPI *TODMCloseDocEx)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags,
+ DWORD activeTime,
+ DWORD pagesPrinted,
+ LPVOID sessionData,
+ WORD dataLen);
+
+ typedef ODMSTATUS (WINAPI *TODMSaveAsEx)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPSTR lpszNewDocId,
+ LPSTR lpszFormat,
+ ODMSAVEASCALLBACK pcbCallBack,
+ LPVOID pInstanceData,
+ LPDWORD pdwFlags);
+
+ typedef ODMSTATUS (WINAPI *TODMSaveDocEx)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPSTR lpszNewDocId,
+ LPDWORD pdwFlags);
+
+ typedef ODMSTATUS (WINAPI *TODMSelectDocEx)( ODMHANDLE odmHandle,
+ LPSTR lpszDocIds,
+ LPWORD pwDocIdsLen,
+ LPWORD pwDocCount,
+ LPDWORD pdwFlags,
+ LPSTR lpszFormatFilter);
+
+ typedef ODMSTATUS (WINAPI *TODMQueryCapability)(ODMHANDLE odmHandle,
+ LPCSTR lpszDmsId,
+ DWORD function,
+ DWORD item,
+ DWORD flags);
+
+ typedef ODMSTATUS (WINAPI *TODMSetDocEvent)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ DWORD flags,
+ DWORD event,
+ LPVOID lpData,
+ DWORD dwDataLen,
+ LPSTR lpszComment);
+
+ typedef ODMSTATUS (WINAPI *TODMGetAlternateContent)(ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags,
+ LPSTR lpszFormat,
+ LPSTR lpszDocLocation);
+
+ typedef ODMSTATUS (WINAPI *TODMSetAlternateContent)(ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags,
+ LPSTR lpszFormat,
+ LPSTR lpszDocLocation);
+
+ typedef ODMSTATUS (WINAPI *TODMGetDocRelation)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags,
+ LPSTR lpszLinkedId,
+ LPSTR lpszFormat,
+ LPSTR lpszPreviousId);
+
+ typedef ODMSTATUS (WINAPI *TODMSetDocRelation)( ODMHANDLE odmHandle,
+ LPSTR lpszDocId,
+ LPDWORD pdwFlags,
+ LPSTR lpszLinkedId,
+ LPSTR lpszFormat,
+ LPSTR lpszPreviousId);
+
+ // now we define some macros
+
+ #define NODMRegisterApp(a,b,c,d,e) (*(pODMRegisterApp))(a,b,c,d,e)
+ #define NODMUnRegisterApp(a) (*(pODMUnRegisterApp))(a)
+ #define NODMSelectDoc(a,b,c) (*(pODMSelectDoc))(a,b,c)
+ #define NODMOpenDoc(a,b,c,d) (*(pODMOpenDoc))(a,b,c,d)
+ #define NODMSaveDoc(a,b,c) (*(pODMSaveDoc))(a,b,c)
+ #define NODMCloseDoc(a,b,c,d,e,f) (*(pODMCloseDoc))(a,b,c,d,e,f)
+ #define NODMNewDoc(a,b,c,d,e) (*(pODMNewDoc))(a,b,c,d,e)
+ #define NODMSaveAs(a,b,c,d,e,f) (*(pODMSaveAs))(a,b,c,d,e,f)
+ #define NODMActivate(a,b,c) (*(pODMActivate))(a,b,c)
+ #define NODMGetDocInfo(a,b,c,d,e) (*(pODMGetDocInfo))(a,b,c,d,e)
+ #define NODMSetDocInfo(a,b,c,d) (*(pODMSetDocInfo))(a,b,c,d)
+ #define NODMGetDMSInfo(a,b,c,d) (*(pODMGetDMSInfo))(a,b,c,d)
+ #define NODMGetDMSCount() (*(pODMGetDMSCount))()
+ #define NODMGetDMSList(a,b) (*(pODMGetDMSList))(a,b)
+ #define NODMGetDMS(a,b) (*(pODMGetDMS))(a,b)
+ #define NODMSetDMS(a,b) (*(pODMSetDMS))(a,b)
+ #define NODMQueryExecute(a,b,c,d,e) (*(pODMQueryExecute))(a,b,c,d,e)
+ #define NODMQueryGetResults(a,b,c,d,e,f) (*(pODMQueryGetResults))(a,b,c,d,e,f)
+ #define NODMQueryClose(a,b) (*(pODMQueryClose))(a,b)
+ #define NODMCloseDocEx(a,b,c,d,e,f,g) (*(pODMCloseDocEx))(a,b,c,d,e,f,g)
+ #define NODMSaveAsEx(a,b,c,d,e,f,g) (*(pODMSaveAsEx))(a,b,c,d,e,f,g)
+ #define NODMSaveDocEx(a,b,c,d) (*(pODMSaveDocEx))(a,b,c,d)
+ #define NODMSelectDocEx(a,b,c,d,e,f) (*(pODMSelectDocEx))(a,b,c,d,e,f)
+ #define NODMQueryCapability(a,b,c,d,e) (*(pODMQueryCapability))(a,b,c,d,e)
+ #define NODMSetDocEvent(a,b,c,d,e,f,g) (*(pODMSetDocEvent))(a,b,c,d,e,f,g)
+ #define NODMGetAlternateContent(a,b,c,d,e) (*(pODMGetAlternateContent))(a,b,c,d,e)
+ #define NODMSetAlternateContent(a,b,c,d,e) (*(pODMSetAlternateContent))(a,b,c,d,e)
+ #define NODMGetDocRelation(a,b,c,d,e,f) (*(pODMGetDocRelation))(a,b,c,d,e,f)
+ #define NODMSetDocRelation(a,b,c,d,e,f) (*(pODMSetDocRelation))(a,b,c,d,e,f)
+
+ sal_Bool LoadLibrary();
+
+ extern TODMRegisterApp pODMRegisterApp;
+ extern TODMUnRegisterApp pODMUnRegisterApp;
+ extern TODMSelectDoc pODMSelectDoc;
+ extern TODMOpenDoc pODMOpenDoc;
+ extern TODMSaveDoc pODMSaveDoc;
+ extern TODMCloseDoc pODMCloseDoc;
+ extern TODMNewDoc pODMNewDoc;
+ extern TODMSaveAs pODMSaveAs;
+ extern TODMActivate pODMActivate;
+ extern TODMGetDocInfo pODMGetDocInfo;
+ extern TODMSetDocInfo pODMSetDocInfo;
+ extern TODMGetDMSInfo pODMGetDMSInfo;
+ extern TODMGetDMSCount pODMGetDMSCount;
+ extern TODMGetDMSList pODMGetDMSList;
+ extern TODMGetDMS pODMGetDMS;
+ extern TODMSetDMS pODMSetDMS;
+ extern TODMQueryExecute pODMQueryExecute;
+ extern TODMQueryGetResults pODMQueryGetResults;
+ extern TODMQueryClose pODMQueryClose;
+ extern TODMCloseDocEx pODMCloseDocEx;
+ extern TODMSaveAsEx pODMSaveAsEx;
+ extern TODMSaveDocEx pODMSaveDocEx;
+ extern TODMSelectDocEx pODMSelectDocEx;
+ extern TODMQueryCapability pODMQueryCapability;
+ extern TODMSetDocEvent pODMSetDocEvent;
+ extern TODMGetAlternateContent pODMGetAlternateContent;
+ extern TODMSetAlternateContent pODMSetAlternateContent;
+ extern TODMGetDocRelation pODMGetDocRelation;
+ extern TODMSetDocRelation pODMSetDocRelation;
+
+}
+
+#endif // ODMA_LIB_HXX
diff --git a/ucb/source/ucp/odma/odma_main.cxx b/ucb/source/ucp/odma/odma_main.cxx
new file mode 100644
index 000000000000..3d7a22e907dd
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_main.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <osl/process.h>
+#include "odma_provider.hxx"
+
+#ifdef WNT
+#define SOFFICE "soffice.exe"
+#else
+#define SOFFICE "soffice"
+#endif
+
+/** our main program to convert ODMAIDs to ODMA URLs
+*/
+
+#if (defined UNX) || (defined OS2)
+void main( int argc, char * argv[] )
+#else
+void _cdecl main( int argc, char * argv[] )
+#endif
+{
+ static ::rtl::OUString sProcess(RTL_CONSTASCII_USTRINGPARAM(SOFFICE));
+ if(argc > 1)
+ {
+ ::rtl::OUString* pArguments = new ::rtl::OUString[argc-1];
+ for(int i = 0; i < argc-1; ++i)
+ {
+ pArguments[i] = ::rtl::OUString::createFromAscii(argv[i+1]);
+ if( pArguments[i].matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(ODMA_URL_ODMAID)))
+ {
+ ::rtl::OUString sArgument
+ = ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ODMA_URL_SCHEME ODMA_URL_SHORT "/"));
+ sArgument += pArguments[i];
+ pArguments[i] = sArgument;
+ }
+ }
+
+ rtl_uString ** ustrArgumentList = new rtl_uString * [argc-1];
+ for (int i = 0; i < argc-1; i++)
+ ustrArgumentList[i] = pArguments[i].pData;
+
+ oslProcess aProcess;
+
+ if ( osl_Process_E_None == osl_executeProcess(
+ sProcess.pData,
+ ustrArgumentList,
+ argc-1,
+ osl_Process_DETACHED,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &aProcess )
+ )
+ osl_freeProcessHandle( aProcess );
+
+ delete [] ustrArgumentList;
+ delete [] pArguments;
+ }
+}
+
diff --git a/ucb/source/ucp/odma/odma_provider.cxx b/ucb/source/ucp/odma/odma_provider.cxx
new file mode 100644
index 000000000000..6c4df4c40b88
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_provider.cxx
@@ -0,0 +1,599 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <ucbhelper/contentidentifier.hxx>
+#include "odma_provider.hxx"
+#include "odma_content.hxx"
+#include "odma_contentprops.hxx"
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <rtl/uri.hxx>
+#include <algorithm>
+#include <osl/file.hxx>
+
+using namespace com::sun::star;
+using namespace odma;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+ODMHANDLE ContentProvider::m_aOdmHandle = NULL;
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rSMgr )
+{
+
+}
+
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+ ContentsMap::iterator aIter = m_aContents.begin();
+ for (;aIter != m_aContents.end() ;++aIter )
+ {
+ if(aIter->second->m_bIsOpen)
+ closeDocument(aIter->first);
+ }
+ if(m_aOdmHandle)
+ {
+ NODMUnRegisterApp(m_aOdmHandle);
+ m_aOdmHandle = NULL;
+ }
+}
+// -----------------------------------------------------------------------------
+ODMHANDLE ContentProvider::getHandle()
+{
+ if(!m_aOdmHandle)
+ {
+ ODMSTATUS odm = NODMRegisterApp(&m_aOdmHandle,ODM_API_VERSION,ODMA_ODMA_REGNAME,NULL,NULL);
+ switch(odm)
+ {
+ case ODM_SUCCESS:
+ break;
+ case ODM_E_NODMS:
+ break;
+ case ODM_E_CANTINIT:
+ break;
+ case ODM_E_VERSION:
+ break;
+ default:
+ break;
+ }
+ }
+ return m_aOdmHandle;
+}
+// -----------------------------------------------------------------------------
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// @@@ Add own interfaces.
+XINTERFACE_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+// @@@ Add own interfaces.
+XTYPEPROVIDER_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// @@@ Adjust implementation name. Keep the prefix "com.sun.star.comp."!
+// @@@ Adjust service name.
+XSERVICEINFO_IMPL_1( ContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.odma.ContentProvider" ),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_PROVIDER_SERVICE_NAME) ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ // Check URL scheme...
+ if(!getHandle())
+ throw ucb::IllegalIdentifierException();
+
+ rtl::OUString aScheme( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(ODMA_URL_SCHEME) ) );
+ sal_Int32 nIndex = 0;
+ rtl::OUString sOdma = aScheme.getToken(3,'.',nIndex);
+ rtl::OUString sCanonicURL = Identifier->getContentIdentifier();
+ // check if url starts with odma
+ if ( !(Identifier->getContentProviderScheme().equalsIgnoreAsciiCase( aScheme ) ||
+ Identifier->getContentProviderScheme().equalsIgnoreAsciiCase( sOdma )) )
+ throw ucb::IllegalIdentifierException();
+
+ if(!( sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME_SHORT ODMA_URL_SHORT)) ||
+ sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT))))
+ throw ucb::IllegalIdentifierException();
+
+ // @@@ Further id checks may go here...
+#if 0
+ if ( id-check-failes )
+ throw ucb::IllegalIdentifierException();
+#endif
+
+ // @@@ Id normalization may go here...
+#if 0
+ // Normalize URL and create new Id.
+ rtl::OUString aCanonicURL = ( Identifier->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xCanonicId
+ = new ::ucb::ContentIdentifier( m_xSMgr, aCanonicURL );
+#else
+ uno::Reference< ucb::XContentIdentifier > xCanonicId = Identifier;
+#endif
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xCanonicId ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ // @@@ Decision, which content implementation to instanciate may be
+ // made here ( in case you have different content classes ).
+
+ // Create a new content.
+
+ sCanonicURL = convertURL(sCanonicURL);
+
+ ::rtl::Reference<ContentProperties> aProp;
+ // first check if we got an ODMA ID from outside
+ if( sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_ODMAID)))
+ {// we get an orignal ODMA id so we have to look for the name
+ ::rtl::OString sDocId = ::rtl::OUStringToOString(sCanonicURL,RTL_TEXTENCODING_MS_1252);
+ sal_Char* lpszDocName = new sal_Char[ODM_NAME_MAX];
+
+ ODMSTATUS odm = NODMGetDocInfo( getHandle(),
+ const_cast<sal_Char*>(sDocId.getStr()),
+ ODM_NAME,
+ lpszDocName,
+ ODM_NAME_MAX
+ );
+ if(odm == ODM_SUCCESS)
+ {
+ aProp = new ContentProperties();
+ aProp->m_sDocumentName = ::rtl::OStringToOUString(rtl::OString(lpszDocName),RTL_TEXTENCODING_ASCII_US);
+ aProp->m_sDocumentId = sDocId;
+ aProp->m_sContentType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
+ append(aProp);
+ }
+ delete [] lpszDocName;
+ }
+ else // we got an already fetched name here so look for it
+ {
+ // we have a valid document name
+ aProp = getContentPropertyWithTitle(sCanonicURL);
+ if(!aProp.is())
+ aProp = getContentPropertyWithSavedAsName(sCanonicURL);
+ if(!aProp.is())
+ {
+ if(sCanonicURL.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("/")))
+ { // found only the scheme
+ aProp = new ContentProperties();
+ aProp->m_sDocumentId = "/";
+ aProp->m_sTitle = sCanonicURL;
+ aProp->m_bIsFolder = sal_True;
+ aProp->m_bIsDocument = !aProp->m_bIsFolder;
+ m_aContents.insert(ContentsMap::value_type(aProp->m_sDocumentId,aProp));
+ }
+ else
+ aProp = queryContentProperty(sCanonicURL);
+ }
+ }
+ if(!aProp.is())
+ throw ucb::IllegalIdentifierException();
+
+ xContent = new Content( m_xSMgr, this, xCanonicId ,aProp);
+ registerNewContent( xContent );
+
+ if ( !xContent->getIdentifier().is() )
+ throw ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+// -----------------------------------------------------------------------------
+void ContentProvider::closeDocument(const ::rtl::OString& _sDocumentId)
+{
+ ContentsMap::iterator aIter = m_aContents.find(_sDocumentId);
+ if(aIter != m_aContents.end())
+ {
+ DWORD dwFlags = ODM_SILENT;
+ ODMSTATUS odm = NODMCloseDocEx( ContentProvider::getHandle(),
+ const_cast<sal_Char*>(_sDocumentId.getStr()),
+ &dwFlags,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ NULL,
+ 0);
+ OSL_ENSURE(odm == ODM_SUCCESS,"Error while closing a document!");
+ if(odm == ODM_SUCCESS)
+ aIter->second->m_bIsOpen = sal_False;
+ }
+}
+// -----------------------------------------------------------------------------
+void ContentProvider::saveDocument(const ::rtl::OString& _sDocumentId)
+{
+ ContentsMap::iterator aIter = m_aContents.find(_sDocumentId);
+ if(aIter != m_aContents.end())
+ {
+ sal_Char* lpszDocId = new sal_Char[ODM_DOCID_MAX];
+ DWORD dwFlags = ODM_SILENT;
+ ODMSTATUS odm = NODMSaveDocEx(getHandle(),
+ const_cast<sal_Char*>(_sDocumentId.getStr()),
+ lpszDocId,
+ &dwFlags);
+ OSL_ENSURE(odm == ODM_SUCCESS,"Could not save document!");
+ if(odm != ODM_SUCCESS)
+ {
+ delete [] lpszDocId;
+ throw uno::Exception();
+ }
+ aIter->second->m_sDocumentId = rtl::OString(lpszDocId);
+ delete [] lpszDocId;
+ }
+}
+// -----------------------------------------------------------------------------
+util::Date toDate(const ::rtl::OString& _sSQLString)
+{
+ sal_uInt16 nYear = 0,
+ nMonth = 0,
+ nDay = 0;
+ nYear = (sal_uInt16)_sSQLString.copy(0,4).toInt32();
+ nMonth = (sal_uInt16)_sSQLString.copy(4,2).toInt32();
+ nDay = (sal_uInt16)_sSQLString.copy(6,2).toInt32();
+
+ return util::Date(nDay,nMonth,nYear);
+}
+//-----------------------------------------------------------------------------
+util::Time toTime(const ::rtl::OString& _sSQLString)
+{
+ sal_uInt16 nHour = 0,
+ nMinute = 0,
+ nSecond = 0;
+ nHour = (sal_uInt16)_sSQLString.copy(8,2).toInt32();
+ nMinute = (sal_uInt16)_sSQLString.copy(10,2).toInt32();
+ nSecond = (sal_uInt16)_sSQLString.copy(12,2).toInt32();
+
+ return util::Time(0,nHour,nMinute,nSecond);
+}
+//-----------------------------------------------------------------------------
+util::DateTime toDateTime(const ::rtl::OString& _sSQLString)
+{
+ util::Date aDate = toDate(_sSQLString);
+ util::Time aTime = toTime(_sSQLString);
+
+ return util::DateTime(0,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year);
+}
+// -----------------------------------------------------------------------------
+void ContentProvider::fillDocumentProperties(const ::rtl::Reference<ContentProperties>& _rProp)
+{
+ // read some properties from the DMS
+ sal_Char* lpszDocInfo = new sal_Char[ODM_DOCID_MAX];
+ sal_Char* pDocId = const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr());
+
+ // read the create date of the document
+ ODMSTATUS odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_CREATEDDATE,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_aDateCreated = toDateTime(::rtl::OString(lpszDocInfo));
+
+ // read the modified date of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_MODIFYDATE,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_aDateModified = toDateTime(::rtl::OString(lpszDocInfo));
+
+ // read the title of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_TITLETEXT,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_sTitle = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
+
+ // read the name of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_NAME,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_sDocumentName = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
+
+ // read the author of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_AUTHOR,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_sAuthor = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
+
+ // read the subject of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_SUBJECT,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_sSubject = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
+
+ // read the keywords of the document
+ odm = NODMGetDocInfo( getHandle(),
+ pDocId,
+ ODM_KEYWORDS,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if(odm == ODM_SUCCESS)
+ _rProp->m_sKeywords = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
+
+/*
+ odm = NODMGetDocInfo( getHandle(),
+ const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()),
+ ODM_URL,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+*/
+ delete [] lpszDocInfo;
+}
+// -----------------------------------------------------------------------------
+void ContentProvider::append(const ::rtl::Reference<ContentProperties>& _rProp)
+{
+ // now fill some more properties
+ fillDocumentProperties(_rProp);
+ // and append them
+ m_aContents.insert(ContentsMap::value_type(_rProp->m_sDocumentId,_rProp));
+}
+// -----------------------------------------------------------------------------
+::rtl::Reference<ContentProperties> ContentProvider::queryContentProperty(const ::rtl::OUString& _sDocumentName)
+{
+ ::rtl::Reference<ContentProperties> aReturn;
+ sal_Char* lpszDMSList = new sal_Char[ODM_DMSID_MAX];
+
+ ODMSTATUS odm = NODMGetDMS(ODMA_ODMA_REGNAME, lpszDMSList);
+ if(odm == ODM_SUCCESS)
+ {
+ sal_Char* pQueryId = new sal_Char[ODM_QUERYID_MAX];
+ lpszDMSList[strlen(lpszDMSList)+1] = '\0';
+
+ ::rtl::OString sTitleText(::rtl::OUStringToOString(_sDocumentName,RTL_TEXTENCODING_ASCII_US));
+ ::rtl::OString sQuery("SELECT ODM_DOCID, ODM_NAME WHERE ODM_TITLETEXT = '");
+ sQuery += sTitleText;
+ sQuery += "'";
+
+ DWORD dwFlags = ODM_SPECIFIC;
+ odm = NODMQueryExecute(getHandle(), sQuery,dwFlags, lpszDMSList, pQueryId );
+ if(odm == ODM_SUCCESS)
+ {
+ sal_uInt16 nCount = 10;
+ sal_uInt16 nMaxCount = 10;
+ sal_Char* lpszDocId = new sal_Char[ODM_DOCID_MAX * nMaxCount];
+ sal_Char* lpszDocName = new sal_Char[ODM_NAME_MAX * nMaxCount];
+ sal_Char* lpszDocInfo = new sal_Char[ODM_DOCID_MAX];
+
+ ::rtl::OUString sContentType(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
+ do
+ {
+ if(nCount >= nMaxCount)
+ {
+ // get the result
+ nCount = nMaxCount;
+ odm = NODMQueryGetResults(getHandle(), pQueryId,lpszDocId, lpszDocName, ODM_NAME_MAX, (WORD*)&nCount);
+ }
+ if(odm == ODM_SUCCESS)
+ for(sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ odm = NODMGetDocInfo( getHandle(),
+ &lpszDocId[ODM_DOCID_MAX*i],
+ ODM_TITLETEXT,
+ lpszDocInfo,
+ ODM_DOCID_MAX);
+ if( odm == ODM_SUCCESS && sTitleText == ::rtl::OString(lpszDocInfo))
+ {
+ aReturn = new ContentProperties();
+ aReturn->m_sDocumentName = ::rtl::OStringToOUString(rtl::OString(&lpszDocName[ODM_NAME_MAX*i]),RTL_TEXTENCODING_ASCII_US);
+ aReturn->m_sDocumentId = ::rtl::OString(&lpszDocId[ODM_DOCID_MAX*i]);
+ aReturn->m_sContentType = sContentType;
+ append(aReturn);
+ nCount = 0; // break condition from outer loop
+ break;
+ }
+ }
+ }
+ while(nCount > nMaxCount);
+
+ delete [] lpszDocInfo;
+ delete [] lpszDocId;
+ delete [] lpszDocName;
+ }
+
+ // now close the query
+ odm = NODMQueryClose(ContentProvider::getHandle(), pQueryId);
+ delete [] pQueryId;
+ }
+ delete [] lpszDMSList;
+
+
+ return aReturn;
+}
+// -----------------------------------------------------------------------------
+::rtl::Reference<ContentProperties> ContentProvider::getContentProperty(const ::rtl::OUString& _sName,
+ const ContentPropertiesMemberFunctor& _aFunctor) const
+{
+ ::rtl::Reference<ContentProperties> aReturn;
+ ContentsMap::const_iterator aFind = ::std::find_if( m_aContents.begin(),
+ m_aContents.end(),
+ ::std::compose1(
+ ::std::bind2nd(_aFunctor,_sName),
+ ::std::select2nd<ContentsMap::value_type>()
+ )
+ );
+ if(aFind != m_aContents.end())
+ aReturn = aFind->second;
+ return aReturn;
+}
+// -----------------------------------------------------------------------------
+::rtl::Reference<ContentProperties> ContentProvider::getContentPropertyWithSavedAsName(const ::rtl::OUString& _sSaveAsName) const
+{
+ ContentPropertiesMemberFunctor aFunc(::std::mem_fun(&ContentProperties::getSavedAsName));
+ return getContentProperty(_sSaveAsName,aFunc);
+}
+// -----------------------------------------------------------------------------
+::rtl::Reference<ContentProperties> ContentProvider::getContentPropertyWithTitle(const ::rtl::OUString& _sTitle) const
+{
+ ContentPropertiesMemberFunctor aFunc(::std::mem_fun(&ContentProperties::getTitle));
+ return getContentProperty(_sTitle,aFunc);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ContentProvider::openDoc(const ::rtl::Reference<ContentProperties>& _rProp) throw (uno::Exception)
+{
+ OSL_ENSURE(_rProp.is(),"No valid content properties!");
+ if(!_rProp->m_bIsOpen)
+ {
+ sal_Char *pFileName = new sal_Char[ODM_FILENAME_MAX];
+
+ DWORD dwFlag = ODM_MODIFYMODE | ODM_SILENT;
+ ODMSTATUS odm = NODMOpenDoc(getHandle(), dwFlag, const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()), pFileName);
+ switch(odm)
+ {
+ case ODM_E_INUSE:
+ dwFlag = ODM_VIEWMODE;
+ if( NODMOpenDoc(getHandle(), dwFlag, const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()), pFileName) != ODM_SUCCESS)
+ break;
+ // else run through
+ case ODM_SUCCESS:
+ ::osl::FileBase::getFileURLFromSystemPath(::rtl::OStringToOUString(rtl::OString(pFileName),RTL_TEXTENCODING_ASCII_US)
+ ,_rProp->m_sFileURL);
+ _rProp->m_bIsOpen = sal_True;
+ break;
+ default:
+ delete [] pFileName;
+ throw uno::Exception(); // TODO give a more precise error message here
+ }
+
+ delete [] pFileName;
+ }
+ return _rProp->m_sFileURL;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ContentProvider::convertURL(const ::rtl::OUString& _sCanonicURL)
+{
+ sal_Int32 nPos = 0;
+ // check if url starts with odma
+ if(_sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME_SHORT ODMA_URL_SHORT)))
+ { // URL starts with odma:// so we have to remove this
+ nPos = ODMA_URL_SHORT_LGTH;
+ }
+ else if(_sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT)))
+ { // URL starts with vnd.sun.star.odma:/// so we have to remove this
+ nPos = ODMA_URL_LGTH;
+ }
+
+ ::rtl::OUString sCanonicURL = _sCanonicURL;
+ // now check what formats we allow
+ if(nPos == _sCanonicURL.getLength()) // only ask for root entry
+ sCanonicURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ if(nPos < sCanonicURL.getLength())
+ {
+ sCanonicURL = sCanonicURL.copy(nPos);
+ sCanonicURL = rtl::Uri::decode(sCanonicURL,rtl_UriDecodeWithCharset,RTL_TEXTENCODING_UTF8);
+ }
+ if(sCanonicURL.getLength() > 1 && sCanonicURL.getStr()[0] == sal_Unicode('/'))
+ {
+ sCanonicURL = sCanonicURL.copy(1);
+ if(sCanonicURL.getLength() == 1 && sCanonicURL.getStr()[0] == sal_Unicode('.'))
+ sCanonicURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ }
+ return sCanonicURL;
+}
+// -----------------------------------------------------------------------------
+sal_Bool ContentProvider::deleteDocument(const ::rtl::Reference<ContentProperties>& _rProp)
+{
+ closeDocument(_rProp->m_sDocumentId);
+ ODMSTATUS odm = NODMActivate(ContentProvider::getHandle(),
+ ODM_DELETE,
+ const_cast< sal_Char*>(_rProp->m_sDocumentId.getStr()));
+ if(odm == ODM_SUCCESS)
+ m_aContents.erase(_rProp->m_sDocumentId);
+
+ return odm == ODM_SUCCESS;
+}
+// -----------------------------------------------------------------------------
diff --git a/ucb/source/ucp/odma/odma_provider.hxx b/ucb/source/ucp/odma/odma_provider.hxx
new file mode 100644
index 000000000000..0e861f59b492
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_provider.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef ODMA_PROVIDER_HXX
+#define ODMA_PROVIDER_HXX
+
+#include <ucbhelper/providerhelper.hxx>
+#include "odma_lib.hxx"
+
+#include "rtl/ref.hxx"
+
+#include <map>
+#include "odma_contentprops.hxx"
+
+namespace odma {
+
+//=========================================================================
+
+// UNO service name for the provider. This name will be used by the UCB to
+// create instances of the provider.
+#define ODMA_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.OdmaContentProvider"
+// #define ODMA_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 34
+
+// URL scheme. This is the scheme the provider will be able to create
+// contents for. The UCB will select the provider ( i.e. in order to create
+// contents ) according to this scheme.
+#define ODMA_URL_ODMAID "::ODMA"
+#define ODMA_URL_SCHEME "vnd.sun.star.odma"
+#define ODMA_URL_SCHEME_SHORT "odma"
+#define ODMA_URL_SHORT ":"
+#define ODMA_URL_SHORT_LGTH 5
+#define ODMA_URL_LGTH 18
+#define ODMA_URL_ODMAID_LGTH 6
+
+// UCB Content Type.
+#define ODMA_CONTENT_TYPE "application/" ODMA_URL_SCHEME "-content"
+#define ODMA_ODMA_REGNAME "sodma"
+#define ODM_NAME_MAX 64 // Max length of a name document including
+ // the terminating NULL character.
+
+//=========================================================================
+class ContentProperties;
+class ContentProvider : public ::ucbhelper::ContentProviderImplHelper
+{
+ typedef ::std::map< ::rtl::OString, ::rtl::Reference<ContentProperties> > ContentsMap;
+ ContentsMap m_aContents; // contains all ContentProperties
+ static ODMHANDLE m_aOdmHandle; // the one and only ODMA handle to our DMS
+
+ /** fillDocumentProperties fills the given _rProp with ODMA properties
+ @param _rProp the ContentProperties
+ */
+ void fillDocumentProperties(const ::rtl::Reference<ContentProperties>& _rProp);
+
+ /**
+ */
+ ::rtl::Reference<ContentProperties> getContentProperty(const ::rtl::OUString& _sName,
+ const ContentPropertiesMemberFunctor& _aFunctor) const;
+public:
+ ContentProvider( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+ static ODMHANDLE getHandle();
+
+ /** append add an entry to the internal map
+ @param _rProp the content properties
+ */
+ void append(const ::rtl::Reference<ContentProperties>& _rProp);
+
+ /** closeDocument closes the document
+ @param _sDocumentId the id of the document
+ */
+ void closeDocument(const ::rtl::OString& _sDocumentId);
+
+ /** saveDocument saves the document in DMS
+ @param _sDocumentId the id of the document
+ */
+ void saveDocument(const ::rtl::OString& _sDocumentId);
+
+ /** queryContentProperty query in the DMS for a content which document name is equal to _sDocumentName
+ @param _sDocumentName the document to query for
+
+ @return the content properties for this content or an empty refernce
+ */
+ ::rtl::Reference<ContentProperties> queryContentProperty(const ::rtl::OUString& _sDocumentName);
+
+ /** getContentProperty returns the ContentProperties for the first content with that title
+ @param _sTitle the title of the document
+
+ @return the content properties
+ */
+ ::rtl::Reference<ContentProperties> getContentPropertyWithTitle(const ::rtl::OUString& _sTitle) const;
+
+ /** getContentProperty returns the ContentProperties for the first content with that SavedAsName
+ @param _sSaveAsName the SavedAsName of the document
+
+ @return the content properties
+ */
+ ::rtl::Reference<ContentProperties> getContentPropertyWithSavedAsName(const ::rtl::OUString& _sSaveAsName) const;
+
+ /** openDoc returns the URL for the temporary file for the specific Content and opens it
+ @param _rProp used for check if already open, the member m_sFileURL will be set if is wan't opened yet
+
+ @return the URL of the temporary file
+ */
+ static ::rtl::OUString openDoc(const ::rtl::Reference<ContentProperties>& _rProp) throw (::com::sun::star::uno::Exception);
+
+ /** convertURL converts a normal URL into an ODMA understandable name
+ @param _sCanonicURL the URL from ContentIndentifier
+
+ @return the ODMA name
+ */
+ static ::rtl::OUString convertURL(const ::rtl::OUString& _sCanonicURL);
+
+ /** deleteDocument deletes the document inside the DMS and remove the content properties from inside list
+ @param _rProp the ContentProperties
+
+ @return true when successful
+ */
+ sal_Bool deleteDocument(const ::rtl::Reference<ContentProperties>& _rProp);
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/odma/odma_resultset.cxx b/ucb/source/ucp/odma/odma_resultset.cxx
new file mode 100644
index 000000000000..82e6b271fcd3
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_resultset.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+#include "odma_datasupplier.hxx"
+#include "odma_resultset.hxx"
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+using namespace odma;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const Reference< XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const OpenCommandArgument2& rCommand,
+ const Reference< XCommandEnvironment >& rxEnv )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/odma/odma_resultset.hxx b/ucb/source/ucp/odma/odma_resultset.hxx
new file mode 100644
index 000000000000..77787b1fccda
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_resultset.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef ODMA_RESULTSET_HXX
+#define ODMA_RESULTSET_HXX
+
+#include <ucbhelper/resultsethelper.hxx>
+
+#include "rtl/ref.hxx"
+#include "odma_content.hxx"
+
+namespace odma {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/odma/odma_services.cxx b/ucb/source/ucp/odma/odma_services.cxx
new file mode 100644
index 000000000000..3e4639e25806
--- /dev/null
+++ b/ucb/source/ucp/odma/odma_services.cxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "odma_contentprops.hxx"
+#include "odma_provider.hxx"
+#include "odma_lib.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const OUString & rImplementationName,
+ Sequence< OUString > const & rServiceNames )
+{
+ OUString aKeyName( OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += OUString::createFromAscii( "/UNO/SERVICES" );
+
+ Reference< XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Write info into registry.
+ //////////////////////////////////////////////////////////////////////
+
+ // @@@ Adjust namespace names.
+ writeInfo( pRegistryKey,
+ ::odma::ContentProvider::getImplementationName_Static(),
+ ::odma::ContentProvider::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Create factory, if implementation name matches.
+ //////////////////////////////////////////////////////////////////////
+
+ // @@@ Adjust namespace names.
+ if ( ::odma::ContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ if(::odma::LoadLibrary())
+ xFactory = ::odma::ContentProvider::createServiceFactory( xSMgr );
+ else
+ OSL_ASSERT(!"Could not load library!");
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/odma/ucpodma.xml b/ucb/source/ucp/odma/ucpodma.xml
new file mode 100644
index 000000000000..1ca36334d966
--- /dev/null
+++ b/ucb/source/ucp/odma/ucpodma.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpodma
+ </module-name>
+
+ <component-description>
+ <author>
+ Ocke Janssen
+ </author>
+ <name>
+ com.sun.star.comp.ucb.OdmaContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to contents stored on an document management
+ system (DMS).
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.ODMAContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationAccess
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> external </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XInputStream </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentCreationException </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.PostCommandArgument2 </type>
+ <type> com.sun.star.ucb.RememberAuthentication </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.XCommandEnvironment </type>
+ <type> com.sun.star.ucb.UnsupportedCommandException </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandInfoChangeNotifier </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.util.DateTime </type>
+</module-description>
diff --git a/ucb/source/ucp/package/makefile.mk b/ucb/source/ucp/package/makefile.mk
new file mode 100644
index 000000000000..8c6dcda31829
--- /dev/null
+++ b/ucb/source/ucp/package/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# UCP Version - Increase, if UCP libraray becomes incompatible.
+UCP_VERSION=1
+
+# Name for UCP. Will become part of the library name (See below).
+UCP_NAME=pkg
+
+PRJ=..$/..$/..
+
+PRJNAME=ucb
+
+TARGET=ucp$(UCP_NAME)
+
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/pkgservices.obj \
+ $(SLO)$/pkguri.obj \
+ $(SLO)$/pkgprovider.obj \
+ $(SLO)$/pkgcontent.obj \
+ $(SLO)$/pkgcontentcaps.obj \
+ $(SLO)$/pkgresultset.obj \
+ $(SLO)$/pkgdatasupplier.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCP_VERSION)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+# --- Targets ----------------------------------------------------------
+
+.ENDIF # L10N_framework
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/package/pkgcontent.cxx b/ucb/source/ucp/package/pkgcontent.cxx
new file mode 100644
index 000000000000..8bdebb138467
--- /dev/null
+++ b/ucb/source/ucp/package/pkgcontent.cxx
@@ -0,0 +1,3012 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+ *************************************************************************/
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include "pkgcontent.hxx"
+#include "pkgprovider.hxx"
+#include "pkgresultset.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace package_ucp;
+
+#define NONE_MODIFIED sal_uInt32( 0x00 )
+#define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
+#define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
+#define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
+#define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProperties::ContentProperties( const rtl::OUString& rContentType )
+: aContentType( rContentType ),
+ nSize( 0 ),
+ bCompressed( sal_True ),
+ bEncrypted( sal_False ),
+ bHasEncryptedEntries( sal_False )
+{
+ bIsFolder = rContentType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_FOLDER_CONTENT_TYPE ) )
+ || rContentType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_FOLDER_CONTENT_TYPE ) );
+ bIsDocument = !bIsFolder;
+
+ OSL_ENSURE( bIsFolder ||
+ rContentType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_STREAM_CONTENT_TYPE ) )
+ || rContentType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_STREAM_CONTENT_TYPE ) ),
+ "ContentProperties::ContentProperties - Unknown type!" );
+}
+
+//=========================================================================
+
+uno::Sequence< ucb::ContentInfo >
+ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
+{
+ if ( bIsFolder )
+ {
+ uno::Sequence< beans::Property > aProps( 1 );
+ aProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = Content::getContentType( rUri.getScheme(), sal_True );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+ aSeq.getArray()[ 0 ].Properties = aProps;
+
+ // Stream.
+ aSeq.getArray()[ 1 ].Type
+ = Content::getContentType( rUri.getScheme(), sal_False );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+ aSeq.getArray()[ 1 ].Properties = aProps;
+
+ return aSeq;
+ }
+ else
+ {
+ return uno::Sequence< ucb::ContentInfo >( 0 );
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+ PackageUri aURI( aURL );
+ ContentProperties aProps;
+ uno::Reference< container::XHierarchicalNameAccess > xPackage;
+
+ if ( loadData( pProvider, aURI, aProps, xPackage ) )
+ {
+ // resource exists
+
+ sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
+ if ( ( nLastSlash + 1 ) == aURL.getLength() )
+ {
+ // Client explicitely requested a folder!
+ if ( !aProps.bIsFolder )
+ return 0;
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() );
+ return new Content( rxSMgr, pProvider, xId, xPackage, aURI, aProps );
+ }
+ else
+ {
+ // resource doesn't exist
+
+ sal_Bool bFolder = sal_False;
+
+ // Guess type according to URI.
+ sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
+ if ( ( nLastSlash + 1 ) == aURL.getLength() )
+ bFolder = sal_True;
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() );
+
+ ucb::ContentInfo aInfo;
+ if ( bFolder || aURI.isRootFolder() )
+ aInfo.Type = getContentType( aURI.getScheme(), sal_True );
+ else
+ aInfo.Type = getContentType( aURI.getScheme(), sal_False );
+
+ return new Content( rxSMgr, pProvider, xId, xPackage, aURI, aInfo );
+ }
+}
+
+//=========================================================================
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+{
+ if ( !Info.Type.getLength() )
+ return 0;
+
+ PackageUri aURI( Identifier->getContentIdentifier() );
+
+ if ( !Info.Type.equalsIgnoreAsciiCase(
+ getContentType( aURI.getScheme(), sal_True ) ) &&
+ !Info.Type.equalsIgnoreAsciiCase(
+ getContentType( aURI.getScheme(), sal_False ) ) )
+ return 0;
+
+ uno::Reference< container::XHierarchicalNameAccess > xPackage;
+
+#if 0
+ // Fail, if content does exist.
+ if ( hasData( pProvider, aURI, xPackage ) )
+ return 0;
+#else
+ xPackage = pProvider->createPackage( aURI.getPackage(), aURI.getParam() );
+#endif
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() );
+ return new Content( rxSMgr, pProvider, xId, xPackage, aURI, Info );
+}
+
+//=========================================================================
+// static
+::rtl::OUString Content::getContentType(
+ const ::rtl::OUString& aScheme, sal_Bool bFolder )
+{
+ return ( rtl::OUString::createFromAscii( "application/" )
+ + aScheme
+ + ( bFolder
+ ? rtl::OUString::createFromAscii( "-folder" )
+ : rtl::OUString::createFromAscii( "-stream" ) ) );
+}
+
+//=========================================================================
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const uno::Reference< container::XHierarchicalNameAccess > & Package,
+ const PackageUri& rUri,
+ const ContentProperties& rProps )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aUri( rUri ),
+ m_aProps( rProps ),
+ m_eState( PERSISTENT ),
+ m_xPackage( Package ),
+ m_pProvider( pProvider ),
+ m_nModifiedProps( NONE_MODIFIED )
+{
+}
+
+//=========================================================================
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const uno::Reference< container::XHierarchicalNameAccess > & Package,
+ const PackageUri& rUri,
+ const ucb::ContentInfo& Info )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aUri( rUri ),
+ m_aProps( Info.Type ),
+ m_eState( TRANSIENT ),
+ m_xPackage( Package ),
+ m_pProvider( pProvider ),
+ m_nModifiedProps( NONE_MODIFIED )
+{
+}
+
+//=========================================================================
+// virtual
+Content::~Content()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Content::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ if ( isFolder() )
+ aRet = cppu::queryInterface(
+ rType, static_cast< ucb::XContentCreator * >( this ) );
+
+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( isFolder() )
+ {
+ static cppu::OTypeCollection* pFolderTypes = 0;
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pFolderTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pDocumentTypes = 0;
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pDocumentTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.PackageContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ if ( isFolder() )
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString::createFromAscii(
+ PACKAGE_FOLDER_CONTENT_SERVICE_NAME );
+ else
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString::createFromAscii(
+ PACKAGE_STREAM_CONTENT_SERVICE_NAME );
+
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.aContentType;
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "No properties!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getPropertySetInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getCommandInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open
+ //////////////////////////////////////////////////////////////////
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet = open( aOpenCommand, Environment );
+ }
+ else if ( !m_aUri.isRootFolder()
+ && aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ //////////////////////////////////////////////////////////////////
+
+ ucb::InsertCommandArgument aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ sal_Int32 nNameClash = aArg.ReplaceExisting
+ ? ucb::NameClash::OVERWRITE
+ : ucb::NameClash::ERROR;
+ insert( aArg.Data, nNameClash, Environment );
+ }
+ else if ( !m_aUri.isRootFolder()
+ && aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ //////////////////////////////////////////////////////////////////
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+ destroy( bDeletePhysical, Environment );
+
+ // Remove own and all children's persistent data.
+ if ( !removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ Environment,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer
+ // ( Not available at stream objects )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::TransferInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ transfer( aInfo, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) &&
+ isFolder() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent
+ // ( Not available at stream objects )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::ContentInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= createNewContent( aInfo );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "flush" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // flush
+ // ( Not available at stream objects )
+ //////////////////////////////////////////////////////////////////
+
+ if( !flushData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ Environment,
+ rtl::OUString::createFromAscii(
+ "Cannot write file to disk!" ),
+ this );
+ // Unreachable
+ }
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ // @@@ Implement logic to abort running commands, if this makes
+ // sense for your content.
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getCreatableContentsInfo( m_aUri );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ if ( isFolder() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !Info.Type.getLength() )
+ return uno::Reference< ucb::XContent >();
+
+ if ( !Info.Type.equalsIgnoreAsciiCase(
+ getContentType( m_aUri.getScheme(), sal_True ) ) &&
+ !Info.Type.equalsIgnoreAsciiCase(
+ getContentType( m_aUri.getScheme(), sal_False ) ) )
+ return uno::Reference< ucb::XContent >();
+
+ rtl::OUString aURL = m_aUri.getUri();
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ if ( Info.Type.equalsIgnoreAsciiCase(
+ getContentType( m_aUri.getScheme(), sal_True ) ) )
+ aURL += rtl::OUString::createFromAscii( "New_Folder" );
+ else
+ aURL += rtl::OUString::createFromAscii( "New_Stream" );
+
+ uno::Reference< ucb::XContentIdentifier > xId(
+ new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) );
+
+ return create( m_xSMgr, m_pProvider, xId, Info );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "createNewContent called on non-folder object!" );
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString Content::getParentURL()
+{
+ return m_aUri.getParentUri();
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const rtl::OUString& rContentId )
+{
+ ContentProperties aData;
+ uno::Reference< container::XHierarchicalNameAccess > xPackage;
+ if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) )
+ {
+ return getPropertyValues( rSMgr,
+ rProperties,
+ aData,
+ rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >(
+ pProvider ),
+ rContentId );
+ }
+ else
+ {
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ xRow->appendVoid( pProps[ n ] );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+ }
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const ContentProperties& rData,
+ const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >&
+ rProvider,
+ const rtl::OUString& rContentId )
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ uno::Reference< beans::XPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ // Process Core properties.
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ xRow->appendString ( rProp, rData.aContentType );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, rData.aTitle );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.bIsDocument );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.bIsFolder );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ xRow->appendObject(
+ rProp, uno::makeAny(
+ rData.getCreatableContentsInfo(
+ PackageUri( rContentId ) ) ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ xRow->appendString ( rProp, rData.aMediaType );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ // Property only available for streams.
+ if ( rData.bIsDocument )
+ xRow->appendLong( rProp, rData.nSize );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) )
+ {
+ // Property only available for streams.
+ if ( rData.bIsDocument )
+ xRow->appendBoolean( rProp, rData.bCompressed );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) )
+ {
+ // Property only available for streams.
+ if ( rData.bIsDocument )
+ xRow->appendBoolean( rProp, rData.bEncrypted );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) )
+ {
+ // Property only available for root folder.
+ PackageUri aURI( rContentId );
+ if ( aURI.isRootFolder() )
+ xRow->appendBoolean( rProp, rData.bHasEncryptedEntries );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ rProvider->getAdditionalPropertySet( rContentId,
+ sal_False ),
+ uno::UNO_QUERY );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ if ( !xRow->appendPropertySetValue(
+ xAdditionalPropSet,
+ rProp ) )
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ else
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ }
+ }
+ else
+ {
+ // Append all Core Properties.
+ xRow->appendString (
+ beans::Property(
+ rtl::OUString::createFromAscii( "ContentType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.aContentType );
+ xRow->appendString(
+ beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData.aTitle );
+ xRow->appendBoolean(
+ beans::Property(
+ rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.bIsDocument );
+ xRow->appendBoolean(
+ beans::Property(
+ rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.bIsFolder );
+ xRow->appendObject(
+ beans::Property(
+ rtl::OUString::createFromAscii( "CreatableContentsInfo" ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny(
+ rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
+ xRow->appendString(
+ beans::Property(
+ rtl::OUString::createFromAscii( "MediaType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ),
+ rData.aMediaType );
+
+ // Properties only available for streams.
+ if ( rData.bIsDocument )
+ {
+ xRow->appendLong(
+ beans::Property(
+ rtl::OUString::createFromAscii( "Size" ),
+ -1,
+ getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.nSize );
+
+ xRow->appendBoolean(
+ beans::Property(
+ rtl::OUString::createFromAscii( "Compressed" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND ),
+ rData.bCompressed );
+
+ xRow->appendBoolean(
+ beans::Property(
+ rtl::OUString::createFromAscii( "Encrypted" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND ),
+ rData.bEncrypted );
+ }
+
+ // Properties only available for root folder.
+ PackageUri aURI( rContentId );
+ if ( aURI.isRootFolder() )
+ {
+ xRow->appendBoolean(
+ beans::Property(
+ rtl::OUString::createFromAscii( "HasEncryptedEntries" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.bHasEncryptedEntries );
+ }
+
+ // Append all Additional Core Properties.
+
+ uno::Reference< beans::XPropertySet > xSet(
+ rProvider->getAdditionalPropertySet( rContentId, sal_False ),
+ uno::UNO_QUERY );
+ xRow->appendPropertySet( xSet );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+//=========================================================================
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return getPropertyValues( m_xSMgr,
+ rProperties,
+ m_aProps,
+ rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >(
+ m_xProvider.get() ),
+ m_xIdentifier->getContentIdentifier() );
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+// aEvent.PropertyName =
+ aEvent.PropertyHandle = -1;
+// aEvent.OldValue =
+// aEvent.NewValue =
+
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+
+ uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+ sal_Bool bExchange = sal_False;
+ sal_Bool bStore = sal_False;
+ rtl::OUString aNewTitle;
+ sal_Int32 nTitlePos = -1;
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+
+ if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ if ( m_aUri.isRootFolder() )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty titles!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.aTitle )
+ {
+ // modified title -> modified URL -> exchange !
+ if ( m_eState == PERSISTENT )
+ bExchange = sal_True;
+
+ // new value will be set later...
+ aNewTitle = aNewValue;
+
+ // remember position within sequence of values
+ // (for error handling).
+ nTitlePos = n;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<=
+ lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<=
+ beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ if ( aNewValue != m_aProps.aMediaType )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = uno::makeAny( m_aProps.aMediaType );
+ aEvent.NewValue = uno::makeAny( aNewValue );
+
+ m_aProps.aMediaType = aNewValue;
+ nChanged++;
+ bStore = sal_True;
+ m_nModifiedProps |= MEDIATYPE_MODIFIED;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) )
+ {
+ // Property only available for streams.
+ if ( m_aProps.bIsDocument )
+ {
+ sal_Bool bNewValue;
+ if ( rValue.Value >>= bNewValue )
+ {
+ if ( bNewValue != m_aProps.bCompressed )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = uno::makeAny( m_aProps.bCompressed );
+ aEvent.NewValue = uno::makeAny( bNewValue );
+
+ m_aProps.bCompressed = bNewValue;
+ nChanged++;
+ bStore = sal_True;
+ m_nModifiedProps |= COMPRESSED_MODIFIED;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Compressed only supported by streams!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) )
+ {
+ // Property only available for streams.
+ if ( m_aProps.bIsDocument )
+ {
+ sal_Bool bNewValue;
+ if ( rValue.Value >>= bNewValue )
+ {
+ if ( bNewValue != m_aProps.bEncrypted )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = uno::makeAny( m_aProps.bEncrypted );
+ aEvent.NewValue = uno::makeAny( bNewValue );
+
+ m_aProps.bEncrypted = bNewValue;
+ nChanged++;
+ bStore = sal_True;
+ m_nModifiedProps |= ENCRYPTED_MODIFIED;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Encrypted only supported by streams!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
+ {
+ // @@@ This is a temporary solution. In the future submitting
+ // the key should be done using an interaction handler!
+
+ // Write-Only property. Only supported by root folder and streams
+ // (all non-root folders of a package have the same encryption key).
+ if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
+ {
+ uno::Sequence < sal_Int8 > aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ if ( aNewValue != m_aProps.aEncryptionKey )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = uno::makeAny(
+ m_aProps.aEncryptionKey );
+ aEvent.NewValue = uno::makeAny( aNewValue );
+
+ m_aProps.aEncryptionKey = aNewValue;
+ nChanged++;
+ bStore = sal_True;
+ m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "EncryptionKey not supported by non-root folder!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet = getAdditionalPropertySet( sal_False );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ try
+ {
+ uno::Any aOldValue
+ = xAdditionalPropSet->getPropertyValue( rValue.Name );
+ if ( aOldValue != rValue.Value )
+ {
+ xAdditionalPropSet->setPropertyValue(
+ rValue.Name, rValue.Value );
+
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = aOldValue;
+ aEvent.NewValue = rValue.Value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( beans::PropertyVetoException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::IllegalArgumentException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= uno::Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+
+ if ( bExchange )
+ {
+ uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
+
+ // Assemble new content identifier...
+ rtl::OUString aNewURL = m_aUri.getParentUri();
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+ aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle );
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL );
+
+ aGuard.clear();
+ if ( exchangeIdentity( xNewId ) )
+ {
+ // Adapt persistent data.
+ renameData( xOldId, xNewId );
+
+ // Adapt Additional Core Properties.
+ renameAdditionalPropertySet( xOldId->getContentIdentifier(),
+ xNewId->getContentIdentifier(),
+ sal_True );
+ }
+ else
+ {
+ // Do not set new title!
+ aNewTitle = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= uno::Exception(
+ rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if ( aNewTitle.getLength() )
+ {
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( m_aProps.aTitle );
+ aEvent.NewValue = uno::makeAny( aNewTitle );
+
+ m_aProps.aTitle = aNewTitle;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+
+ if ( nChanged > 0 )
+ {
+ // Save changes, if content was already made persistent.
+ if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
+ ( bStore && ( m_eState == PERSISTENT ) ) )
+ {
+ if ( !storeData( uno::Reference< io::XInputStream >() ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ aGuard.clear();
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+uno::Any Content::open(
+ const ucb::OpenCommandArgument2& rArg,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ if ( rArg.Mode == ucb::OpenMode::ALL ||
+ rArg.Mode == ucb::OpenMode::FOLDERS ||
+ rArg.Mode == ucb::OpenMode::DOCUMENTS )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, rArg, xEnv );
+ return uno::makeAny( xSet );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a document content
+ //////////////////////////////////////////////////////////////////
+
+ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+ {
+ // Currently(?) unsupported.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( rArg.Mode ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
+ if ( xOut.is() )
+ {
+ // PUSH: write data into xOut
+
+ uno::Reference< io::XInputStream > xIn = getInputStream();
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference< ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii( "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
+
+ while ( nRead > 0 )
+ {
+ aBuffer.realloc( nRead );
+ xOut->writeBytes( aBuffer );
+ aBuffer.realloc( 0 );
+ nRead = xIn->readSomeBytes( aBuffer, 65536 );
+ }
+
+ xOut->closeOutput();
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::IOException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataSink > xDataSink(
+ rArg.Sink, uno::UNO_QUERY );
+ if ( xDataSink.is() )
+ {
+ // PULL: wait for client read
+
+ uno::Reference< io::XInputStream > xIn = getInputStream();
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference<
+ ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii(
+ "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ // Done.
+ xDataSink->setInputStream( xIn );
+ }
+ else
+ {
+ // Note: aOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArg.Sink ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+ }
+
+ return uno::Any();
+}
+
+//=========================================================================
+void Content::insert(
+ const uno::Reference< io::XInputStream >& xStream,
+ sal_Int32 nNameClashResolve,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Check, if all required properties were set.
+ if ( isFolder() )
+ {
+ // Required: Title
+
+ if ( !m_aProps.aTitle.getLength() )
+ m_aProps.aTitle = m_aUri.getName();
+ }
+ else
+ {
+ // Required: rArg.Data
+
+ if ( !xStream.is() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingInputStreamException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Required: Title
+
+ if ( !m_aProps.aTitle.getLength() )
+ m_aProps.aTitle = m_aUri.getName();
+ }
+
+ rtl::OUString aNewURL = m_aUri.getParentUri();
+ if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+ aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
+ PackageUri aNewUri( aNewURL );
+
+ // Handle possible name clash...
+ switch ( nNameClashResolve )
+ {
+ // fail.
+ case ucb::NameClash::ERROR:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_aProps.aTitle ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+
+ // replace (possibly) existing object.
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case ucb::NameClash::RENAME:
+ if ( hasData( aNewUri ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ rtl::OUString aNew = aNewUri.getUri();
+ aNew += rtl::OUString::createFromAscii( "_" );
+ aNew += rtl::OUString::valueOf( ++nTry );
+ aNewUri.setUri( aNew );
+ }
+ while ( hasData( aNewUri ) && ( nTry < 1000 ) );
+
+ if ( nTry == 1000 )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clash!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ else
+ {
+ m_aProps.aTitle += rtl::OUString::createFromAscii( "_" );
+ m_aProps.aTitle += rtl::OUString::valueOf( nTry );
+ }
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ default:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+ }
+
+ // Identifier changed?
+ sal_Bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
+
+ if ( bNewId )
+ {
+ m_xIdentifier = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL );
+ m_aUri = aNewUri;
+ }
+
+ if ( !storeData( xStream ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii( "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ m_eState = PERSISTENT;
+
+ if ( bNewId )
+ {
+ // Take over correct default values from underlying packager...
+ uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
+ loadData( m_pProvider,
+ m_aUri,
+ m_aProps,
+ xXHierarchicalNameAccess );
+
+ aGuard.clear();
+ inserted();
+ }
+}
+
+//=========================================================================
+void Content::destroy(
+ sal_Bool bDeletePhysical,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ m_eState = DEAD;
+
+ aGuard.clear();
+ deleted();
+
+ if ( isFolder() )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical, xEnv );
+ ++it;
+ }
+ }
+}
+
+//=========================================================================
+void Content::transfer(
+ const ucb::TransferInfo& rInfo,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source a package content?
+ if ( ( rInfo.SourceURL.getLength() == 0 ) ||
+ ( rInfo.SourceURL.compareTo(
+ m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source not a parent of me / not me?
+ rtl::OUString aId = m_aUri.getParentUri();
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ if ( rInfo.SourceURL.getLength() <= aId.getLength() )
+ {
+ if ( aId.compareTo(
+ rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(rInfo.SourceURL),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_RECURSIVE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Target is equal to or is a child of source!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 0) Obtain content object for source.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the PackageContentProvider.
+ rtl::Reference< Content > xSource;
+
+ try
+ {
+ xSource = static_cast< Content * >(
+ m_xProvider->queryContent( xId ).get() );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xSource.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(xId->getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate source object!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 1) Create new child content.
+ //////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aType = xSource->isFolder()
+ ? getContentType( m_aUri.getScheme(), sal_True )
+ : getContentType( m_aUri.getScheme(), sal_False );
+ ucb::ContentInfo aContentInfo;
+ aContentInfo.Type = aType;
+ aContentInfo.Attributes = 0;
+
+ // Note: The static cast is okay here, because its sure that
+ // createNewContent always creates a Content.
+ rtl::Reference< Content > xTarget
+ = static_cast< Content * >( createNewContent( aContentInfo ).get() );
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(aId),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "XContentCreator::createNewContent failed!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 2) Copy data from source content to child content.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > aSourceProps
+ = xSource->getPropertySetInfo( xEnv )->getProperties();
+ sal_Int32 nCount = aSourceProps.getLength();
+
+ if ( nCount )
+ {
+ sal_Bool bHadTitle = ( rInfo.NewTitle.getLength() == 0 );
+
+ // Get all source values.
+ uno::Reference< sdbc::XRow > xRow
+ = xSource->getPropertyValues( aSourceProps );
+
+ uno::Sequence< beans::PropertyValue > aValues( nCount );
+ beans::PropertyValue* pValues = aValues.getArray();
+
+ const beans::Property* pProps = aSourceProps.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+ beans::PropertyValue& rValue = pValues[ n ];
+
+ rValue.Name = rProp.Name;
+ rValue.Handle = rProp.Handle;
+
+ if ( !bHadTitle && rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ // Set new title instead of original.
+ bHadTitle = sal_True;
+ rValue.Value <<= rInfo.NewTitle;
+ }
+ else
+ rValue.Value
+ = xRow->getObject( n + 1,
+ uno::Reference<
+ container::XNameAccess >() );
+
+ rValue.State = beans::PropertyState_DIRECT_VALUE;
+
+ if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
+ {
+ // Add Additional Core Property.
+ try
+ {
+ xTarget->addProperty( rProp.Name,
+ rProp.Attributes,
+ rValue.Value );
+ }
+ catch ( beans::PropertyExistException const & )
+ {
+ }
+ catch ( beans::IllegalTypeException const & )
+ {
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ }
+ }
+ }
+
+ // Set target values.
+ xTarget->setPropertyValues( aValues, xEnv );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 3) Commit (insert) child.
+ //////////////////////////////////////////////////////////////////////
+
+ xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
+
+ //////////////////////////////////////////////////////////////////////
+ // 4) Transfer (copy) children of source.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xSource->isFolder() )
+ {
+ uno::Reference< container::XEnumeration > xIter
+ = xSource->getIterator();
+ if ( xIter.is() )
+ {
+ while ( xIter->hasMoreElements() )
+ {
+ try
+ {
+ uno::Reference< container::XNamed > xNamed;
+ xIter->nextElement() >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::transfer - Got no XNamed!" );
+ break;
+ }
+
+ rtl::OUString aName = xNamed->getName();
+
+ if ( !aName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::transfer - Empty name!" );
+ break;
+ }
+
+ rtl::OUString aChildId = xId->getContentIdentifier();
+ if ( ( aChildId.lastIndexOf( '/' ) + 1 )
+ != aChildId.getLength() )
+ aChildId += rtl::OUString::createFromAscii( "/" );
+
+ aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
+
+ ucb::TransferInfo aInfo;
+ aInfo.MoveData = sal_False;
+ aInfo.NewTitle = rtl::OUString();
+ aInfo.SourceURL = aChildId;
+ aInfo.NameClash = rInfo.NameClash;
+
+ // Transfer child to target.
+ xTarget->transfer( aInfo, xEnv );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ }
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 5) Destroy source ( when moving only ) .
+ //////////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ xSource->destroy( sal_True, xEnv );
+
+ // Remove all persistent data of source and its children.
+ if ( !xSource->removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(
+ xSource->m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ xSource->removeAdditionalPropertySet( sal_True );
+ }
+}
+
+//=========================================================================
+sal_Bool Content::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Already persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+ PackageUri aNewUri( xNewId->getContentIdentifier() );
+ if ( !hasData( aNewUri ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ m_aUri = aNewUri;
+ if ( isFolder() )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier > xOldChildId
+ = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ }
+ return sal_True;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
+ "Content::queryChildren - Invalid URL!" );
+
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ if ( aChildURL.indexOf( '/', nLen ) == -1 )
+ {
+ // No further slashes. It's a child!
+ rChildren.push_back(
+ ContentRef(
+ static_cast< Content * >( xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
+ const PackageUri& rURI )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xPackage;
+ if ( rURI.getPackage() == m_aUri.getPackage() )
+ {
+ if ( !m_xPackage.is() )
+ m_xPackage = m_pProvider->createPackage( m_aUri.getPackage(), m_aUri.getParam() );
+
+ return m_xPackage;
+ }
+
+ return m_pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
+{
+ return getPackage( m_aUri );
+}
+
+//=========================================================================
+// static
+sal_Bool Content::hasData(
+ ContentProvider* pProvider,
+ const PackageUri& rURI,
+ uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
+{
+ rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
+ if ( !rxPackage.is() )
+ return sal_False;
+
+ return rxPackage->hasByHierarchicalName( rURI.getPath() );
+}
+
+//=========================================================================
+sal_Bool Content::hasData( const PackageUri& rURI )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xPackage;
+ if ( rURI.getPackage() == m_aUri.getPackage() )
+ {
+ xPackage = getPackage();
+ if ( !xPackage.is() )
+ return sal_False;
+
+ return xPackage->hasByHierarchicalName( rURI.getPath() );
+ }
+
+ return hasData( m_pProvider, rURI, xPackage );
+}
+
+//=========================================================================
+//static
+sal_Bool Content::loadData(
+ ContentProvider* pProvider,
+ const PackageUri& rURI,
+ ContentProperties& rProps,
+ uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
+{
+ rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
+ if ( !rxPackage.is() )
+ return sal_False;
+
+ if ( rURI.isRootFolder() )
+ {
+ // Properties available only from package
+ uno::Reference< beans::XPropertySet > xPackagePropSet(
+ rxPackage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xPackagePropSet.is(),
+ "Content::loadData - "
+ "Got no XPropertySet interface from package!" );
+
+ if ( xPackagePropSet.is() )
+ {
+ // HasEncryptedEntries ( only avalibale at root folder )
+ try
+ {
+ uno::Any aHasEncryptedEntries
+ = xPackagePropSet->getPropertyValue(
+ rtl::OUString::createFromAscii(
+ "HasEncryptedEntries" ) );
+ if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - "
+ "Got no HasEncryptedEntries value!" );
+ return sal_False;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - "
+ "Got no HasEncryptedEntries value!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - "
+ "Got no HasEncryptedEntries value!" );
+ return sal_False;
+ }
+ }
+ }
+
+ if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
+ return sal_False;
+
+ try
+ {
+ uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
+ if ( aEntry.hasValue() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet;
+ aEntry >>= xPropSet;
+
+ if ( !xPropSet.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no XPropertySet interface!" );
+ return sal_False;
+ }
+
+ // Title
+ rProps.aTitle = rURI.getName();
+
+ // MediaType
+ try
+ {
+ uno::Any aMediaType
+ = xPropSet->getPropertyValue(
+ rtl::OUString::createFromAscii( "MediaType" ) );
+ if ( !( aMediaType >>= rProps.aMediaType ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no MediaType value!" );
+ return sal_False;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no MediaType value!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no MediaType value!" );
+ return sal_False;
+ }
+
+ uno::Reference< container::XEnumerationAccess > xEnumAccess;
+ aEntry >>= xEnumAccess;
+
+ // ContentType / IsFolder / IsDocument
+ if ( xEnumAccess.is() )
+ {
+ // folder
+ rProps.aContentType = getContentType( rURI.getScheme(), sal_True );
+ rProps.bIsDocument = sal_False;
+ rProps.bIsFolder = sal_True;
+ }
+ else
+ {
+ // stream
+ rProps.aContentType = getContentType( rURI.getScheme(), sal_False );
+ rProps.bIsDocument = sal_True;
+ rProps.bIsFolder = sal_False;
+ }
+
+ if ( rProps.bIsDocument )
+ {
+ // Size ( only available for streams )
+ try
+ {
+ uno::Any aSize
+ = xPropSet->getPropertyValue(
+ rtl::OUString::createFromAscii( "Size" ) );
+ if ( !( aSize >>= rProps.nSize ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Size value!" );
+ return sal_False;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Size value!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Size value!" );
+ return sal_False;
+ }
+
+ // Compressed ( only available for streams )
+ try
+ {
+ uno::Any aCompressed
+ = xPropSet->getPropertyValue(
+ rtl::OUString::createFromAscii( "Compressed" ) );
+ if ( !( aCompressed >>= rProps.bCompressed ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Compressed value!" );
+ return sal_False;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Compressed value!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Compressed value!" );
+ return sal_False;
+ }
+
+ // Encrypted ( only available for streams )
+ try
+ {
+ uno::Any aEncrypted
+ = xPropSet->getPropertyValue(
+ rtl::OUString::createFromAscii( "Encrypted" ) );
+ if ( !( aEncrypted >>= rProps.bEncrypted ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Encrypted value!" );
+ return sal_False;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Encrypted value!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::loadData - Got no Encrypted value!" );
+ return sal_False;
+ }
+ }
+ return sal_True;
+ }
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool Content::renameData(
+ const uno::Reference< ucb::XContentIdentifier >& xOldId,
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ PackageUri aURI( xOldId->getContentIdentifier() );
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
+ aURI );
+ if ( !xNA.is() )
+ return sal_False;
+
+ if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
+ return sal_False;
+
+ try
+ {
+ uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
+ uno::Reference< container::XNamed > xNamed;
+ aEntry >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::renameData - Got no XNamed interface!" );
+ return sal_False;
+ }
+
+ PackageUri aNewURI( xNewId->getContentIdentifier() );
+
+ // No success indicator!? No return value / exceptions specified.
+ xNamed->setName( aNewURI.getName() );
+
+ return sal_True;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
+ if ( !xNA.is() )
+ return sal_False;
+
+ uno::Reference< beans::XPropertySet > xPackagePropSet(
+ xNA, uno::UNO_QUERY );
+ OSL_ENSURE( xPackagePropSet.is(),
+ "Content::storeData - "
+ "Got no XPropertySet interface from package!" );
+
+ if ( !xPackagePropSet.is() )
+ return sal_False;
+
+ if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
+ {
+ if ( m_aUri.isRootFolder() )
+ {
+ // Property available only from package and from streams (see below)
+ try
+ {
+ xPackagePropSet->setPropertyValue(
+ rtl::OUString::createFromAscii( "EncryptionKey" ),
+ uno::makeAny( m_aProps.aEncryptionKey ) );
+ m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( beans::PropertyVetoException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // setPropertyValue
+ }
+ }
+ }
+
+ if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
+ {
+// if ( !bCreate )
+// return sal_True;
+
+ try
+ {
+ // Create new resource...
+ uno::Reference< lang::XSingleServiceFactory > xFac(
+ xNA, uno::UNO_QUERY );
+ if ( !xFac.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::storeData - "
+ "Got no XSingleServiceFactory interface!" );
+ return sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= isFolder();
+
+ uno::Reference< uno::XInterface > xNew
+ = xFac->createInstanceWithArguments( aArgs );
+
+ if ( !xNew.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::storeData - createInstance failed!" );
+ return sal_False;
+ }
+
+ PackageUri aParentUri( getParentURL() );
+ uno::Any aEntry
+ = xNA->getByHierarchicalName( aParentUri.getPath() );
+ uno::Reference< container::XNameContainer > xParentContainer;
+ aEntry >>= xParentContainer;
+
+ if ( !xParentContainer.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::storeData - "
+ "Got no XNameContainer interface!" );
+ return sal_False;
+ }
+
+ xParentContainer->insertByName( m_aProps.aTitle,
+ uno::makeAny( xNew ) );
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // insertByName
+ OSL_ENSURE( sal_False,
+ "Content::storeData - insertByName failed!" );
+ return sal_False;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // insertByName
+ OSL_ENSURE( sal_False,
+ "Content::storeData - insertByName failed!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // insertByName
+ OSL_ENSURE( sal_False,
+ "Content::storeData - insertByName failed!" );
+ return sal_False;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ OSL_ENSURE( sal_False,
+ "Content::storeData - getByHierarchicalName failed!" );
+ return sal_False;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstanceWithArguments
+ OSL_ENSURE( sal_False, "Content::storeData - Error!" );
+ return sal_False;
+ }
+ }
+
+ if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
+ return sal_False;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet;
+ xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
+
+ if ( !xPropSet.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::storeData - Got no XPropertySet interface!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // Store property values...
+ //////////////////////////////////////////////////////////////////
+
+ if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
+ {
+ xPropSet->setPropertyValue(
+ rtl::OUString::createFromAscii( "MediaType" ),
+ uno::makeAny( m_aProps.aMediaType ) );
+ m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
+ }
+
+ if ( m_nModifiedProps & COMPRESSED_MODIFIED )
+ {
+ if ( !isFolder() )
+ xPropSet->setPropertyValue(
+ rtl::OUString::createFromAscii( "Compressed" ),
+ uno::makeAny( m_aProps.bCompressed ) );
+
+ m_nModifiedProps &= ~COMPRESSED_MODIFIED;
+ }
+
+ if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
+ {
+ if ( !isFolder() )
+ xPropSet->setPropertyValue(
+ rtl::OUString::createFromAscii( "Encrypted" ),
+ uno::makeAny( m_aProps.bEncrypted ) );
+
+ m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
+ }
+
+ if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
+ {
+ if ( !isFolder() )
+ xPropSet->setPropertyValue(
+ rtl::OUString::createFromAscii( "EncryptionKey" ),
+ uno::makeAny( m_aProps.aEncryptionKey ) );
+
+ m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // Store data stream...
+ //////////////////////////////////////////////////////////////////
+
+ if ( xStream.is() && !isFolder() )
+ {
+ uno::Reference< io::XActiveDataSink > xSink(
+ xPropSet, uno::UNO_QUERY );
+
+ if ( !xSink.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::storeData - "
+ "Got no XActiveDataSink interface!" );
+ return sal_False;
+ }
+
+ xSink->setInputStream( xStream );
+ }
+
+ return sal_True;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( beans::PropertyVetoException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // setPropertyValue
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // setPropertyValue
+ }
+
+ OSL_ENSURE( sal_False, "Content::storeData - Error!" );
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool Content::removeData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
+ if ( !xNA.is() )
+ return sal_False;
+
+ PackageUri aParentUri( getParentURL() );
+ if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
+ return sal_False;
+
+ try
+ {
+ uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
+ uno::Reference< container::XNameContainer > xContainer;
+ aEntry >>= xContainer;
+
+ if ( !xContainer.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::removeData - "
+ "Got no XNameContainer interface!" );
+ return sal_False;
+ }
+
+ xContainer->removeByName( m_aUri.getName() );
+ return sal_True;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName, removeByName
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // removeByName
+ }
+
+ OSL_ENSURE( sal_False, "Content::removeData - Error!" );
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool Content::flushData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Note: XChangesBatch is only implemented by the package itself, not
+ // by the single entries. Maybe this has to change...
+
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
+ if ( !xNA.is() )
+ return sal_False;
+
+ uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
+ if ( !xBatch.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::flushData - Got no XChangesBatch interface!" );
+ return sal_False;
+ }
+
+ try
+ {
+ xBatch->commitChanges();
+ return sal_True;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ }
+
+ OSL_ENSURE( sal_False, "Content::flushData - Error!" );
+ return sal_False;
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > Content::getInputStream()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< io::XInputStream > xStream;
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
+ if ( !xNA.is() )
+ return xStream;
+
+ if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
+ return xStream;
+
+ try
+ {
+ uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
+ uno::Reference< io::XActiveDataSink > xSink;
+ aEntry >>= xSink;
+
+ if ( !xSink.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::getInputStream - "
+ "Got no XActiveDataSink interface!" );
+ return xStream;
+ }
+
+ xStream = xSink->getInputStream();
+
+ OSL_ENSURE( xStream.is(),
+ "Content::getInputStream - Got no stream!" );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ }
+
+ return xStream;
+}
+
+//=========================================================================
+uno::Reference< container::XEnumeration > Content::getIterator()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XEnumeration > xIter;
+ uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
+ if ( !xNA.is() )
+ return xIter;
+
+ if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
+ return xIter;
+
+ try
+ {
+ uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
+ uno::Reference< container::XEnumerationAccess > xIterFac;
+ aEntry >>= xIterFac;
+
+ if ( !xIterFac.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::getIterator - "
+ "Got no XEnumerationAccess interface!" );
+ return xIter;
+ }
+
+ xIter = xIterFac->createEnumeration();
+
+ OSL_ENSURE( xIter.is(),
+ "Content::getIterator - Got no iterator!" );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+ }
+
+ return xIter;
+}
diff --git a/ucb/source/ucp/package/pkgcontent.hxx b/ucb/source/ucp/package/pkgcontent.hxx
new file mode 100644
index 000000000000..5dbc8a69c1de
--- /dev/null
+++ b/ucb/source/ucp/package/pkgcontent.hxx
@@ -0,0 +1,335 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PKGCONTENT_HXX
+#define _PKGCONTENT_HXX
+
+#include <list>
+#include <rtl/ref.hxx>
+
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+#include "pkguri.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace beans
+ {
+ struct Property;
+ struct PropertyValue;
+ }
+ namespace container
+ {
+ class XHierarchicalNameAccess;
+ class XEnumeration;
+ }
+ namespace io
+ {
+ class XInputStream;
+ }
+ namespace sdbc
+ {
+ class XRow;
+ }
+ namespace ucb
+ {
+ struct OpenCommandArgument2;
+ struct TransferInfo;
+ }
+} } }
+
+namespace package_ucp
+{
+
+//=========================================================================
+
+// UNO service name for the content.
+#define PACKAGE_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.PackageFolderContent"
+#define PACKAGE_STREAM_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.PackageStreamContent"
+
+//=========================================================================
+
+struct ContentProperties
+{
+ ::rtl::OUString aTitle; // Title
+ ::rtl::OUString aContentType; // ContentType
+ sal_Bool bIsDocument; // IsDocument
+ sal_Bool bIsFolder; // IsFolder
+ ::rtl::OUString aMediaType; // MediaType
+ com::sun::star::uno::Sequence <
+ sal_Int8 > aEncryptionKey; // EncryptionKey
+ sal_Int64 nSize; // Size
+ sal_Bool bCompressed; // Compressed
+ sal_Bool bEncrypted; // Encrypted
+ sal_Bool bHasEncryptedEntries; // HasEncryptedEntries
+
+ ContentProperties()
+ : bIsDocument( sal_True ), bIsFolder( sal_False ), nSize( 0 ),
+ bCompressed( sal_True ), bEncrypted( sal_False ),
+ bHasEncryptedEntries( sal_False ) {}
+
+ ContentProperties( const ::rtl::OUString& rContentType );
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ getCreatableContentsInfo( PackageUri const & rUri ) const;
+};
+
+//=========================================================================
+
+class ContentProvider;
+
+class Content : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ContentState { TRANSIENT, // created via CreateNewContent,
+ // but did not process "insert" yet
+ PERSISTENT, // processed "insert"
+ DEAD // processed "delete"
+ };
+
+ PackageUri m_aUri;
+ ContentProperties m_aProps;
+ ContentState m_eState;
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > m_xPackage;
+ ContentProvider* m_pProvider;
+ sal_uInt32 m_nModifiedProps;
+
+private:
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >& Package,
+ const PackageUri& rUri,
+ const ContentProperties& rProps );
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >& Package,
+ const PackageUri& rUri,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ContentProperties& rData,
+ const rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >& rProvider,
+ const ::rtl::OUString& rContentId );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >
+ getPackage( const PackageUri& rURI );
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >
+ getPackage();
+
+ static sal_Bool
+ loadData( ContentProvider* pProvider,
+ const PackageUri& rURI,
+ ContentProperties& rProps,
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > &
+ rxPackage );
+ static sal_Bool
+ hasData( ContentProvider* pProvider,
+ const PackageUri& rURI,
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > &
+ rxPackage );
+
+ sal_Bool
+ hasData( const PackageUri& rURI );
+ sal_Bool
+ renameData( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xOldId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xNewId );
+ sal_Bool
+ storeData( const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >& xStream );
+ sal_Bool
+ removeData();
+
+ sal_Bool
+ flushData();
+
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+ void queryChildren( ContentRefList& rChildren );
+
+ sal_Bool
+ exchangeIdentity( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+
+ ::com::sun::star::uno::Any
+ open( const ::com::sun::star::ucb::OpenCommandArgument2& rArg,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream >& xStream,
+ sal_Int32 nNameClashResolve,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void destroy( sal_Bool bDeletePhysical,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void transfer( const ::com::sun::star::ucb::TransferInfo& rInfo,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getInputStream();
+
+ sal_Bool isFolder() const { return m_aProps.bIsFolder; }
+
+public:
+ // Create existing content. Fail, if not already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ // Create new content. Fail, if already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ // Called from resultset data supplier.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+
+ // Called from resultset data supplier.
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XEnumeration >
+ getIterator();
+
+ static ::rtl::OUString
+ getContentType( const ::rtl::OUString& aScheme, sal_Bool bFolder );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/package/pkgcontentcaps.cxx b/ucb/source/ucp/package/pkgcontentcaps.cxx
new file mode 100644
index 000000000000..88807d900275
--- /dev/null
+++ b/ucb/source/ucp/package/pkgcontentcaps.cxx
@@ -0,0 +1,562 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ Props/Commands:
+
+ rootfolder folder stream
+ ---------------------------------------------
+ ContentType r r r
+ IsDocument r r r
+ IsFolder r r r
+ MediaType (w) (w) w
+ Title r w w
+ Size - - r
+ CreatableContentsInfo r r r
+ Compressed - - w
+ Encrypted - - w
+ HasEncryptedEntries r - -
+
+ getCommandInfo x x x
+ getPropertySetInfo x x x
+ getPropertyValues x x x
+ setPropertyValues x x x
+ insert - x x
+ delete - x x
+ open x x x
+ transfer x x -
+ flush x x -
+ createNewContent x x -
+
+ *************************************************************************/
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "pkgcontent.hxx"
+
+using namespace com::sun::star;
+using namespace package_ucp;
+
+//=========================================================================
+//
+// Content implementation.
+//
+//=========================================================================
+
+#define MAKEPROPSEQUENCE( a ) \
+ uno::Sequence< beans::Property >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+#define MAKECMDSEQUENCE( a ) \
+ uno::Sequence< ucb::CommandInfo >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+//=========================================================================
+//
+// IMPORTENT: If any property data ( name / type / ... ) are changed, then
+// Content::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( isFolder() )
+ {
+ if ( m_aUri.isRootFolder() )
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aRootFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+ return MAKEPROPSEQUENCE( aRootFolderPropertyInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Folder: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aFolderPropertyInfoTable );
+ }
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Stream: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aStreamPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
+ -1,
+ getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ )
+ };
+ return MAKEPROPSEQUENCE( aStreamPropertyInfoTable );
+ }
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( isFolder() )
+ {
+ if ( m_aUri.isRootFolder() )
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aRootFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "flush" ) ),
+ -1,
+ getCppuVoidType()
+ )
+ };
+
+ return MAKECMDSEQUENCE( aRootFolderCommandInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Folder: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "flush" ) ),
+ -1,
+ getCppuVoidType()
+ )
+ };
+
+ return MAKECMDSEQUENCE( aFolderCommandInfoTable );
+ }
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Stream: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aStreamCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required commands
+ ///////////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////////
+ };
+
+ return MAKECMDSEQUENCE( aStreamCommandInfoTable );
+ }
+}
diff --git a/ucb/source/ucp/package/pkgdatasupplier.cxx b/ucb/source/ucp/package/pkgdatasupplier.cxx
new file mode 100644
index 000000000000..133e16dc7ed8
--- /dev/null
+++ b/ucb/source/ucp/package/pkgdatasupplier.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+#include <osl/diagnose.h>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+#include "pkgdatasupplier.hxx"
+#include "pkgcontent.hxx"
+#include "pkgprovider.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace package_ucp;
+
+namespace package_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aURL;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+
+ ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ uno::Reference< container::XEnumeration > m_xFolderEnum;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+ sal_Bool m_bThrowException;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_xFolderEnum( rContent->getIterator() ), m_nOpenMode( nOpenMode ),
+ m_bCountFinal( !m_xFolderEnum.is() ), m_bThrowException( m_bCountFinal )
+ {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DataSupplier::DataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+DataSupplier::~DataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
+ return m_pImpl->m_aResults[ nIndex ]->aURL;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > DataSupplier::queryContent(
+ sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ sal_Bool bFound = sal_False;
+ sal_uInt32 nPos = nOldCount;
+
+ while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
+ {
+ try
+ {
+ uno::Reference< container::XNamed > xNamed;
+ m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "DataSupplier::getResult - Got no XNamed!" );
+ break;
+ }
+
+ rtl::OUString aName = xNamed->getName();
+
+ if ( !aName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "DataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( aName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+
+ if ( nPos == nIndex )
+ {
+ // Result obtained.
+ bFound = sal_True;
+ break;
+ }
+
+ nPos++;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ m_pImpl->m_bThrowException = sal_True;
+ break;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ m_pImpl->m_bThrowException = sal_True;
+ break;
+ }
+ }
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
+ {
+ try
+ {
+ uno::Reference< container::XNamed > xNamed;
+ m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ OSL_ENSURE( sal_False,
+ "DataSupplier::getResult - Got no XNamed!" );
+ break;
+ }
+
+ rtl::OUString aName = xNamed->getName();
+
+ if ( !aName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "DataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( aName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ m_pImpl->m_bThrowException = sal_True;
+ break;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ m_pImpl->m_bThrowException = sal_True;
+ break;
+ }
+ }
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged(
+ nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
+ sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ static_cast< ContentProvider * >(
+ m_pImpl->m_xContent->getProvider().get() ),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+ if ( m_pImpl->m_bThrowException )
+ throw ucb::ResultSetException();
+}
+
+//=========================================================================
+::rtl::OUString DataSupplier::assembleChildURL( const ::rtl::OUString& aName )
+{
+ rtl::OUString aURL;
+ rtl::OUString aContURL
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+ sal_Int32 nParam = aContURL.indexOf( '?' );
+ if ( nParam >= 0 )
+ {
+ aURL = aContURL.copy( 0, nParam );
+
+ sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
+ if ( nPackageUrlEnd != aURL.getLength() - 1 )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ aURL += ::ucb_impl::urihelper::encodeSegment( aName );
+ aURL += aContURL.copy( nParam );
+ }
+ else
+ {
+ aURL = aContURL;
+
+ sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
+ if ( nPackageUrlEnd != aURL.getLength() - 1 )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ aURL += ::ucb_impl::urihelper::encodeSegment( aName );
+ }
+ return aURL;
+}
+
+
diff --git a/ucb/source/ucp/package/pkgdatasupplier.hxx b/ucb/source/ucp/package/pkgdatasupplier.hxx
new file mode 100644
index 000000000000..2342becad8eb
--- /dev/null
+++ b/ucb/source/ucp/package/pkgdatasupplier.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PKGDATASUPPLIER_HXX
+#define _PKGDATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultset.hxx>
+
+namespace package_ucp {
+
+struct DataSupplier_Impl;
+class Content;
+
+class DataSupplier : public ::ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+public:
+ DataSupplier( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode );
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+
+ ::rtl::OUString assembleChildURL( const ::rtl::OUString& aName );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/package/pkgprovider.cxx b/ucb/source/ucp/package/pkgprovider.cxx
new file mode 100644
index 000000000000..92c35fe78bb9
--- /dev/null
+++ b/ucb/source/ucp/package/pkgprovider.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <hash_map>
+#include <osl/diagnose.h>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include "pkgprovider.hxx"
+#include "pkgcontent.hxx"
+#include "pkguri.hxx"
+
+using namespace com::sun::star;
+
+namespace package_ucp
+{
+
+//=========================================================================
+//
+// class Package.
+//
+//=========================================================================
+
+class Package : public cppu::OWeakObject,
+ public container::XHierarchicalNameAccess
+{
+ friend class ContentProvider;
+
+ rtl::OUString m_aName;
+ uno::Reference< container::XHierarchicalNameAccess > m_xNA;
+ ContentProvider* m_pOwner;
+
+public:
+ Package( const rtl::OUString& rName,
+ const uno::Reference< container::XHierarchicalNameAccess > & xNA,
+ ContentProvider* pOwner )
+ : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
+ virtual ~Package() { m_pOwner->removePackage( m_aName ); }
+
+ // XInterface
+ virtual uno::Any SAL_CALL
+ queryInterface( const uno::Type& aType )
+ throw( uno::RuntimeException )
+ { return m_xNA->queryInterface( aType ); }
+ virtual void SAL_CALL
+ acquire() throw()
+ { OWeakObject::acquire(); }
+ virtual void SAL_CALL
+ release() throw()
+ { OWeakObject::release(); }
+
+ // XHierarchicalNameAccess
+ virtual uno::Any SAL_CALL
+ getByHierarchicalName( const rtl::OUString& aName )
+ throw( container::NoSuchElementException, uno::RuntimeException )
+ { return m_xNA->getByHierarchicalName( aName ); }
+ virtual sal_Bool SAL_CALL
+ hasByHierarchicalName( const rtl::OUString& aName )
+ throw( uno::RuntimeException )
+ { return m_xNA->hasByHierarchicalName( aName ); }
+};
+
+//=========================================================================
+//
+// Packages.
+//
+//=========================================================================
+
+struct equalString
+{
+ bool operator()(
+ const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
+ {
+ return !!( rKey1 == rKey2 );
+ }
+};
+
+struct hashString
+{
+ size_t operator()( const rtl::OUString & rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+typedef std::hash_map
+<
+ rtl::OUString,
+ Package*,
+ hashString,
+ equalString
+>
+PackageMap;
+
+class Packages : public PackageMap {};
+
+}
+
+using namespace package_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rSMgr ),
+ m_pPackages( 0 )
+{
+}
+
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+ delete m_pPackages;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( ContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.PackageContentProvider" ),
+ rtl::OUString::createFromAscii(
+ PACKAGE_CONTENT_PROVIDER_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ if ( !Identifier.is() )
+ return uno::Reference< ucb::XContent >();
+
+ PackageUri aUri( Identifier->getContentIdentifier() );
+ if ( !aUri.isValid() )
+ throw ucb::IllegalIdentifierException();
+
+ // Create a new identifier for the mormalized URL returned by
+ // PackageUri::getUri().
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xId ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ // Create a new content.
+
+ xContent = Content::create( m_xSMgr, this, Identifier ); // not xId!!!
+ registerNewContent( xContent );
+
+ if ( xContent.is() && !xContent->getIdentifier().is() )
+ throw ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
+//=========================================================================
+//
+// Other methods.
+//
+//=========================================================================
+
+uno::Reference< container::XHierarchicalNameAccess >
+ContentProvider::createPackage( const rtl::OUString & rName, const rtl::OUString & rParam )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !rName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "ContentProvider::createPackage - Invalid URL!" );
+ return uno::Reference< container::XHierarchicalNameAccess >();
+ }
+
+ rtl::OUString rURL = rName + rParam;
+
+ if ( m_pPackages )
+ {
+ Packages::const_iterator it = m_pPackages->find( rURL );
+ if ( it != m_pPackages->end() )
+ {
+ // Already instanciated. Return package.
+ return (*it).second->m_xNA;
+ }
+ }
+ else
+ m_pPackages = new Packages;
+
+ // Create new package...
+ try
+ {
+ uno::Sequence< uno::Any > aArguments( 1 );
+ aArguments[ 0 ] <<= rURL;
+
+ uno::Reference< uno::XInterface > xIfc
+ = m_xSMgr->createInstanceWithArguments(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.packages.comp.ZipPackage" ),
+ aArguments );
+
+ if ( xIfc.is() )
+ {
+ uno::Reference<
+ container::XHierarchicalNameAccess > xNameAccess(
+ xIfc, uno::UNO_QUERY );
+
+ OSL_ENSURE( xNameAccess.is(),
+ "ContentProvider::createPackage - "
+ "Got no hierarchical name access!" );
+
+ rtl::Reference< Package> xPackage
+ = new Package( rURL, xNameAccess, this );
+
+ (*m_pPackages)[ rURL ] = xPackage.get();
+
+ return xPackage.get();
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ // createInstanceWithArguemts
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstanceWithArguemts
+ }
+
+ return uno::Reference< container::XHierarchicalNameAccess >();
+}
+
+//=========================================================================
+sal_Bool ContentProvider::removePackage( const rtl::OUString & rName )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pPackages )
+ {
+ Packages::iterator it = m_pPackages->find( rName );
+ if ( it != m_pPackages->end() )
+ {
+ m_pPackages->erase( it );
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
diff --git a/ucb/source/ucp/package/pkgprovider.hxx b/ucb/source/ucp/package/pkgprovider.hxx
new file mode 100644
index 000000000000..89843f192cc1
--- /dev/null
+++ b/ucb/source/ucp/package/pkgprovider.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PKGPROVIDER_HXX
+#define _PKGPROVIDER_HXX
+
+#include <ucbhelper/providerhelper.hxx>
+#include "pkguri.hxx"
+
+namespace com { namespace sun { namespace star { namespace container {
+ class XHierarchicalNameAccess;
+} } } }
+
+namespace package_ucp {
+
+//=========================================================================
+
+// UNO service name for the provider. This name will be used by the UCB to
+// create instances of the provider.
+#define PACKAGE_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.PackageContentProvider"
+#define PACKAGE_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 39
+
+// UCB Content Type.
+#define PACKAGE_FOLDER_CONTENT_TYPE \
+ "application/" PACKAGE_URL_SCHEME "-folder"
+#define PACKAGE_STREAM_CONTENT_TYPE \
+ "application/" PACKAGE_URL_SCHEME "-stream"
+#define PACKAGE_ZIP_FOLDER_CONTENT_TYPE \
+ "application/" PACKAGE_ZIP_URL_SCHEME "-folder"
+#define PACKAGE_ZIP_STREAM_CONTENT_TYPE \
+ "application/" PACKAGE_ZIP_URL_SCHEME "-stream"
+
+//=========================================================================
+
+class Packages;
+
+class ContentProvider : public ::ucbhelper::ContentProviderImplHelper
+{
+ Packages* m_pPackages;
+
+public:
+ ContentProvider( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess >
+ createPackage( const rtl::OUString & rName, const rtl::OUString & rParam );
+ sal_Bool
+ removePackage( const rtl::OUString & rName );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/package/pkgresultset.cxx b/ucb/source/ucp/package/pkgresultset.cxx
new file mode 100644
index 000000000000..076e7aa69132
--- /dev/null
+++ b/ucb/source/ucp/package/pkgresultset.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+#include "pkgdatasupplier.hxx"
+#include "pkgresultset.hxx"
+
+using namespace com::sun::star;
+
+using namespace package_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand,
+ const uno::Reference< ucb::XCommandEnvironment >& rxEnv )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/package/pkgresultset.hxx b/ucb/source/ucp/package/pkgresultset.hxx
new file mode 100644
index 000000000000..43621f8adf90
--- /dev/null
+++ b/ucb/source/ucp/package/pkgresultset.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PKGRESULTSET_HXX
+#define _PKGRESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "pkgcontent.hxx"
+
+namespace package_ucp {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/package/pkgservices.cxx b/ucb/source/ucp/package/pkgservices.cxx
new file mode 100644
index 000000000000..251ce8c78dd1
--- /dev/null
+++ b/ucb/source/ucp/package/pkgservices.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "pkgprovider.hxx"
+
+using namespace com::sun::star;
+
+namespace {
+
+//=========================================================================
+sal_Bool writeInfo(
+ void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+} // namespace
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Write info into registry.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ ::package_ucp::ContentProvider::getImplementationName_Static(),
+ ::package_ucp::ContentProvider::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Create factory, if implementation name matches.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( ::package_ucp::ContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = ::package_ucp::ContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/package/pkguri.cxx b/ucb/source/ucp/package/pkguri.cxx
new file mode 100644
index 000000000000..feb8daec7905
--- /dev/null
+++ b/ucb/source/ucp/package/pkguri.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+#include "osl/diagnose.h"
+
+#include "../inc/urihelper.hxx"
+
+#include "pkguri.hxx"
+
+using namespace package_ucp;
+using namespace rtl;
+
+//=========================================================================
+//=========================================================================
+//
+// PackageUri Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+static void normalize( OUString& rURL )
+{
+ sal_Int32 nPos = 0;
+ do
+ {
+ nPos = rURL.indexOf( '%', nPos );
+ if ( nPos != -1 )
+ {
+ if ( nPos < ( rURL.getLength() - 2 ) )
+ {
+ OUString aTmp = rURL.copy( nPos + 1, 2 );
+ rURL = rURL.replaceAt( nPos + 1, 2, aTmp.toAsciiUpperCase() );
+ nPos++;
+ }
+ }
+ }
+ while ( nPos != -1 );
+}
+
+//=========================================================================
+void PackageUri::init() const
+{
+ // Already inited?
+ if ( m_aUri.getLength() && !m_aPath.getLength() )
+ {
+ // Note: Maybe it's a re-init, setUri only resets m_aPath!
+ m_aPackage = m_aParentUri = m_aName = m_aParam = m_aScheme
+ = OUString();
+
+ // URI must match at least: <sheme>://<non_empty_url_to_file>
+ if ( ( m_aUri.getLength() < PACKAGE_URL_SCHEME_LENGTH + 4 ) )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Scheme must be followed by '://'
+ if ( ( m_aUri.getStr()[ PACKAGE_URL_SCHEME_LENGTH ]
+ != sal_Unicode( ':' ) )
+ ||
+ ( m_aUri.getStr()[ PACKAGE_URL_SCHEME_LENGTH + 1 ]
+ != sal_Unicode( '/' ) )
+ ||
+ ( m_aUri.getStr()[ PACKAGE_URL_SCHEME_LENGTH + 2 ]
+ != sal_Unicode( '/' ) ) )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ rtl::OUString aPureUri;
+ sal_Int32 nParam = m_aUri.indexOf( '?' );
+ if( nParam >= 0 )
+ {
+ m_aParam = m_aUri.copy( nParam );
+ aPureUri = m_aUri.copy( 0, nParam );
+ }
+ else
+ aPureUri = m_aUri;
+
+ // Scheme is case insensitive.
+ m_aScheme = aPureUri.copy(
+ 0, PACKAGE_URL_SCHEME_LENGTH ).toAsciiLowerCase();
+
+ if ( m_aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_URL_SCHEME ) )
+ || m_aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_URL_SCHEME ) ) )
+ {
+ if ( m_aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_URL_SCHEME ) ) )
+ {
+ m_aParam +=
+ ( m_aParam.getLength()
+ ? ::rtl::OUString::createFromAscii( "&purezip" )
+ : ::rtl::OUString::createFromAscii( "?purezip" ) );
+ }
+
+ aPureUri = aPureUri.replaceAt( 0,
+ m_aScheme.getLength(),
+ m_aScheme );
+
+ sal_Int32 nStart = PACKAGE_URL_SCHEME_LENGTH + 3;
+ sal_Int32 nEnd = aPureUri.lastIndexOf( '/' );
+ if ( nEnd == PACKAGE_URL_SCHEME_LENGTH + 3 )
+ {
+ // Only <scheme>:/// - Empty authority
+
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+ else if ( nEnd == ( aPureUri.getLength() - 1 ) )
+ {
+ if ( aPureUri.getStr()[ aPureUri.getLength() - 2 ]
+ == sal_Unicode( '/' ) )
+ {
+ // Only <scheme>://// or <scheme>://<something>//
+
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Remove trailing slash.
+ aPureUri = aPureUri.copy( 0, nEnd );
+ }
+
+
+ nEnd = aPureUri.indexOf( '/', nStart );
+ if ( nEnd == -1 )
+ {
+ // root folder.
+
+ OUString aNormPackage = aPureUri.copy( nStart );
+ normalize( aNormPackage );
+
+ aPureUri = aPureUri.replaceAt(
+ nStart, aPureUri.getLength() - nStart, aNormPackage );
+ m_aPackage
+ = ::ucb_impl::urihelper::decodeSegment( aNormPackage );
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ m_aUri = m_aUri.replaceAt( 0,
+ ( nParam >= 0 )
+ ? nParam
+ : m_aUri.getLength(), aPureUri );
+
+ sal_Int32 nLastSlash = m_aPackage.lastIndexOf( '/' );
+ if ( nLastSlash != -1 )
+ m_aName = ::ucb_impl::urihelper::decodeSegment(
+ m_aPackage.copy( nLastSlash + 1 ) );
+ else
+ m_aName
+ = ::ucb_impl::urihelper::decodeSegment( m_aPackage );
+ }
+ else
+ {
+ m_aPath = aPureUri.copy( nEnd + 1 );
+
+ // Empty path segments or encoded slashes?
+ if ( m_aPath.indexOf(
+ rtl::OUString::createFromAscii( "//" ) ) != -1
+ || m_aPath.indexOf(
+ rtl::OUString::createFromAscii( "%2F" ) ) != -1
+ || m_aPath.indexOf(
+ rtl::OUString::createFromAscii( "%2f" ) ) != -1 )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ OUString aNormPackage = aPureUri.copy( nStart, nEnd - nStart );
+ normalize( aNormPackage );
+
+ aPureUri = aPureUri.replaceAt(
+ nStart, nEnd - nStart, aNormPackage );
+ aPureUri = aPureUri.replaceAt(
+ nEnd + 1,
+ aPureUri.getLength() - nEnd - 1,
+ ::ucb_impl::urihelper::encodeURI( m_aPath ) );
+
+ m_aPackage
+ = ::ucb_impl::urihelper::decodeSegment( aNormPackage );
+ m_aPath = ::ucb_impl::urihelper::decodeSegment( m_aPath );
+ m_aUri = m_aUri.replaceAt( 0,
+ ( nParam >= 0 )
+ ? nParam
+ : m_aUri.getLength(), aPureUri );
+
+ sal_Int32 nLastSlash = aPureUri.lastIndexOf( '/' );
+ if ( nLastSlash != -1 )
+ {
+ m_aParentUri = aPureUri.copy( 0, nLastSlash );
+ m_aName = ::ucb_impl::urihelper::decodeSegment(
+ aPureUri.copy( nLastSlash + 1 ) );
+ }
+ }
+
+ // success
+ m_bValid = true;
+ }
+ else
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ }
+ }
+}
diff --git a/ucb/source/ucp/package/pkguri.hxx b/ucb/source/ucp/package/pkguri.hxx
new file mode 100644
index 000000000000..68513bcfa940
--- /dev/null
+++ b/ucb/source/ucp/package/pkguri.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PKGURI_HXX
+#define _PKGURI_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace package_ucp {
+
+//=========================================================================
+
+#define PACKAGE_URL_SCHEME "vnd.sun.star.pkg"
+#define PACKAGE_ZIP_URL_SCHEME "vnd.sun.star.zip"
+#define PACKAGE_URL_SCHEME_LENGTH 16
+
+//=========================================================================
+
+class PackageUri
+{
+ mutable ::rtl::OUString m_aUri;
+ mutable ::rtl::OUString m_aParentUri;
+ mutable ::rtl::OUString m_aPackage;
+ mutable ::rtl::OUString m_aPath;
+ mutable ::rtl::OUString m_aName;
+ mutable ::rtl::OUString m_aParam;
+ mutable ::rtl::OUString m_aScheme;
+ mutable bool m_bValid;
+
+private:
+ void init() const;
+
+public:
+ PackageUri() : m_bValid( false ) {}
+ PackageUri( const ::rtl::OUString & rPackageUri )
+ : m_aUri( rPackageUri ), m_bValid( false ) {}
+
+ sal_Bool isValid() const
+ { init(); return m_bValid; }
+
+ const ::rtl::OUString & getUri() const
+ { init(); return m_aUri; }
+
+ void setUri( const ::rtl::OUString & rPackageUri )
+ { m_aPath = ::rtl::OUString(); m_aUri = rPackageUri; m_bValid = false; }
+
+ const ::rtl::OUString & getParentUri() const
+ { init(); return m_aParentUri; }
+
+ const ::rtl::OUString & getPackage() const
+ { init(); return m_aPackage; }
+
+ const ::rtl::OUString & getPath() const
+ { init(); return m_aPath; }
+
+ const ::rtl::OUString & getName() const
+ { init(); return m_aName; }
+
+ const ::rtl::OUString & getParam() const
+ { init(); return m_aParam; }
+
+ const ::rtl::OUString & getScheme() const
+ { init(); return m_aScheme; }
+
+ inline sal_Bool isRootFolder() const;
+};
+
+inline sal_Bool PackageUri::isRootFolder() const
+{
+ init();
+ return ( ( m_aPath.getLength() == 1 ) &&
+ ( m_aPath.getStr()[ 0 ] == sal_Unicode( '/' ) ) );
+}
+
+}
+
+#endif
diff --git a/ucb/source/ucp/package/ucppkg.xml b/ucb/source/ucp/package/ucppkg.xml
new file mode 100644
index 000000000000..6b71fca63486
--- /dev/null
+++ b/ucb/source/ucp/package/ucppkg.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucppkg
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.PackageContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to the contents of package (zip
+ archive) files.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.PackageContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.packages.comp.ZipPackage
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XNamed </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.util.XChangesBatch </type>
+</module-description>
diff --git a/ucb/source/ucp/tdoc/makefile.mk b/ucb/source/ucp/tdoc/makefile.mk
new file mode 100644
index 000000000000..83e9599eed72
--- /dev/null
+++ b/ucb/source/ucp/tdoc/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+# Version
+UCPTDOC_MAJOR=1
+TARGET=ucptdoc$(UCPTDOC_MAJOR).uno
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+
+# no "lib" prefix
+DLLPRE =
+
+SLOFILES=\
+ $(SLO)$/tdoc_provider.obj \
+ $(SLO)$/tdoc_services.obj \
+ $(SLO)$/tdoc_uri.obj \
+ $(SLO)$/tdoc_content.obj \
+ $(SLO)$/tdoc_contentcaps.obj \
+ $(SLO)$/tdoc_storage.obj \
+ $(SLO)$/tdoc_docmgr.obj \
+ $(SLO)$/tdoc_datasupplier.obj \
+ $(SLO)$/tdoc_resultset.obj \
+ $(SLO)$/tdoc_documentcontentfactory.obj \
+ $(SLO)$/tdoc_passwordrequest.obj \
+ $(SLO)$/tdoc_stgelems.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# Make symbol renaming match library name for Mac OS X
+.IF "$(OS)"=="MACOSX"
+SYMBOLPREFIX=$(TARGET)
+.ENDIF
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # L10N_framework
+
+# --- Targets ----------------------------------------------------------
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/tdoc/tdoc_content.cxx b/ucb/source/ucp/tdoc/tdoc_content.cxx
new file mode 100644
index 000000000000..2c2103e46224
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_content.cxx
@@ -0,0 +1,3135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "osl/diagnose.h"
+#include "osl/doublecheckedlocking.h"
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/io/XActiveDataStreamer.hpp"
+#include "com/sun/star/lang/IllegalAccessException.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/ucb/ContentAction.hpp"
+#include "com/sun/star/ucb/ContentInfoAttribute.hpp"
+#include "com/sun/star/ucb/InsertCommandArgument.hpp"
+#include "com/sun/star/ucb/InteractiveBadTransferURLException.hpp"
+#include "com/sun/star/ucb/MissingInputStreamException.hpp"
+#include "com/sun/star/ucb/MissingPropertiesException.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/NameClashException.hpp"
+#include "com/sun/star/ucb/OpenCommandArgument2.hpp"
+#include "com/sun/star/ucb/OpenMode.hpp"
+#include "com/sun/star/ucb/TransferInfo.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
+#include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
+#include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
+#include "com/sun/star/ucb/XCommandInfo.hpp"
+#include "com/sun/star/ucb/XPersistentPropertySet.hpp"
+
+#include "ucbhelper/cancelcommandexecution.hxx"
+#include "ucbhelper/contentidentifier.hxx"
+#include "ucbhelper/propertyvalueset.hxx"
+
+#include "tdoc_content.hxx"
+#include "tdoc_resultset.hxx"
+#include "tdoc_passwordrequest.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+static ContentType lcl_getContentType( const rtl::OUString & rType )
+{
+ if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_ROOT_CONTENT_TYPE ) ) )
+ return ROOT;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_DOCUMENT_CONTENT_TYPE ) ) )
+ return DOCUMENT;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) ) )
+ return FOLDER;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ return STREAM;
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "Content::Content - unsupported content type string" );
+ return STREAM;
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ // Fail, if resource does not exist.
+ ContentProperties aProps;
+ if ( !Content::loadData( pProvider,
+ Uri( Identifier->getContentIdentifier() ),
+ aProps ) )
+ return 0;
+
+ return new Content( rxSMgr, pProvider, Identifier, aProps );
+}
+
+//=========================================================================
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+{
+ if ( !Info.Type.getLength() )
+ return 0;
+
+ if ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) ) &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ {
+ OSL_ENSURE( sal_False, "Content::create - unsupported content type!" );
+ return 0;
+ }
+
+#if 0
+ // Fail, if content does exist.
+ if ( Content::hasData( pProvider,
+ Uri( Identifier->getContentIdentifier() ) ) )
+ return 0;
+#endif
+
+ return new Content( rxSMgr, pProvider, Identifier, Info );
+}
+
+//=========================================================================
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
+ ContentProvider * pProvider,
+ const uno::Reference< ucb::XContentIdentifier > & Identifier,
+ const ContentProperties & rProps )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( rProps ),
+ m_eState( PERSISTENT ),
+ m_pProvider( pProvider )
+{
+}
+
+//=========================================================================
+// ctor for a content just created via XContentCreator::createNewContent()
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( lcl_getContentType( Info.Type ), rtl::OUString() ), // no Title (yet)
+ m_eState( TRANSIENT ),
+ m_pProvider( pProvider )
+{
+}
+
+//=========================================================================
+// virtual
+Content::~Content()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Content::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = ContentImplHelper::queryInterface( rType );
+
+ if ( !aRet.hasValue() )
+ {
+ aRet = cppu::queryInterface(
+ rType, static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ {
+ if ( !m_aProps.isContentCreator() )
+ return uno::Any();
+ }
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( m_aProps.isContentCreator() )
+ {
+ static cppu::OTypeCollection* pFolderTypes = 0;
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pFolderTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pDocumentTypes = 0;
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pDocumentTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.TransientDocumentsContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+
+ if ( m_aProps.getType() == STREAM )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_STREAM_CONTENT_SERVICE_NAME );
+ else if ( m_aProps.getType() == FOLDER )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_FOLDER_CONTENT_SERVICE_NAME );
+ else if ( m_aProps.getType() == DOCUMENT )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_DOCUMENT_CONTENT_SERVICE_NAME );
+ else
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_ROOT_CONTENT_SERVICE_NAME );
+
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return m_aProps.getContentType();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+Content::getIdentifier()
+ throw( uno::RuntimeException )
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Transient?
+ if ( m_eState == TRANSIENT )
+ {
+ // Transient contents have no identifier.
+ return uno::Reference< ucb::XContentIdentifier >();
+ }
+ }
+ return ContentImplHelper::getIdentifier();
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "No properties!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getPropertySetInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getCommandInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open
+ //////////////////////////////////////////////////////////////////
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet = open( aOpenCommand, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert ( Supported by folders and streams only )
+ //////////////////////////////////////////////////////////////////
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != STREAM ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "insert command only supported by "
+ "folders and streams!" ) ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( eType == STREAM )
+ {
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ Uri aParentUri( aUri.getParentUri() );
+ if ( aParentUri.isDocument() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "insert command not supported by "
+ "streams that are direct children "
+ "of document root!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+#endif
+ ucb::InsertCommandArgument aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ sal_Int32 nNameClash = aArg.ReplaceExisting
+ ? ucb::NameClash::OVERWRITE
+ : ucb::NameClash::ERROR;
+ insert( aArg.Data, nNameClash, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete ( Supported by folders and streams only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != STREAM ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "delete command only supported by "
+ "folders and streams!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+ destroy( bDeletePhysical, Environment );
+
+ // Remove own and all children's persistent data.
+ if ( !removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ Environment,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer ( Supported by document and folders only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "transfer command only supported "
+ "by folders and documents!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ ucb::TransferInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ transfer( aInfo, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent ( Supported by document and folders only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "createNewContent command only "
+ "supported by folders and "
+ "documents!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ ucb::ContentInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= createNewContent( aInfo );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getCreatableContentsInfo();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ if ( m_aProps.isContentCreator() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !Info.Type.getLength() )
+ return uno::Reference< ucb::XContent >();
+
+ sal_Bool bCreateFolder =
+ Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ // streams cannot be created as direct children of document root
+ if ( !bCreateFolder && ( m_aProps.getType() == DOCUMENT ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::createNewContent - streams cannot be "
+ "created as direct children of document root!" );
+ return uno::Reference< ucb::XContent >();
+ }
+#endif
+ if ( !bCreateFolder &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::createNewContent - unsupported type!" );
+ return uno::Reference< ucb::XContent >();
+ }
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.getLength() > 0,
+ "Content::createNewContent - empty identifier!" );
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ if ( bCreateFolder )
+ aURL += rtl::OUString::createFromAscii( "New_Folder" );
+ else
+ aURL += rtl::OUString::createFromAscii( "New_Stream" );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
+
+ return create( m_xSMgr, m_pProvider, xId, Info );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "createNewContent called on non-contentcreator object!" );
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+// virtual
+rtl::OUString Content::getParentURL()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ return aUri.getParentUri();
+}
+
+//=========================================================================
+uno::Reference< ucb::XContentIdentifier >
+Content::makeNewIdentifier( const rtl::OUString& rTitle )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Assemble new content identifier...
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ rtl::OUStringBuffer aNewURL = aUri.getParentUri();
+ aNewURL.append( ::ucb_impl::urihelper::encodeSegment( rTitle ) );
+
+ return
+ uno::Reference< ucb::XContentIdentifier >(
+ new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewURL.makeStringAndClear() ) );
+}
+
+//=========================================================================
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Only folders (root, documents, folders) have children.
+ if ( !m_aProps.getIsFolder() )
+ return;
+
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( aURL.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aURL += rtl::OUString::createFromAscii( "/" );
+ }
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) ||
+ ( nPos == ( aChildURL.getLength() - 1 ) ) )
+ {
+ // No further slashes / only a final slash. It's a child!
+ rChildren.push_back(
+ ContentRef(
+ static_cast< Content * >( xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+sal_Bool Content::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Already persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Only folders and streams can be renamed -> exchange identity.
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( sal_False, "Content::exchangeIdentity - "
+ "Not supported by root or document!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+ if ( !hasData( Uri( xNewId->getContentIdentifier() ) ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ if ( eType == FOLDER )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier > xOldChildId
+ = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ }
+ return sal_True;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - "
+ "Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const rtl::OUString& rContentId )
+{
+ ContentProperties aData;
+ if ( loadData( pProvider, rContentId, aData ) )
+ {
+ return getPropertyValues(
+ rSMgr, rProperties, aData, pProvider, rContentId );
+ }
+ else
+ {
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ xRow->appendVoid( pProps[ n ] );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+ }
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const ContentProperties& rData,
+ ContentProvider* pProvider,
+ const rtl::OUString& rContentId )
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ uno::Reference< beans::XPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ // Process Core properties.
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ xRow->appendString ( rProp, rData.getContentType() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, rData.getTitle() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsDocument() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsFolder() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ xRow->appendObject(
+ rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Storage" ) ) )
+ {
+ // Storage is only supported by folders.
+ ContentType eType = rData.getType();
+ if ( eType == FOLDER )
+ xRow->appendObject(
+ rProp,
+ uno::makeAny(
+ pProvider->queryStorageClone( rContentId ) ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DocumentModel" ) ) )
+ {
+ // DocumentModel is only supported by documents.
+ ContentType eType = rData.getType();
+ if ( eType == DOCUMENT )
+ xRow->appendObject(
+ rProp,
+ uno::makeAny(
+ pProvider->queryDocumentModel( rContentId ) ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ pProvider->getAdditionalPropertySet( rContentId,
+ sal_False ),
+ uno::UNO_QUERY );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ if ( !xRow->appendPropertySetValue(
+ xAdditionalPropSet,
+ rProp ) )
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ else
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ }
+ }
+ else
+ {
+ // Append all Core Properties.
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "ContentType" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getContentType() );
+
+ ContentType eType = rData.getType();
+
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ // Title is read-only for root and documents.
+ beans::PropertyAttribute::BOUND ||
+ ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ ? beans::PropertyAttribute::READONLY
+ : 0 ),
+ rData.getTitle() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsDocument() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsFolder() );
+ xRow->appendObject(
+ beans::Property(
+ rtl::OUString::createFromAscii( "CreatableContentsInfo" ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny( rData.getCreatableContentsInfo() ) );
+
+ // Storage is only supported by folders.
+ if ( eType == FOLDER )
+ xRow->appendObject(
+ beans::Property( rtl::OUString::createFromAscii( "Storage" ),
+ -1,
+ getCppuType(
+ static_cast<
+ const uno::Reference< embed::XStorage > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny( pProvider->queryStorageClone( rContentId ) ) );
+
+ // DocumentModel is only supported by documents.
+ if ( eType == DOCUMENT )
+ xRow->appendObject(
+ beans::Property( rtl::OUString::createFromAscii( "DocumentModel" ),
+ -1,
+ getCppuType(
+ static_cast<
+ const uno::Reference< frame::XModel > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny(
+ pProvider->queryDocumentModel( rContentId ) ) );
+
+ // Append all Additional Core Properties.
+
+ uno::Reference< beans::XPropertySet > xSet(
+ pProvider->getAdditionalPropertySet( rContentId, sal_False ),
+ uno::UNO_QUERY );
+ xRow->appendPropertySet( xSet );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+//=========================================================================
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return getPropertyValues( m_xSMgr,
+ rProperties,
+ m_aProps,
+ m_pProvider,
+ m_xIdentifier->getContentIdentifier() );
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ // aEvent.PropertyName =
+ aEvent.PropertyHandle = -1;
+ // aEvent.OldValue =
+ // aEvent.NewValue =
+
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+
+ uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ sal_Bool bExchange = sal_False;
+ rtl::OUString aOldTitle;
+ sal_Int32 nTitlePos = -1;
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+
+ if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ // Title is read-only for root and documents.
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty titles!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.getTitle() )
+ {
+ // modified title -> modified URL -> exchange !
+ if ( m_eState == PERSISTENT )
+ bExchange = sal_True;
+
+ aOldTitle = m_aProps.getTitle();
+ m_aProps.setTitle( aNewValue );
+
+ // property change event will be sent later...
+
+ // remember position within sequence of values
+ // (for error handling).
+ nTitlePos = n;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty Title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Title Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Storage" ) ) )
+ {
+ ContentType eType = m_aProps.getType();
+ if ( eType == FOLDER )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // Storage is only supported by folders.
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Storage property only supported by folders" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DocumentModel" ) ) )
+ {
+ ContentType eType = m_aProps.getType();
+ if ( eType == DOCUMENT )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // Storage is only supported by folders.
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "DocumentModel property only supported by "
+ "documents" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet = getAdditionalPropertySet( sal_False );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ try
+ {
+ uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
+ rValue.Name );
+ if ( aOldValue != rValue.Value )
+ {
+ xAdditionalPropSet->setPropertyValue(
+ rValue.Name, rValue.Value );
+
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue = aOldValue;
+ aEvent.NewValue = rValue.Value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( beans::PropertyVetoException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::IllegalArgumentException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= uno::Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+
+ if ( bExchange )
+ {
+ uno::Reference< ucb::XContentIdentifier > xOldId
+ = m_xIdentifier;
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = makeNewIdentifier( m_aProps.getTitle() );
+
+ aGuard.clear();
+ if ( exchangeIdentity( xNewId ) )
+ {
+ // Adapt persistent data.
+ renameData( xOldId, xNewId );
+
+ // Adapt Additional Core Properties.
+ renameAdditionalPropertySet( xOldId->getContentIdentifier(),
+ xNewId->getContentIdentifier(),
+ sal_True );
+ }
+ else
+ {
+ // Roll-back.
+ m_aProps.setTitle( aOldTitle );
+ aOldTitle = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= uno::Exception(
+ rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if ( aOldTitle.getLength() )
+ {
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( aOldTitle );
+ aEvent.NewValue = uno::makeAny( m_aProps.getTitle() );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+
+ if ( nChanged > 0 )
+ {
+ // Save changes, if content was already made persistent.
+ if ( !bExchange && ( m_eState == PERSISTENT ) )
+ {
+ if ( !storeData( uno::Reference< io::XInputStream >(), xEnv ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ aChanges.realloc( nChanged );
+
+ aGuard.clear();
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+uno::Any Content::open(
+ const ucb::OpenCommandArgument2& rArg,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ if ( rArg.Mode == ucb::OpenMode::ALL ||
+ rArg.Mode == ucb::OpenMode::FOLDERS ||
+ rArg.Mode == ucb::OpenMode::DOCUMENTS )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, rArg );
+ return uno::makeAny( xSet );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a document content
+ //////////////////////////////////////////////////////////////////
+
+ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+ {
+ // Currently(?) unsupported.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( rArg.Mode ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ uno::Reference< io::XActiveDataStreamer > xDataStreamer(
+ rArg.Sink, uno::UNO_QUERY );
+ if ( xDataStreamer.is() )
+ {
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XStream > xStream = getStream( xEnv );
+ if ( !xStream.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference< ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii(
+ "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ // Done.
+ xDataStreamer->setStream( xStream );
+ }
+ else
+ {
+ uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
+ if ( xOut.is() )
+ {
+ // PUSH: write data into xOut
+
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference< ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii( "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
+
+ while ( nRead > 0 )
+ {
+ aBuffer.realloc( nRead );
+ xOut->writeBytes( aBuffer );
+ aBuffer.realloc( 0 );
+ nRead = xIn->readSomeBytes( aBuffer, 65536 );
+ }
+
+ xOut->closeOutput();
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::IOException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataSink > xDataSink(
+ rArg.Sink, uno::UNO_QUERY );
+ if ( xDataSink.is() )
+ {
+ // PULL: wait for client read
+
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference<
+ ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii(
+ "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ // Done.
+ xDataSink->setInputStream( xIn );
+ }
+ else
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArg.Sink ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+ }
+ }
+
+ return uno::Any();
+}
+
+//=========================================================================
+void Content::insert( const uno::Reference< io::XInputStream >& xData,
+ sal_Int32 nNameClashResolve,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+
+ OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
+ "insert command only supported by streams and folders!" );
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+#if OSL_DEBUG_LEVEL > 0
+ if ( eType == STREAM )
+ {
+ Uri aParentUri( aUri.getParentUri() );
+ OSL_ENSURE( !aParentUri.isDocument(),
+ "insert command not supported by streams that are direct "
+ "children of document root!" );
+ }
+#endif
+#endif
+
+ // Check, if all required properties were set.
+ if ( eType == FOLDER )
+ {
+ // Required: Title
+
+ if ( m_aProps.getTitle().getLength() == 0 )
+ m_aProps.setTitle( aUri.getDecodedName() );
+ }
+ else // stream
+ {
+ // Required: data
+
+ if ( !xData.is() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingInputStreamException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Required: Title
+
+ if ( m_aProps.getTitle().getLength() == 0 )
+ m_aProps.setTitle( aUri.getDecodedName() );
+ }
+
+ rtl::OUStringBuffer aNewURL = aUri.getParentUri();
+ aNewURL.append( m_aProps.getTitle() );
+ Uri aNewUri( aNewURL.makeStringAndClear() );
+
+ // Handle possible name clash...
+ switch ( nNameClashResolve )
+ {
+ // fail.
+ case ucb::NameClash::ERROR:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_aProps.getTitle() ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+
+ // replace (possibly) existing object.
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case ucb::NameClash::RENAME:
+ if ( hasData( aNewUri ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ rtl::OUStringBuffer aNew = aNewUri.getUri();
+ aNew.appendAscii( "_" );
+ aNew.append( rtl::OUString::valueOf( ++nTry ) );
+ aNewUri.setUri( aNew.makeStringAndClear() );
+ }
+ while ( hasData( aNewUri ) && ( nTry < 1000 ) );
+
+ if ( nTry == 1000 )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clash!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ else
+ {
+ rtl::OUStringBuffer aNewTitle = m_aProps.getTitle();
+ aNewTitle.appendAscii( "_" );
+ aNewTitle.append( rtl::OUString::valueOf( ++nTry ) );
+ m_aProps.setTitle( aNewTitle.makeStringAndClear() );
+ }
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ default:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+ }
+
+ // Identifier changed?
+ sal_Bool bNewId = ( aUri != aNewUri );
+
+ if ( bNewId )
+ {
+ m_xIdentifier
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewUri.getUri() );
+ }
+
+ if ( !storeData( xData, xEnv ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii( "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ m_eState = PERSISTENT;
+
+ if ( bNewId )
+ {
+ //loadData( m_pProvider, m_aUri, m_aProps );
+
+ aGuard.clear();
+ inserted();
+ }
+}
+
+//=========================================================================
+void Content::destroy( sal_Bool bDeletePhysical,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+
+ OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
+ "delete command only supported by streams and folders!" );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ m_eState = DEAD;
+
+ aGuard.clear();
+ deleted();
+
+ if ( eType == FOLDER )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical, xEnv );
+ ++it;
+ }
+ }
+}
+
+//=========================================================================
+void Content::notifyDocumentClosed()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ m_eState = DEAD;
+
+ // @@@ anything else to reset or such?
+
+ // callback follows!
+ aGuard.clear();
+
+ // Propagate destruction to content event listeners
+ // Remove this from provider's content list.
+ deleted();
+}
+
+//=========================================================================
+uno::Reference< ucb::XContent >
+Content::queryChildContent( const rtl::OUString & rRelativeChildUri )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ const rtl::OUString aMyId = getIdentifier()->getContentIdentifier();
+ rtl::OUStringBuffer aBuf( aMyId );
+ if ( aMyId.getStr()[ aMyId.getLength() - 1 ] != sal_Unicode( '/' ) )
+ aBuf.appendAscii( "/" );
+ if ( rRelativeChildUri.getStr()[ 0 ] != sal_Unicode( '/' ) )
+ aBuf.append( rRelativeChildUri );
+ else
+ aBuf.append( rRelativeChildUri.copy( 1 ) );
+
+ uno::Reference< ucb::XContentIdentifier > xChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aBuf.makeStringAndClear() );
+
+ uno::Reference< ucb::XContent > xChild;
+ try
+ {
+ xChild = m_pProvider->queryContent( xChildId );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE( xChild.is(),
+ "Content::queryChildContent - unable to create child content!" );
+ return xChild;
+}
+
+//=========================================================================
+void Content::notifyChildRemoved( const rtl::OUString & rRelativeChildUri )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Ugly! Need to create child content object, just to fill event properly.
+ uno::Reference< ucb::XContent > xChild
+ = queryChildContent( rRelativeChildUri );
+
+ if ( xChild.is() )
+ {
+ // callback follows!
+ aGuard.clear();
+
+ // Notify "REMOVED" event.
+ ucb::ContentEvent aEvt(
+ static_cast< cppu::OWeakObject * >( this ),
+ ucb::ContentAction::REMOVED,
+ xChild,
+ getIdentifier() );
+ notifyContentEvent( aEvt );
+ }
+}
+
+//=========================================================================
+void Content::notifyChildInserted( const rtl::OUString & rRelativeChildUri )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Ugly! Need to create child content object, just to fill event properly.
+ uno::Reference< ucb::XContent > xChild
+ = queryChildContent( rRelativeChildUri );
+
+ if ( xChild.is() )
+ {
+ // callback follows!
+ aGuard.clear();
+
+ // Notify "INSERTED" event.
+ ucb::ContentEvent aEvt(
+ static_cast< cppu::OWeakObject * >( this ),
+ ucb::ContentAction::INSERTED,
+ xChild,
+ getIdentifier() );
+ notifyContentEvent( aEvt );
+ }
+}
+
+//=========================================================================
+void Content::transfer(
+ const ucb::TransferInfo& rInfo,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
+
+ if ( ( rInfo.SourceURL.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
+ {
+ // Invaild length (to short).
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ rtl::OUString aScheme
+ = rInfo.SourceURL.copy( 0, TDOC_URL_SCHEME_LENGTH + 2 )
+ .toAsciiLowerCase();
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_URL_SCHEME ":/" ) ) )
+ {
+ // Invalid scheme.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Does source URI describe a tdoc folder or stream?
+ Uri aSourceUri( rInfo.SourceURL );
+ if ( !aSourceUri.isValid() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! Syntax!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ if ( aSourceUri.isRoot() || aSourceUri.isDocument() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Must describe a folder or stream!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source not a parent of me / not me?
+ rtl::OUString aId = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nPos = aId.lastIndexOf( '/' );
+ if ( nPos != ( aId.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aId += rtl::OUString::createFromAscii( "/" );
+ }
+
+ if ( rInfo.SourceURL.getLength() <= aId.getLength() )
+ {
+ if ( aId.compareTo(
+ rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_RECURSIVE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Target is equal to or is a child of source!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( m_aProps.getType() == DOCUMENT )
+ {
+ bool bOK = false;
+
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aSourceUri.getParentUri(), READ_WRITE_NOCREATE );
+ if ( xStorage.is() )
+ {
+ try
+ {
+ if ( xStorage->isStreamElement( aSourceUri.getDecodedName() ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Streams cannot be created as "
+ "children of document root!" ),
+ static_cast< cppu::OWeakObject * >(
+ this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+ bOK = true;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // handled below.
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // handled below.
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // handled below.
+ }
+ }
+
+ if ( !bOK )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Unabale to determine source type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+#endif
+
+ /////////////////////////////////////////////////////////////////////////
+ // Copy data.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aNewName( rInfo.NewTitle.getLength() > 0
+ ? rInfo.NewTitle
+ : aSourceUri.getDecodedName() );
+
+ if ( !copyData( aSourceUri, aNewName ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Cannot copy data!" ) ),
+ this );
+ // Unreachable
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ // Copy own and all children's Additional Core Properties.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aTargetUri = m_xIdentifier->getContentIdentifier();
+ if ( ( aTargetUri.lastIndexOf( '/' ) + 1 ) != aTargetUri.getLength() )
+ aTargetUri += rtl::OUString::createFromAscii( "/" );
+
+ if ( rInfo.NewTitle.getLength() > 0 )
+ aTargetUri += ::ucb_impl::urihelper::encodeSegment( rInfo.NewTitle );
+ else
+ aTargetUri += aSourceUri.getName();
+
+ if ( !copyAdditionalPropertySet(
+ aSourceUri.getUri(), aTargetUri, sal_True ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Cannot copy additional properties!" ) ),
+ this );
+ // Unreachable
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ // Propagate new content.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::Reference< Content > xTarget;
+ try
+ {
+ uno::Reference< ucb::XContentIdentifier > xTargetId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aTargetUri );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the WebDAVContentProvider.
+ xTarget = static_cast< Content * >(
+ m_pProvider->queryContent( xTargetId ).get() );
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( aTargetUri ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate target object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Announce transfered content in its new folder.
+ xTarget->inserted();
+
+ /////////////////////////////////////////////////////////////////////////
+ // Remove source, if requested
+ /////////////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ rtl::Reference< Content > xSource;
+ try
+ {
+ uno::Reference< ucb::XContentIdentifier >
+ xSourceId = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure
+ // that m_xProvider is always the ContentProvider.
+ xSource = static_cast< Content * >(
+ m_xProvider->queryContent( xSourceId ).get() );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xSource.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate target object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Propagate destruction (recursively).
+ xSource->destroy( sal_True, xEnv );
+
+ // Remove all persistent data of source and its children.
+ if ( !xSource->removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ if ( !xSource->removeAdditionalPropertySet( sal_True ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove additional properties of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ } // rInfo.MoveData
+}
+
+//=========================================================================
+//static
+bool Content::hasData( ContentProvider* pProvider, const Uri & rUri )
+{
+ if ( rUri.isRoot() )
+ {
+ return true; // root has no storage
+ }
+ else if ( rUri.isDocument() )
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getUri(), READ );
+ return xStorage.is();
+ }
+ else
+ {
+ // folder or stream
+
+ // Ask parent storage. In case that rUri describes a stream,
+ // ContentProvider::queryStorage( rUri ) would return null.
+
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getParentUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ uno::Reference< container::XNameAccess > xParentNA(
+ xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNA.is(), "Got no css.container.XNameAccess!" );
+
+ return xParentNA->hasByName( rUri.getDecodedName() );
+ }
+}
+
+//=========================================================================
+//static
+bool Content::loadData( ContentProvider* pProvider,
+ const Uri & rUri,
+ ContentProperties& rProps )
+{
+ if ( rUri.isRoot() ) // root has no storage, but can always be created
+ {
+ rProps
+ = ContentProperties(
+ ROOT, pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ else if ( rUri.isDocument() ) // document must have storage
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ rProps
+ = ContentProperties(
+ DOCUMENT, pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ else // stream or folder; stream has no storage; folder has storage
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getParentUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ // Check whether exists at all, is stream or folder
+ try
+ {
+ // return: true -> folder
+ // return: false -> stream
+ // NoSuchElementException -> neither folder nor stream
+ bool bIsFolder
+ = xStorage->isStorageElement( rUri.getDecodedName() );
+
+ rProps
+ = ContentProperties(
+ bIsFolder ? FOLDER : STREAM,
+ pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with such name
+ //OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for any reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ }
+ return true;
+}
+
+//=========================================================================
+bool Content::storeData( const uno::Reference< io::XInputStream >& xData,
+ const uno::Reference<
+ ucb::XCommandEnvironment >& xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "storeData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+
+ if ( eType == FOLDER )
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage( aUri.getUri(), READ_WRITE_CREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ xStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xPropSet.is(),
+ "Content::storeData - Got no XPropertySet interface!" );
+ if ( !xPropSet.is() )
+ return false;
+
+ try
+ {
+ // According to MBA, if no mediatype is set, folder and all
+ // its contents will be lost on save of the document!!!
+ xPropSet->setPropertyValue(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ // @@@ better mediatype
+ "application/binary" ) ) ) );
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( false, "Property MediaType not supported!" );
+ return false;
+ }
+ catch ( beans::PropertyVetoException const & )
+ {
+ OSL_ENSURE( false, "Caught PropertyVetoException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ return false;
+ }
+
+ if ( !commitStorage( xStorage ) )
+ return false;
+ }
+ else if ( eType == STREAM )
+ {
+ // stream
+
+ // Important: Parent storage and output stream must be kept alive until
+ // changes have been committed!
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aUri.getParentUri(), READ_WRITE_CREATE );
+ uno::Reference< io::XOutputStream > xOut;
+
+ if ( !xStorage.is() )
+ return false;
+
+ if ( xData.is() )
+ {
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ xOut = getTruncatedOutputStream( xEnv );
+
+ OSL_ENSURE( xOut.is(), "No target data stream!" );
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nRead = xData->readSomeBytes( aBuffer, 65536 );
+
+ while ( nRead > 0 )
+ {
+ aBuffer.realloc( nRead );
+ xOut->writeBytes( aBuffer );
+ aBuffer.realloc( 0 );
+ nRead = xData->readSomeBytes( aBuffer, 65536 );
+ }
+
+ closeOutputStream( xOut );
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught NotConnectedException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught BufferSizeExceededException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught IOException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( ... )
+ {
+ closeOutputStream( xOut );
+ throw;
+ }
+ }
+
+ // Commit changes.
+ if ( !commitStorage( xStorage ) )
+ return false;
+ }
+ else
+ {
+ OSL_ENSURE( false, "Unknown content type!" );
+ return false;
+ }
+ return true;
+}
+
+//=========================================================================
+bool Content::renameData(
+ const uno::Reference< ucb::XContentIdentifier >& xOldId,
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "renameData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aOldUri( xOldId->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aOldUri.getParentUri(), READ_WRITE_NOCREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ try
+ {
+ Uri aNewUri( xNewId->getContentIdentifier() );
+ xStorage->renameElement(
+ aOldUri.getDecodedName(), aNewUri.getDecodedName() );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with old name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // an element with new name already exists in this storage
+ OSL_ENSURE( false, "Caught ElementExistException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xStorage );
+}
+
+//=========================================================================
+bool Content::removeData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "removeData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aUri.getParentUri(), READ_WRITE_NOCREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ try
+ {
+ xStorage->removeElement( aUri.getDecodedName() );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xStorage );
+}
+
+//=========================================================================
+bool Content::copyData( const Uri & rSourceUri, const rtl::OUString & rNewName )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == STREAM ) )
+ {
+ OSL_ENSURE( false, "copyData not supported by root and streams!" );
+ return false;
+ }
+
+ Uri aDestUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xDestStorage
+ = m_pProvider->queryStorage( aDestUri.getUri(), READ_WRITE_NOCREATE );
+
+ if ( !xDestStorage.is() )
+ return false;
+
+ uno::Reference< embed::XStorage > xSourceStorage
+ = m_pProvider->queryStorage( rSourceUri.getParentUri(), READ );
+
+ if ( !xSourceStorage.is() )
+ return false;
+
+ try
+ {
+ xSourceStorage->copyElementTo( rSourceUri.getDecodedName(),
+ xDestStorage,
+ rNewName );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught ElementExistException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xDestStorage );
+}
+
+//=========================================================================
+// static
+bool Content::commitStorage( const uno::Reference< embed::XStorage > & xStorage )
+{
+ // Commit changes
+ uno::Reference< embed::XTransactedObject > xTO( xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xTO.is(),
+ "Required interface css.embed.XTransactedObject missing!" );
+ try
+ {
+ xTO->commit();
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ return false;
+ }
+
+ return true;
+}
+
+//=========================================================================
+// static
+bool Content::closeOutputStream(
+ const uno::Reference< io::XOutputStream > & xOut )
+{
+ if ( xOut.is() )
+ {
+ try
+ {
+ xOut->closeOutput();
+ return true;
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ OSL_ENSURE( false, "Caught NotConnectedException!" );
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ OSL_ENSURE( false, "Caught BufferSizeExceededException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ }
+ }
+ return false;
+}
+
+//=========================================================================
+static rtl::OUString obtainPassword(
+ const rtl::OUString & rName,
+ task::PasswordRequestMode eMode,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::Reference< DocumentPasswordRequest > xRequest
+ = new DocumentPasswordRequest( eMode, rName );
+
+ if ( xEnv.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = xEnv->getInteractionHandler();
+ if ( xIH.is() )
+ {
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ throw ucb::CommandFailedException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Abort requested by Interaction Handler." ) ),
+ uno::Reference< uno::XInterface >(),
+ xRequest->getRequest() );
+ }
+
+ uno::Reference< task::XInteractionPassword > xPassword(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xPassword.is() )
+ {
+ return xPassword->getPassword();
+ }
+
+ // Unknown selection. Should never happen.
+ throw ucb::CommandFailedException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Interaction Handler selected unknown continuation!" ) ),
+ uno::Reference< uno::XInterface >(),
+ xRequest->getRequest() );
+ }
+ }
+ }
+
+ // No IH or IH did not handle exception.
+ task::DocumentPasswordRequest aRequest;
+ xRequest->getRequest() >>= aRequest;
+ throw aRequest;
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > Content::getInputStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::OUString aUri;
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getInputStream - content is no stream!" );
+
+ aUri = Uri( m_xIdentifier->getContentIdentifier() ).getUri();
+ }
+
+ for ( ;; )
+ {
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return uno::Reference< io::XInputStream >(
+ m_pProvider->queryInputStream( aUri, aPassword ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( aUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+static uno::Reference< io::XOutputStream > lcl_getTruncatedOutputStream(
+ const rtl::OUString & rUri,
+ ContentProvider * pProvider,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+ for ( ;; )
+ {
+ try
+ {
+ return uno::Reference< io::XOutputStream >(
+ pProvider->queryOutputStream(
+ rUri, aPassword, true /* truncate */ ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( rUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream > Content::getTruncatedOutputStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getTruncatedOutputStream - content is no stream!" );
+
+ return lcl_getTruncatedOutputStream(
+ Uri( m_xIdentifier->getContentIdentifier() ).getUri(),
+ m_pProvider,
+ xEnv );
+}
+
+//=========================================================================
+uno::Reference< io::XStream > Content::getStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getStream - content is no stream!" );
+
+ rtl::OUString aUri( Uri( m_xIdentifier->getContentIdentifier() ).getUri() );
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+ for ( ;; )
+ {
+ try
+ {
+ return uno::Reference< io::XStream >(
+ m_pProvider->queryStream(
+ aUri, aPassword, false /* no truncate */ ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( aUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+uno::Sequence< ucb::ContentInfo >
+ContentProperties::getCreatableContentsInfo() const
+{
+ if ( isContentCreator() )
+ {
+ uno::Sequence< beans::Property > aProps( 1 );
+ aProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( getType() == DOCUMENT )
+ {
+ // streams cannot be created as direct children of document root
+ uno::Sequence< ucb::ContentInfo > aSeq( 1 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+ aSeq.getArray()[ 0 ].Properties = aProps;
+
+ return aSeq;
+ }
+ else
+ {
+#endif
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+ aSeq.getArray()[ 0 ].Properties = aProps;
+
+ // Stream.
+ aSeq.getArray()[ 1 ].Type
+ = rtl::OUString::createFromAscii( TDOC_STREAM_CONTENT_TYPE );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+ aSeq.getArray()[ 1 ].Properties = aProps;
+
+ return aSeq;
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ }
+#endif
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "getCreatableContentsInfo called on non-contentcreator "
+ "object!" );
+
+ return uno::Sequence< ucb::ContentInfo >( 0 );
+ }
+}
+
+//=========================================================================
+bool ContentProperties::isContentCreator() const
+{
+ return ( getType() == FOLDER ) || ( getType() == DOCUMENT );
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_content.hxx b/ucb/source/ucp/tdoc/tdoc_content.hxx
new file mode 100644
index 000000000000..b3a3270292be
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_content.hxx
@@ -0,0 +1,342 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_CONTENT_HXX
+#define INCLUDED_TDOC_CONTENT_HXX
+
+#include <ucbhelper/contenthelper.hxx>
+#include <com/sun/star/task/DocumentPasswordRequest.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include "tdoc_provider.hxx"
+
+#define NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT 1
+
+namespace com { namespace sun { namespace star {
+ namespace sdbc { class XRow; }
+ namespace io { class XInputStream; class XOutputStream; }
+ namespace beans { struct PropertyValue; }
+ namespace ucb { struct OpenCommandArgument2; struct TransferInfo;
+ struct ContentInfo; }
+} } }
+
+namespace tdoc_ucp
+{
+
+//=========================================================================
+
+#define TDOC_ROOT_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsRootContent"
+#define TDOC_DOCUMENT_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsDocumentContent"
+#define TDOC_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsFolderContent"
+#define TDOC_STREAM_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsStreamContent"
+
+//=========================================================================
+
+enum ContentType { STREAM, FOLDER, DOCUMENT, ROOT };
+
+class ContentProperties
+{
+public:
+ ContentProperties()
+ {}
+
+ ContentProperties( const ContentType & rType, const rtl::OUString & rTitle )
+ : m_eType( rType ),
+ m_aContentType( rType == STREAM
+ ? rtl::OUString::createFromAscii( TDOC_STREAM_CONTENT_TYPE )
+ : rType == FOLDER
+ ? rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE )
+ : rType == DOCUMENT
+ ? rtl::OUString::createFromAscii( TDOC_DOCUMENT_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( TDOC_ROOT_CONTENT_TYPE ) ),
+ m_aTitle( rTitle )
+ {}
+
+ ContentType getType() const { return m_eType; }
+
+ // Properties
+
+ const rtl::OUString & getContentType() const { return m_aContentType; }
+
+ bool getIsFolder() const { return m_eType > STREAM; }
+ bool getIsDocument() const { return !getIsFolder(); }
+
+ const rtl::OUString & getTitle() const { return m_aTitle; }
+ void setTitle( const rtl::OUString & rTitle ) { m_aTitle = rTitle; }
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ getCreatableContentsInfo() const;
+
+ bool isContentCreator() const;
+
+private:
+ ContentType m_eType;
+ rtl::OUString m_aContentType;
+ rtl::OUString m_aTitle;
+};
+
+//=========================================================================
+
+class Content : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ContentState { TRANSIENT, // created via createNewContent,
+ // but did not process "insert" yet
+ PERSISTENT, // processed "insert"
+ DEAD // processed "delete" / document was closed
+ };
+
+ ContentProperties m_aProps;
+ ContentState m_eState;
+ ContentProvider* m_pProvider;
+
+private:
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const ContentProperties & rProps );
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ static bool hasData( ContentProvider* pProvider, const Uri & rUri );
+ bool hasData( const Uri & rUri ) { return hasData( m_pProvider, rUri ); }
+
+ static bool loadData( ContentProvider* pProvider,
+ const Uri & rUri,
+ ContentProperties& rProps );
+ bool storeData( const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >& xData,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+ bool renameData( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xOldId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xNewId );
+ bool removeData();
+
+ bool copyData( const Uri & rSourceUri, const rtl::OUString & rNewName );
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >
+ makeNewIdentifier( const rtl::OUString& rTitle );
+
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+ void queryChildren( ContentRefList& rChildren );
+
+ sal_Bool exchangeIdentity(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ com::sun::star::uno::Any
+ open( const ::com::sun::star::ucb::OpenCommandArgument2& rArg,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream >& xData,
+ sal_Int32 nNameClashResolve,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void destroy( sal_Bool bDeletePhysical,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void transfer( const ::com::sun::star::ucb::TransferInfo& rInfo,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ContentProperties& rData,
+ ContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+
+
+ static bool commitStorage(
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStorage );
+
+ static bool closeOutputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & xOut );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getInputStream( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > &
+ xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ getTruncatedOutputStream(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >
+ queryChildContent( const rtl::OUString & rRelativeChildUri );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >
+ getStream( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+public:
+ // Create existing content. Fail, if not already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ // Create new content. Fail, if already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ getIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+
+ void notifyDocumentClosed();
+ void notifyChildRemoved( const rtl::OUString & rRelativeChildUri );
+ void notifyChildInserted( const rtl::OUString & rRelativeChildUri );
+
+ rtl::Reference< ContentProvider > getContentProvider() const
+ { return rtl::Reference< ContentProvider >( m_pProvider ); }
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_CONTENT_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
new file mode 100644
index 000000000000..d8c89c351c89
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
@@ -0,0 +1,705 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ **************************************************************************
+
+ Props/Commands:
+
+ root document folder folder stream stream
+ (new) (new)
+ ----------------------------------------------------------------
+ ContentType r r r r r r
+ IsDocument r r r r r r
+ IsFolder r r r r r r
+ Title r r w w w w
+ CreatableContentsInfo r r r r r r
+ Storage - - r r - -
+ DocumentModel - r - - - -
+
+ getCommandInfo x x x x x x
+ getPropertySetInfo x x x x x x
+ getPropertyValues x x x x x x
+ setPropertyValues x x x x x x
+ insert - - x x x(*) x(*)
+ delete - - x - x -
+ open x x x - x -
+ transfer - x x - - -
+ createNewContent - x x - - -
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ (*) not supported by streams that are direct children of document
+#endif
+
+ *************************************************************************/
+
+#include "com/sun/star/beans/Property.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/ucb/CommandInfo.hpp"
+#include "com/sun/star/ucb/OpenCommandArgument2.hpp"
+#include "com/sun/star/ucb/TransferInfo.hpp"
+
+#include "tdoc_content.hxx"
+
+namespace com { namespace sun { namespace star { namespace embed {
+ class XStorage;
+} } } }
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//
+// Content implementation.
+//
+//=========================================================================
+
+#define MAKEPROPSEQUENCE( a ) \
+ uno::Sequence< beans::Property >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+#define MAKECMDSEQUENCE( a ) \
+ uno::Sequence< ucb::CommandInfo >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+//=========================================================================
+//
+// IMPORTENT: If any property data ( name / type / ... ) are changed, then
+// Content::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_aProps.getType() == STREAM )
+ {
+ //=================================================================
+ //
+ // Stream: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aStreamPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aStreamPropertyInfoTable );
+ }
+ else if ( m_aProps.getType() == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Storage" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Reference< embed::XStorage > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+ return MAKEPROPSEQUENCE( aFolderPropertyInfoTable );
+ }
+ else if ( m_aProps.getType() == DOCUMENT )
+ {
+ //=================================================================
+ //
+ // Document: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aDocPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentModel" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Reference< frame::XModel > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+ return MAKEPROPSEQUENCE( aDocPropertyInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root: Supported properties
+ //
+ //=================================================================
+
+ OSL_ENSURE( m_aProps.getType() == ROOT, "Wrong content type!" );
+
+ static const beans::Property aRootPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aRootPropertyInfoTable );
+ }
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_aProps.getType() == STREAM )
+ {
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ Uri aParentUri( aUri.getParentUri() );
+
+ if ( aParentUri.isDocument() )
+ {
+ //=================================================================
+ //
+ // Stream, that is a child of a document: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aStreamCommandInfoTable1[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aStreamCommandInfoTable1 );
+ }
+#endif
+ //=================================================================
+ //
+ // Stream: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aStreamCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aStreamCommandInfoTable );
+ }
+ else if ( m_aProps.getType() == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aFolderCommandInfoTable );
+ }
+ else if ( m_aProps.getType() == DOCUMENT )
+ {
+ //=================================================================
+ //
+ // Document: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aDocCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aDocCommandInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root: Supported commands
+ //
+ //=================================================================
+
+ OSL_ENSURE( m_aProps.getType() == ROOT, "Wrong content type!" );
+
+ static const ucb::CommandInfo aRootCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aRootCommandInfoTable );
+ }
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx b/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx
new file mode 100644
index 000000000000..c9931c872b16
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+
+#include "osl/diagnose.h"
+#include "ucbhelper/contentidentifier.hxx"
+
+#include "tdoc_datasupplier.hxx"
+#include "tdoc_content.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+namespace tdoc_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aURL;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+
+ ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ uno::Sequence< rtl::OUString > * m_pNamesOfChildren;
+ sal_Int32 m_nOpenMode;
+ bool m_bCountFinal;
+ bool m_bThrowException;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_pNamesOfChildren( 0 ), m_nOpenMode( nOpenMode ),
+ m_bCountFinal( false ), m_bThrowException( false )
+ {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+
+ delete m_pNamesOfChildren;
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ResultSetDataSupplier::ResultSetDataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+ResultSetDataSupplier::~ResultSetDataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString
+ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
+ return m_pImpl->m_aResults[ nIndex ]->aURL;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent >
+ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ bool bFound = false;
+
+ if ( queryNamesOfChildren() )
+ {
+ for ( sal_uInt32 n = nOldCount;
+ n < sal::static_int_cast<sal_uInt32>(
+ m_pImpl->m_pNamesOfChildren->getLength());
+ ++n )
+ {
+ const rtl::OUString & rName
+ = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
+
+ if ( !rName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "ResultDataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( rName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+
+ if ( n == nIndex )
+ {
+ // Result obtained.
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 ResultSetDataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ if ( queryNamesOfChildren() )
+ {
+ for ( sal_uInt32 n = nOldCount;
+ n < sal::static_int_cast<sal_uInt32>(
+ m_pImpl->m_pNamesOfChildren->getLength());
+ ++n )
+ {
+ const rtl::OUString & rName
+ = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
+
+ if ( !rName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "ResultDataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( rName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+ }
+ }
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 ResultSetDataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool ResultSetDataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow >
+ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ m_pImpl->m_xContent->getContentProvider().get(),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+ if ( m_pImpl->m_bThrowException )
+ throw ucb::ResultSetException();
+}
+
+//=========================================================================
+bool ResultSetDataSupplier::queryNamesOfChildren()
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_pNamesOfChildren == 0 )
+ {
+ uno::Sequence< rtl::OUString > * pNamesOfChildren
+ = new uno::Sequence< rtl::OUString >();
+
+ if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
+ m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
+ *pNamesOfChildren ) )
+ {
+ OSL_ENSURE( false, "Got no list of children!" );
+ m_pImpl->m_bThrowException = sal_True;
+ return false;
+ }
+ else
+ {
+ m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
+ }
+ }
+ return true;
+}
+
+//=========================================================================
+::rtl::OUString
+ResultSetDataSupplier::assembleChildURL( const ::rtl::OUString& aName )
+{
+ rtl::OUString aContURL
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+ rtl::OUString aURL( aContURL );
+
+ sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
+ if ( nUrlEnd != aURL.getLength() - 1 )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ aURL += aName;
+ return aURL;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx b/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx
new file mode 100644
index 000000000000..28d9a4eba9a2
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DATASUPPLIER_HXX
+#define INCLUDED_TDOC_DATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/resultset.hxx>
+
+namespace tdoc_ucp {
+
+struct DataSupplier_Impl;
+class Content;
+
+class ResultSetDataSupplier : public ::ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+private:
+ bool queryNamesOfChildren();
+ ::rtl::OUString assembleChildURL( const ::rtl::OUString& aName );
+
+public:
+ ResultSetDataSupplier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode = com::sun::star::ucb::OpenMode::ALL );
+ virtual ~ResultSetDataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DATASUPPLIER_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.cxx b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
new file mode 100644
index 000000000000..46aa1ae69ec3
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - filter unwanted models notified by global document event broadcaster
+ - help documents
+ - others, which I don't know yet
+
+ *************************************************************************/
+
+#include "osl/diagnose.h"
+#include "rtl/ref.hxx"
+#include "cppuhelper/weak.hxx"
+
+#include "comphelper/namedvaluecollection.hxx"
+#include "comphelper/documentinfo.hxx"
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/container/XEnumerationAccess.hpp"
+#include "com/sun/star/frame/XStorable.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/document/XStorageBasedDocument.hpp"
+#include "com/sun/star/awt/XTopWindow.hpp"
+
+#include "tdoc_docmgr.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+using ::comphelper::DocumentInfo;
+
+//=========================================================================
+//=========================================================================
+//
+// OfficeDocumentsManager Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+OfficeDocumentsManager::OfficeDocumentsManager(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ OfficeDocumentsEventListener * pDocEventListener )
+: m_xSMgr( xSMgr ),
+ m_xDocEvtNotifier( createDocumentEventNotifier( xSMgr ) ),
+ m_pDocEventListener( pDocEventListener )
+{
+ if ( m_xDocEvtNotifier.is() )
+ {
+ // Order is important (multithreaded environment)
+ m_xDocEvtNotifier->addEventListener( this );
+ buildDocumentsList();
+ }
+}
+
+//=========================================================================
+// virtual
+OfficeDocumentsManager::~OfficeDocumentsManager()
+{
+ OSL_ENSURE( m_aDocs.empty(), "document list not empty!" );
+}
+
+//=========================================================================
+void OfficeDocumentsManager::destroy()
+{
+ if ( m_xDocEvtNotifier.is() )
+ m_xDocEvtNotifier->removeEventListener( this );
+}
+
+//=========================================================================
+static rtl::OUString
+getDocumentId( const uno::Reference< uno::XInterface > & xDoc )
+{
+ rtl::OUString aId;
+
+ // Try to get the UID directly from the document.
+ uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ uno::Any aValue = xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "RuntimeUID" ) ) );
+ aValue >>= aId;
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ // Not actually an error. Property is optional.
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ }
+ }
+
+ if ( aId.getLength() == 0 )
+ {
+ // fallback: generate UID from document's this pointer.
+ // normalize the interface pointer first. Else, calls with different
+ // interfaces to the same object (say, XFoo and XBar) will produce
+ // different IDs
+ uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
+ sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
+ aId = rtl::OUString::valueOf( nId );
+ }
+
+ OSL_ENSURE( aId.getLength() > 0, "getDocumentId - Empty id!" );
+ return aId;
+}
+
+//=========================================================================
+//
+// document::XEventListener
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL OfficeDocumentsManager::notifyEvent(
+ const document::EventObject & Event )
+ throw ( uno::RuntimeException )
+{
+/*
+ Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs
+*/
+
+ if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnLoadFinished" ) ) // document loaded
+ || Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnCreate" ) ) ) // document created
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // already known.
+ break;
+ }
+ ++it;
+ }
+
+ if ( it == m_aDocs.end() )
+ {
+ // new document
+
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ rtl:: OUString aDocId = getDocumentId( Event.Source );
+ rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+
+ m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
+
+ // Propagate document closure.
+ OSL_ENSURE( m_pDocEventListener,
+ "OnLoadFinished/OnCreate event: no owner for insert event propagation!" );
+
+ if ( m_pDocEventListener )
+ m_pDocEventListener->notifyDocumentOpened( aDocId );
+ }
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnUnload" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ // Document has been closed (unloaded)
+
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Propagate document closure.
+ OSL_ENSURE( m_pDocEventListener,
+ "OnUnload event: no owner for close event propagation!" );
+
+ if ( m_pDocEventListener )
+ {
+ rtl::OUString aDocId( (*it).first );
+ m_pDocEventListener->notifyDocumentClosed( aDocId );
+ }
+
+
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnUnload event notified for unknown document!" );
+
+ if( it != m_aDocs.end() )
+ m_aDocs.erase( it );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnSaveDone" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Storage gets exchanged while saving.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ (*it).second.xStorage = xStorage;
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnSaveDone event notified for unknown document!" );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnSaveAsDone" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Storage gets exchanged while saving.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ (*it).second.xStorage = xStorage;
+
+ // Adjust title.
+ (*it).second.aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnSaveAsDone event notified for unknown document!" );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnTitleChanged" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Adjust title.
+ rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+ (*it).second.aTitle = aTitle;
+
+ // Adjust storage.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xDoc.is(), "Got no document storage!" );
+
+ rtl:: OUString aDocId = getDocumentId( Event.Source );
+
+ m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "TitleChanged event notified for unknown document!" );
+ }
+ }
+}
+
+//=========================================================================
+//
+// lang::XEventListener (base of document::XEventListener)
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL OfficeDocumentsManager::disposing(
+ const lang::EventObject& /*Source*/ )
+ throw ( uno::RuntimeException )
+{
+}
+
+//=========================================================================
+//
+// Non-interface.
+//
+//=========================================================================
+
+// static
+uno::Reference< document::XEventBroadcaster >
+OfficeDocumentsManager::createDocumentEventNotifier(
+ const uno::Reference< lang::XMultiServiceFactory >& rXSMgr )
+{
+ uno::Reference< uno::XInterface > xIfc;
+ try
+ {
+ xIfc = rXSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.GlobalEventBroadcaster" ) ) );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE(
+ xIfc.is(),
+ "Could not instanciate com.sun.star.frame.GlobalEventBroadcaster" );
+
+ if ( xIfc.is() )
+ {
+ uno::Reference< document::XEventBroadcaster > xBC(
+ xIfc, uno::UNO_QUERY );
+
+ OSL_ENSURE(
+ xBC.is(),
+ "com.sun.star.frame.GlobalEventBroadcaster does not implement "
+ "interface com.sun.star.document.XEventBroadcaster!" );
+
+ return xBC;
+ }
+ else
+ return uno::Reference< document::XEventBroadcaster >();
+}
+
+//=========================================================================
+void OfficeDocumentsManager::buildDocumentsList()
+{
+ OSL_ENSURE( m_xDocEvtNotifier.is(),
+ "OfficeDocumentsManager::buildDocumentsList - "
+ "No document event notifier!" );
+
+ uno::Reference< container::XEnumerationAccess > xEnumAccess(
+ m_xDocEvtNotifier, uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XEnumeration > xEnum
+ = xEnumAccess->createEnumeration();
+
+ osl::MutexGuard aGuard( m_aMtx );
+
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aValue = xEnum->nextElement();
+ // container::NoSuchElementException
+ // lang::WrappedTargetException
+
+ try
+ {
+ uno::Reference< frame::XModel > xModel;
+ aValue >>= xModel;
+
+ if ( xModel.is() )
+ {
+ if ( isOfficeDocument( xModel ) )
+ {
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // already known.
+ break;
+ }
+ ++it;
+ }
+
+ if ( it == m_aDocs.end() )
+ {
+ // new document
+ rtl::OUString aDocId = getDocumentId( xModel );
+ rtl::OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
+
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( xModel, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xDoc.is(), "Got no document storage!" );
+
+ m_aDocs[ aDocId ]
+ = StorageInfo( aTitle, xStorage, xModel );
+ }
+ }
+ }
+ }
+ catch ( lang::DisposedException const & )
+ {
+ // Note: Due to race conditions the XEnumeration can
+ // contains docs that already have been closed
+ }
+ }
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+OfficeDocumentsManager::queryStorage( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return uno::Reference< embed::XStorage >();
+
+ return (*it).second.xStorage;
+}
+
+//=========================================================================
+rtl::OUString OfficeDocumentsManager::queryDocumentId(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ return getDocumentId( xModel );
+}
+
+//=========================================================================
+uno::Reference< frame::XModel >
+OfficeDocumentsManager::queryDocumentModel( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return uno::Reference< frame::XModel >();
+
+ return (*it).second.xModel;
+}
+
+//=========================================================================
+uno::Sequence< rtl::OUString > OfficeDocumentsManager::queryDocuments()
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Sequence< rtl::OUString > aRet( m_aDocs.size() );
+ sal_Int32 nPos = 0;
+
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ aRet[ nPos ] = (*it).first;
+ ++it;
+ ++nPos;
+ }
+ return aRet;
+}
+
+//=========================================================================
+rtl::OUString
+OfficeDocumentsManager::queryStorageTitle( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return rtl::OUString();
+
+ return (*it).second.aTitle;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isDocumentPreview(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ ::comphelper::NamedValueCollection aArgs(
+ xModel->getArgs() );
+ sal_Bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False );
+ return bIsPreview;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isHelpDocument(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ ::rtl::OUString sURL( xModel->getURL() );
+ if ( sURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.help://" ) ) )
+ return true;
+
+ return false;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ uno::Reference< frame::XController > xController
+ = xModel->getCurrentController();
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XFrame > xFrame
+ = xController->getFrame();
+ if ( xFrame.is() )
+ {
+ // don't use XFrame::isTop here. This nowadays excludes
+ // "sub documents" such as forms embedded in database documents
+ uno::Reference< awt::XTopWindow > xFrameContainer(
+ xFrame->getContainerWindow(), uno::UNO_QUERY );
+ if ( !xFrameContainer.is() )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isBasicIDE(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !m_xModuleMgr.is() )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+ if ( !m_xModuleMgr.is() )
+ {
+ try
+ {
+ m_xModuleMgr
+ = uno::Reference<
+ frame::XModuleManager >(
+ m_xSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.ModuleManager" ) ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE( m_xModuleMgr .is(),
+ "Could not instanciate ModuleManager service!" );
+ }
+ }
+
+ if ( m_xModuleMgr.is() )
+ {
+ rtl::OUString aModule;
+ try
+ {
+ aModule = m_xModuleMgr->identify( xModel );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( frame::UnknownModuleException const & )
+ {
+ OSL_ENSURE( false, "Caught UnknownModuleException!" );
+ }
+
+ if ( aModule.getLength() > 0 )
+ {
+ // Filter unwanted items, that are no real documents.
+ if ( aModule.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.script.BasicIDE" ) ) )
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isOfficeDocument(
+ const uno::Reference< uno::XInterface > & xDoc )
+{
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ uno::Reference< document::XStorageBasedDocument >
+ xStorageBasedDoc( xModel, uno::UNO_QUERY );
+ if ( !xStorageBasedDoc.is() )
+ return false;
+
+ if ( !isWithoutOrInTopLevelFrame( xModel ) )
+ return false;
+
+ if ( isDocumentPreview( xModel ) )
+ return false;
+
+ if ( isHelpDocument( xModel ) )
+ return false;
+
+ if ( isBasicIDE( xModel ) )
+ return false;
+
+ return true;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.hxx b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
new file mode 100644
index 000000000000..8f8b2fc117f0
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DOCMGR_HXX
+#define INCLUDED_TDOC_DOCMGR_HXX
+
+#include <map>
+
+#include "osl/mutex.hxx"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "com/sun/star/document/XEventBroadcaster.hpp"
+#include "com/sun/star/document/XEventListener.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/frame/XModuleManager.hpp"
+
+namespace tdoc_ucp {
+
+ class OfficeDocumentsEventListener
+ {
+ public:
+ virtual void notifyDocumentOpened( const rtl::OUString & rDocId ) = 0;
+ virtual void notifyDocumentClosed( const rtl::OUString & rDocId ) = 0;
+ };
+
+ //=======================================================================
+
+ struct StorageInfo
+ {
+ rtl::OUString aTitle;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > xStorage;
+ com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > xModel;
+
+ StorageInfo() {}; // needed for STL map only.
+
+ StorageInfo(
+ const rtl::OUString & rTitle,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & rxStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & rxModel )
+ : aTitle( rTitle ), xStorage( rxStorage ), xModel( rxModel ) {}
+ };
+
+ //=======================================================================
+
+ struct ltref
+ {
+ bool operator()(
+ const rtl::OUString & r1, const rtl::OUString & r2 ) const
+ {
+ return r1 < r2;
+ }
+ };
+
+ typedef std::map< rtl::OUString, StorageInfo, ltref > DocumentList;
+
+ //=======================================================================
+
+ class OfficeDocumentsManager :
+ public cppu::WeakImplHelper1< com::sun::star::document::XEventListener >
+ {
+ public:
+ OfficeDocumentsManager(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ OfficeDocumentsEventListener * pDocEventListener );
+ virtual ~OfficeDocumentsManager();
+
+ void destroy();
+
+ // document::XEventListener
+ virtual void SAL_CALL notifyEvent(
+ const com::sun::star::document::EventObject & Event )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // lang::XEventListener (base of document::XEventListener)
+ virtual void SAL_CALL disposing(
+ const com::sun::star::lang::EventObject & Source )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // Non-interface
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const rtl::OUString & rDocId );
+
+ rtl::OUString
+ queryDocumentId(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XModel >
+ queryDocumentModel( const rtl::OUString & rDocId );
+
+ com::sun::star::uno::Sequence< rtl::OUString >
+ queryDocuments();
+
+ rtl::OUString
+ queryStorageTitle( const rtl::OUString & rDocId );
+
+ private:
+ static com::sun::star::uno::Reference<
+ com::sun::star::document::XEventBroadcaster >
+ createDocumentEventNotifier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ void buildDocumentsList();
+ bool
+ isOfficeDocument(
+ const com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > & xDoc );
+
+ bool
+ isDocumentPreview(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isWithoutOrInTopLevelFrame(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isBasicIDE(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isHelpDocument(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ osl::Mutex m_aMtx;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::document::XEventBroadcaster > m_xDocEvtNotifier;
+ com::sun::star::uno::Reference<
+ com::sun::star::frame::XModuleManager > m_xModuleMgr;
+ DocumentList m_aDocs;
+ OfficeDocumentsEventListener * m_pDocEventListener;
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DOCMGR_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx
new file mode 100644
index 000000000000..72c5f700aa2c
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "cppuhelper/factory.hxx"
+
+#include "tdoc_documentcontentfactory.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DocumentContentFactory Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DocumentContentFactory::DocumentContentFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
+: m_xSMgr( xSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+DocumentContentFactory::~DocumentContentFactory()
+{
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+::rtl::OUString SAL_CALL DocumentContentFactory::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL
+DocumentContentFactory::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
+ const rtl::OUString * pArray = aSNL.getConstArray();
+ for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ {
+ if ( pArray[ i ] == ServiceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ::rtl::OUString > SAL_CALL
+DocumentContentFactory::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+//=========================================================================
+// static
+rtl::OUString DocumentContentFactory::getImplementationName_Static()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.TransientDocumentsDocumentContentFactory" ) );
+}
+
+//=========================================================================
+// static
+uno::Sequence< rtl::OUString >
+DocumentContentFactory::getSupportedServiceNames_Static()
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.TransientDocumentsDocumentContentFactory" ) );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XTransientDocumentsDocumentContentFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+DocumentContentFactory::createDocumentContent(
+ const uno::Reference< frame::XModel >& Model )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ uno::Reference< frame::XTransientDocumentsDocumentContentFactory > xDocFac;
+ try
+ {
+ xDocFac
+ = uno::Reference< frame::XTransientDocumentsDocumentContentFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb.TransientDocumentsContentProvider" ) )
+ ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ if ( xDocFac.is() )
+ return xDocFac->createDocumentContent( Model );
+
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unable to obtain document content factory!" ) ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+static uno::Reference< uno::XInterface > SAL_CALL
+DocumentContentFactory_CreateInstance(
+ const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
+ throw( uno::Exception )
+{
+ lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
+ new DocumentContentFactory( rSMgr ) );
+ return uno::Reference< uno::XInterface >::query( pX );
+}
+
+//=========================================================================
+// static
+uno::Reference< lang::XSingleServiceFactory >
+DocumentContentFactory::createServiceFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
+{
+ return uno::Reference< lang::XSingleServiceFactory >(
+ cppu::createOneInstanceFactory(
+ rxServiceMgr,
+ DocumentContentFactory::getImplementationName_Static(),
+ DocumentContentFactory_CreateInstance,
+ DocumentContentFactory::getSupportedServiceNames_Static() ) );
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx
new file mode 100644
index 000000000000..7a2d919e5708
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX
+#define INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX
+
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp"
+
+#include "cppuhelper/implbase2.hxx"
+
+namespace tdoc_ucp {
+
+class DocumentContentFactory :
+ public cppu::WeakImplHelper2<
+ com::sun::star::frame::XTransientDocumentsDocumentContentFactory,
+ com::sun::star::lang::XServiceInfo >
+{
+public:
+ DocumentContentFactory( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~DocumentContentFactory();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTransientDocumentsDocumentContentFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createDocumentContent( const ::com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel >& Model )
+ throw ( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+
+ // Non-UNO interfaces
+ static rtl::OUString
+ getImplementationName_Static();
+ static com::sun::star::uno::Sequence< rtl::OUString >
+ getSupportedServiceNames_Static();
+
+ static com::sun::star::uno::Reference<
+ com::sun::star::lang::XSingleServiceFactory >
+ createServiceFactory( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rxServiceMgr );
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx b/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx
new file mode 100644
index 000000000000..c7ce1b893372
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "osl/mutex.hxx"
+
+#include "com/sun/star/lang/XTypeProvider.hpp"
+#include "com/sun/star/task/DocumentPasswordRequest.hpp"
+
+#include "cppuhelper/typeprovider.hxx"
+#include "ucbhelper/interactionrequest.hxx"
+
+#include "tdoc_passwordrequest.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+namespace tdoc_ucp
+{
+ class InteractionSupplyPassword :
+ public ucbhelper::InteractionContinuation,
+ public lang::XTypeProvider,
+ public task::XInteractionPassword
+ {
+ public:
+ InteractionSupplyPassword( ucbhelper::InteractionRequest * pRequest )
+ : InteractionContinuation( pRequest ) {}
+
+ // XInterface
+ virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL acquire()
+ throw ();
+ virtual void SAL_CALL release()
+ throw ();
+
+ // XTypeProvider
+ virtual uno::Sequence< uno::Type > SAL_CALL getTypes()
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw ( uno::RuntimeException );
+
+ // XInteractionContinuation
+ virtual void SAL_CALL select()
+ throw ( uno::RuntimeException );
+
+ // XInteractionPassword
+ virtual void SAL_CALL setPassword( const rtl::OUString & aPasswd )
+ throw ( uno::RuntimeException );
+ virtual rtl::OUString SAL_CALL getPassword()
+ throw ( uno::RuntimeException );
+
+ private:
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aPassword;
+ };
+} // namespace tdoc_ucp
+
+//=========================================================================
+//=========================================================================
+//
+// InteractionSupplyPassword Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL InteractionSupplyPassword::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL InteractionSupplyPassword::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL
+InteractionSupplyPassword::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ static_cast< lang::XTypeProvider * >( this ),
+ static_cast< task::XInteractionContinuation * >( this ),
+ static_cast< task::XInteractionPassword * >( this ) );
+
+ return aRet.hasValue()
+ ? aRet : InteractionContinuation::queryInterface( rType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL
+InteractionSupplyPassword::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static cppu::OImplementationId * pId = 0;
+ if ( !pId )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pId )
+ {
+ static cppu::OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return (*pId).getImplementationId();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL InteractionSupplyPassword::getTypes()
+ throw( uno::RuntimeException )
+{
+ static cppu::OTypeCollection * pCollection = 0;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection collection(
+ getCppuType( static_cast<
+ uno::Reference< lang::XTypeProvider > * >( 0 ) ),
+ getCppuType( static_cast<
+ uno::Reference< task::XInteractionPassword > * >( 0 ) ) );
+ pCollection = &collection;
+ }
+ }
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XInteractionContinuation methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL InteractionSupplyPassword::select()
+ throw( uno::RuntimeException )
+{
+ recordSelection();
+}
+
+//=========================================================================
+//
+// XInteractionPassword methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+InteractionSupplyPassword::setPassword( const ::rtl::OUString& aPasswd )
+ throw ( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_aPassword = aPasswd;
+}
+
+// virtual
+rtl::OUString SAL_CALL InteractionSupplyPassword::getPassword()
+ throw ( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ return m_aPassword;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DocumentPasswordRequest Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DocumentPasswordRequest::DocumentPasswordRequest(
+ task::PasswordRequestMode eMode,
+ const rtl::OUString & rDocumentName )
+{
+ // Fill request...
+ task::DocumentPasswordRequest aRequest;
+// aRequest.Message = // OUString
+// aRequest.Context = // XInterface
+ aRequest.Classification = task::InteractionClassification_ERROR;
+ aRequest.Mode = eMode;
+ aRequest.Name = rDocumentName;
+
+ setRequest( uno::makeAny( aRequest ) );
+
+ // Fill continuations...
+ uno::Sequence<
+ uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
+ aContinuations[ 0 ] = new ucbhelper::InteractionAbort( this );
+ aContinuations[ 1 ] = new ucbhelper::InteractionRetry( this );
+ aContinuations[ 2 ] = new InteractionSupplyPassword( this );
+
+ setContinuations( aContinuations );
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx b/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx
new file mode 100644
index 000000000000..bc170bece65b
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_PASSWORDREQUEST_HXX
+#define INCLUDED_TDOC_PASSWORDREQUEST_HXX
+
+#include "com/sun/star/task/PasswordRequestMode.hpp"
+#include "com/sun/star/task/XInteractionPassword.hpp"
+
+#include "ucbhelper/interactionrequest.hxx"
+
+namespace tdoc_ucp {
+
+ /*
+ @usage:
+
+ uno::Reference< ucb::XCommandEnvironment > Environment = ...;
+
+ if ( Environment.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = Environment->getInteractionHandler();
+ if ( xIH.is() )
+ {
+ rtl::Reference< DocumentPasswordRequest > xRequest
+ = new DocumentPasswordRequest(
+ task::PasswordRequestMode_PASSWORD_ENTER,
+ m_xIdentifier->getContentIdentifier() );
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ // @@@
+ }
+
+ uno::Reference< task::XInteractionRetry > xRetry(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xRetry.is() )
+ {
+ // @@@
+ }
+
+ uno::Reference< task::XInteractionPassword > xPassword(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xPassword.is() )
+ {
+ rtl::OUString aPassword = xPassword->getPassword();
+
+ // @@@
+ }
+ }
+ }
+ }
+
+ */
+
+ class DocumentPasswordRequest : public ucbhelper::InteractionRequest
+ {
+ public:
+ DocumentPasswordRequest(
+ com::sun::star::task::PasswordRequestMode eMode,
+ const rtl::OUString & rDocumentName );
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_PASSWORDREQUEST_HXX */
+
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.cxx b/ucb/source/ucp/tdoc/tdoc_provider.cxx
new file mode 100644
index 000000000000..7ffedfcf1932
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_provider.cxx
@@ -0,0 +1,629 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+
+#include "ucbhelper/contentidentifier.hxx"
+
+#include "tdoc_provider.hxx"
+#include "tdoc_content.hxx"
+#include "tdoc_uri.hxx"
+#include "tdoc_docmgr.hxx"
+#include "tdoc_storage.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
+: ::ucbhelper::ContentProviderImplHelper( xSMgr ),
+ m_xDocsMgr( new OfficeDocumentsManager( xSMgr, this ) ),
+ m_xStgElemFac( new StorageElementFactory( xSMgr, m_xDocsMgr ) )
+{
+}
+
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+ if ( m_xDocsMgr.is() )
+ m_xDocsMgr->destroy();
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ frame::XTransientDocumentsDocumentContentFactory );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ frame::XTransientDocumentsDocumentContentFactory );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1(
+ ContentProvider,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.TransientDocumentsContentProvider" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ TDOC_CONTENT_PROVIDER_SERVICE_NAME ) ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+ContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ Uri aUri( Identifier->getContentIdentifier() );
+ if ( !aUri.isValid() )
+ throw ucb::IllegalIdentifierException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid URL!" ) ),
+ Identifier );
+
+ // Normalize URI.
+ uno::Reference< ucb::XContentIdentifier > xCanonicId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xCanonicId ).get();
+
+ if ( !xContent.is() )
+ {
+ // Create a new content.
+ xContent = Content::create( m_xSMgr, this, xCanonicId );
+ registerNewContent( xContent );
+ }
+
+ return xContent;
+}
+
+//=========================================================================
+//
+// XTransientDocumentsDocumentContentFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+ContentProvider::createDocumentContent(
+ const uno::Reference< frame::XModel >& Model )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ // model -> id -> content identifier -> queryContent
+ if ( m_xDocsMgr.is() )
+ {
+ rtl::OUString aDocId = m_xDocsMgr->queryDocumentId( Model );
+ if ( aDocId.getLength() > 0 )
+ {
+ rtl::OUStringBuffer aBuffer;
+ aBuffer.appendAscii( TDOC_URL_SCHEME ":/" );
+ aBuffer.append( aDocId );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aBuffer.makeStringAndClear() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xId ).get();
+
+ if ( !xContent.is() )
+ {
+ // Create a new content.
+ xContent = Content::create( m_xSMgr, this, xId );
+ }
+
+ if ( xContent.is() )
+ return xContent;
+
+ // no content.
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Illegal Content Identifier!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unable to obtain document id from model!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No Document Manager!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+}
+
+//=========================================================================
+//
+// interface OfficeDocumentsEventListener
+//
+//=========================================================================
+
+// virtual
+void ContentProvider::notifyDocumentClosed( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( getContentListMutex() );
+
+ ::ucbhelper::ContentRefList aAllContents;
+ queryExistingContents( aAllContents );
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ // Notify all content objects related to the closed doc.
+
+ bool bFoundDocumentContent = false;
+ rtl::Reference< Content > xRoot;
+
+ while ( it != end )
+ {
+ Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
+ OSL_ENSURE( aUri.isValid(),
+ "ContentProvider::notifyDocumentClosed - Invalid URI!" );
+
+ if ( !bFoundDocumentContent )
+ {
+ if ( aUri.isRoot() )
+ {
+ xRoot = static_cast< Content * >( (*it).get() );
+ }
+ else if ( aUri.isDocument() )
+ {
+ if ( aUri.getDocumentId() == rDocId )
+ {
+ bFoundDocumentContent = true;
+
+ // document content will notify removal of child itself;
+ // no need for the root to propagate this.
+ xRoot.clear();
+ }
+ }
+ }
+
+ if ( aUri.getDocumentId() == rDocId )
+ {
+ // Inform content.
+ rtl::Reference< Content > xContent
+ = static_cast< Content * >( (*it).get() );
+
+ xContent->notifyDocumentClosed();
+ }
+
+ ++it;
+ }
+
+ if ( xRoot.is() )
+ {
+ // No document content found for rDocId but root content
+ // instanciated. Root content must announce document removal
+ // to content event listeners.
+ xRoot->notifyChildRemoved( rDocId );
+ }
+}
+
+//=========================================================================
+// virtual
+void ContentProvider::notifyDocumentOpened( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( getContentListMutex() );
+
+ ::ucbhelper::ContentRefList aAllContents;
+ queryExistingContents( aAllContents );
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ // Find root content. If instanciated let it propagate document insertion.
+
+ while ( it != end )
+ {
+ Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
+ OSL_ENSURE( aUri.isValid(),
+ "ContentProvider::notifyDocumentOpened - Invalid URI!" );
+
+ if ( aUri.isRoot() )
+ {
+ rtl::Reference< Content > xRoot
+ = static_cast< Content * >( (*it).get() );
+ xRoot->notifyChildInserted( rDocId );
+
+ // Done.
+ break;
+ }
+
+ ++it;
+ }
+}
+
+//=========================================================================
+//
+// Non-UNO
+//
+//=========================================================================
+
+uno::Reference< embed::XStorage >
+ContentProvider::queryStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode ) const
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createStorage( rUri, eMode );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+ return uno::Reference< embed::XStorage >();
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+ContentProvider::queryStorageClone( const rtl::OUString & rUri ) const
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ Uri aUri( rUri );
+ uno::Reference< embed::XStorage > xParentStorage
+ = m_xStgElemFac->createStorage( aUri.getParentUri(), READ );
+ uno::Reference< embed::XStorage > xStorage
+ = m_xStgElemFac->createTemporaryStorage();
+
+ xParentStorage->copyStorageElementLastCommitTo(
+ aUri.getDecodedName(), xStorage );
+ return xStorage;
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+
+ return uno::Reference< embed::XStorage >();
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream >
+ContentProvider::queryInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createInputStream( rUri, rPassword );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XInputStream >();
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream >
+ContentProvider::queryOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return
+ m_xStgElemFac->createOutputStream( rUri, rPassword, bTruncate );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XOutputStream >();
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+ContentProvider::queryStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createStream( rUri, rPassword, bTruncate );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XStream >();
+}
+
+//=========================================================================
+bool ContentProvider::queryNamesOfChildren(
+ const rtl::OUString & rUri, uno::Sequence< rtl::OUString > & rNames ) const
+{
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ // special handling for root, which has no storage, but children.
+ if ( m_xDocsMgr.is() )
+ {
+ rNames = m_xDocsMgr->queryDocuments();
+ return true;
+ }
+ }
+ else
+ {
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = m_xStgElemFac->createStorage( rUri, READ );
+
+ OSL_ENSURE( xStorage.is(), "Got no Storage!" );
+
+ if ( xStorage.is() )
+ {
+ uno::Reference< container::XNameAccess > xNA(
+ xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xNA.is(), "Got no css.container.XNameAccess!" );
+ if ( xNA.is() )
+ {
+ rNames = xNA->getElementNames();
+ return true;
+ }
+ }
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance if the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false,
+ "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+ }
+ return false;
+}
+
+//=========================================================================
+rtl::OUString
+ContentProvider::queryStorageTitle( const rtl::OUString & rUri ) const
+{
+ rtl::OUString aTitle;
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ // always empty.
+ aTitle = rtl::OUString();
+ }
+ else if ( aUri.isDocument() )
+ {
+ // for documents, title shall not be derived from URL. It shall
+ // be somethimg more 'speaking' than just the document UID.
+ if ( m_xDocsMgr.is() )
+ aTitle = m_xDocsMgr->queryStorageTitle( aUri.getDocumentId() );
+ }
+ else
+ {
+ // derive title from URL
+ aTitle = aUri.getDecodedName();
+ }
+
+ OSL_ENSURE( ( aTitle.getLength() > 0 ) || aUri.isRoot(),
+ "ContentProvider::queryStorageTitle - empty title!" );
+ return aTitle;
+}
+
+//=========================================================================
+uno::Reference< frame::XModel >
+ContentProvider::queryDocumentModel( const rtl::OUString & rUri ) const
+{
+ uno::Reference< frame::XModel > xModel;
+
+ if ( m_xDocsMgr.is() )
+ {
+ Uri aUri( rUri );
+ xModel = m_xDocsMgr->queryDocumentModel( aUri.getDocumentId() );
+ }
+
+ OSL_ENSURE( xModel.is(),
+ "ContentProvider::queryDocumentModel - no model!" );
+ return xModel;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.hxx b/ucb/source/ucp/tdoc/tdoc_provider.hxx
new file mode 100644
index 000000000000..70f61e130980
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_provider.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_PROVIDER_HXX
+#define INCLUDED_TDOC_PROVIDER_HXX
+
+#include "rtl/ref.hxx"
+#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
+#include <com/sun/star/packages/WrongPasswordException.hpp>
+#include "ucbhelper/providerhelper.hxx"
+#include "tdoc_uri.hxx" // for TDOC_URL_SCHEME
+#include "tdoc_docmgr.hxx"
+#include "tdoc_storage.hxx" // for StorageAccessMode
+
+namespace com { namespace sun { namespace star { namespace embed {
+ class XStorage;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace frame {
+ class XModel;
+} } } }
+
+namespace tdoc_ucp {
+
+//=========================================================================
+
+#define TDOC_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsContentProvider"
+#define TDOC_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 50
+
+#define TDOC_ROOT_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-root"
+#define TDOC_DOCUMENT_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-document"
+#define TDOC_FOLDER_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-folder"
+#define TDOC_STREAM_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-stream"
+
+//=========================================================================
+
+class StorageElementFactory;
+
+class ContentProvider :
+ public ::ucbhelper::ContentProviderImplHelper,
+ public com::sun::star::frame::XTransientDocumentsDocumentContentFactory,
+ public OfficeDocumentsEventListener
+{
+public:
+ ContentProvider( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTransientDocumentsDocumentContentFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createDocumentContent( const ::com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel >& Model )
+ throw ( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+
+ // Non-UNO interfaces
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const rtl::OUString & rUri, StorageAccessMode eMode ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorageClone( const rtl::OUString & rUri ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ queryInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >
+ queryOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ queryStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ bool queryNamesOfChildren(
+ const rtl::OUString & rUri,
+ com::sun::star::uno::Sequence< rtl::OUString > & rNames ) const;
+
+ // storage properties
+ rtl::OUString queryStorageTitle( const rtl::OUString & rUri ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XModel >
+ queryDocumentModel( const rtl::OUString & rUri ) const;
+
+ // interface OfficeDocumentsEventListener
+ virtual void notifyDocumentOpened( const rtl::OUString & rDocId );
+ virtual void notifyDocumentClosed( const rtl::OUString & rDocId );
+
+private:
+ rtl::Reference< OfficeDocumentsManager > m_xDocsMgr;
+ rtl::Reference< StorageElementFactory > m_xStgElemFac;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_PROVIDER_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_resultset.cxx b/ucb/source/ucp/tdoc/tdoc_resultset.cxx
new file mode 100644
index 000000000000..d8212fa028bb
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_resultset.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+
+#include "ucbhelper/resultset.hxx"
+
+#include "tdoc_datasupplier.hxx"
+#include "tdoc_resultset.hxx"
+#include "tdoc_content.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new ResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new ResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_resultset.hxx b/ucb/source/ucp/tdoc/tdoc_resultset.hxx
new file mode 100644
index 000000000000..a3e420894ade
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_resultset.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_RESULTSET_HXX
+#define INCLUDED_TDOC_RESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+
+namespace tdoc_ucp {
+
+class Content;
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand );
+};
+
+}
+
+#endif /* !INCLUDED_TDOC_RESULTSET_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_services.cxx b/ucb/source/ucp/tdoc/tdoc_services.cxx
new file mode 100644
index 000000000000..6f9641d5159b
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_services.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+
+#include "tdoc_provider.hxx"
+#include "tdoc_documentcontentfactory.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ ContentProvider::getImplementationName_Static(),
+ ContentProvider::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Document Content Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ DocumentContentFactory::getImplementationName_Static(),
+ DocumentContentFactory::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >(
+ pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( ContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = ContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Document Content Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( DocumentContentFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = DocumentContentFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.cxx b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
new file mode 100644
index 000000000000..0bd25f94d096
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
@@ -0,0 +1,1108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - remove root storage access workaround
+
+ *************************************************************************/
+
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/reflection/XProxyFactory.hpp"
+
+#include "tdoc_uri.hxx"
+
+#include "tdoc_stgelems.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ParentStorageHolder Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ParentStorageHolder::ParentStorageHolder(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri )
+: m_xParentStorage( xParentStorage ),
+ m_bParentIsRootStorage( false )
+{
+ Uri aUri( rUri );
+ if ( aUri.isDocument() )
+ m_bParentIsRootStorage = true;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Storage Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+Storage::Storage( const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< StorageElementFactory > & xFactory,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< embed::XStorage > & xStorageToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xFactory( xFactory ),
+ m_xWrappedStorage( xStorageToWrap ),
+ m_xWrappedTransObj( xStorageToWrap, uno::UNO_QUERY ), // optional interface
+ m_xWrappedComponent( xStorageToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStorageToWrap, uno::UNO_QUERY ),
+ m_bIsDocumentStorage( Uri( rUri ).isDocument() )
+{
+ OSL_ENSURE( m_xWrappedStorage.is(),
+ "Storage::Storage: No storage to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "Storage::Storage: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "Storage::Storage: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStorage );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "Storage::Storage: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "Storage::Storage: Wrapped storage cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+Storage::~Storage()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+
+ // Never dispose a document storage. Not owner!
+ if ( !isDocumentStorage() )
+ {
+ if ( m_xWrappedComponent.is() )
+ {
+ // "Auto-dispose"...
+ try
+ {
+ m_xWrappedComponent->dispose();
+ }
+ catch ( lang::DisposedException const & )
+ {
+ // might happen.
+ }
+ catch ( ... )
+ {
+ OSL_ENSURE( false, "Storage::~Storage - Caught exception!" );
+ }
+ }
+ }
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Storage::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ // First, try to use interfaces implemented by myself and base class(es)
+ uno::Any aRet = StorageUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ // Try to use requested interface from aggregated storage
+ return m_xAggProxy->queryAggregation( aType );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::acquire()
+ throw ()
+{
+ osl_incrementInterlockedCount( &m_refCount );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::release()
+ throw ()
+{
+ if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
+ {
+ m_xFactory->releaseElement( this );
+ delete this;
+ }
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Storage::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL Storage::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// lang::XComponent (base of embed::XStorage)
+//
+//=========================================================================
+// virtual
+void SAL_CALL Storage::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedStorage->dispose();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedStorage->addEventListener( xListener );
+}
+//=========================================================================
+// virtual
+void SAL_CALL Storage::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ m_xWrappedStorage->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// container::XElementAccess (base of container::XNameAccess)
+//
+//=========================================================================
+
+// virtual
+uno::Type SAL_CALL Storage::getElementType()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->getElementType();
+}
+
+//=========================================================================
+// virtual
+::sal_Bool SAL_CALL Storage::hasElements()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->hasElements();
+}
+
+//=========================================================================
+//
+// container::XNameAccess (base of embed::XStorage)
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Storage::getByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->getByName( aName );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ::rtl::OUString > SAL_CALL Storage::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->getElementNames();
+}
+
+//=========================================================================
+// virtual
+::sal_Bool SAL_CALL Storage::hasByName( const ::rtl::OUString& aName )
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->hasByName( aName );
+}
+
+//=========================================================================
+//
+// embed::XStorage
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Storage::copyToStorage(
+ const uno::Reference< embed::XStorage >& xDest )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->copyToStorage( xDest );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::openStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openStreamElement( aStreamName, nOpenMode );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::openEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode,
+ const ::rtl::OUString& aPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openEncryptedStreamElement(
+ aStreamName, nOpenMode, aPassword );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< embed::XStorage > SAL_CALL Storage::openStorageElement(
+ const ::rtl::OUString& aStorName, sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openStorageElement( aStorName, nOpenMode );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::cloneStreamElement(
+ const ::rtl::OUString& aStreamName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->cloneStreamElement( aStreamName );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::cloneEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName,
+ const ::rtl::OUString& aPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->cloneEncryptedStreamElement( aStreamName,
+ aPassword );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyLastCommitTo(
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ m_xWrappedStorage->copyLastCommitTo( xTargetStorage );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyStorageElementLastCommitTo(
+ const ::rtl::OUString& aStorName,
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ m_xWrappedStorage->copyStorageElementLastCommitTo( aStorName, xTargetStorage );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL Storage::isStreamElement(
+ const ::rtl::OUString& aElementName )
+ throw ( container::NoSuchElementException,
+ lang::IllegalArgumentException,
+ embed::InvalidStorageException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->isStreamElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL Storage::isStorageElement(
+ const ::rtl::OUString& aElementName )
+ throw ( container::NoSuchElementException,
+ lang::IllegalArgumentException,
+ embed::InvalidStorageException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->isStorageElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::removeElement( const ::rtl::OUString& aElementName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->removeElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::renameElement( const ::rtl::OUString& aEleName,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->renameElement( aEleName, aNewName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyElementTo(
+ const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->copyElementTo( aElementName, xDest, aNewName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::moveElementTo(
+ const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& rNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->moveElementTo( aElementName, xDest, rNewName );
+}
+
+//=========================================================================
+//
+// embed::XTransactedObject
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Storage::commit()
+ throw ( io::IOException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ // Never commit a root storage (-> has no parent)!
+ // Would lead in writing the whole document to disk.
+
+ uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
+ if ( xParentStorage.is() )
+ {
+ OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
+
+ if ( m_xWrappedTransObj.is() )
+ {
+ m_xWrappedTransObj->commit();
+
+ if ( !isParentARootStorage() )
+ {
+ uno::Reference< embed::XTransactedObject > xParentTA(
+ xParentStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ xParentTA->commit();
+ }
+ }
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::revert()
+ throw ( io::IOException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
+ if ( xParentStorage.is() )
+ {
+ OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
+
+ if ( m_xWrappedTransObj.is() )
+ {
+ m_xWrappedTransObj->revert();
+
+ if ( !isParentARootStorage() )
+ {
+ uno::Reference< embed::XTransactedObject > xParentTA(
+ xParentStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ xParentTA->revert();
+ }
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// OutputStream Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+OutputStream::OutputStream(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< io::XOutputStream > & xStreamToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xWrappedStream( xStreamToWrap ),
+ m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
+{
+ OSL_ENSURE( m_xWrappedStream.is(),
+ "OutputStream::OutputStream: No stream to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "OutputStream::OutputStream: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "OutputStream::OutputStream: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+OutputStream::~OutputStream()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL OutputStream::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = OutputStreamUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ if ( m_xAggProxy.is() )
+ return m_xAggProxy->queryAggregation( aType );
+ else
+ return uno::Any();
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL OutputStream::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// io::XOutputStream
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+OutputStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->writeBytes( aData );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::flush()
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->flush();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::closeOutput( )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->closeOutput();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+//
+// lang::XComponent
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+OutputStream::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->dispose();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->removeEventListener( aListener );
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Stream Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+Stream::Stream(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< io::XStream > & xStreamToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xWrappedStream( xStreamToWrap ),
+ m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
+ m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
+ m_xWrappedInputStream( xStreamToWrap->getInputStream(), uno::UNO_QUERY ),
+ m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
+{
+ OSL_ENSURE( m_xWrappedStream.is(),
+ "OutputStream::OutputStream: No stream to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "OutputStream::OutputStream: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "OutputStream::OutputStream: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+Stream::~Stream()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Stream::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = StreamUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ if ( m_xAggProxy.is() )
+ return m_xAggProxy->queryAggregation( aType );
+ else
+ return uno::Any();
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Stream::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL Stream::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// io::XStream.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< io::XInputStream > SAL_CALL Stream::getInputStream()
+ throw( uno::RuntimeException )
+{
+ return uno::Reference< io::XInputStream >( this );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XOutputStream > SAL_CALL Stream::getOutputStream()
+ throw( uno::RuntimeException )
+{
+ return uno::Reference< io::XOutputStream >( this );
+}
+
+//=========================================================================
+//
+// io::XOutputStream.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->writeBytes( aData );
+ commitChanges();
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::flush()
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->flush();
+ commitChanges();
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::closeOutput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->closeOutput();
+ commitChanges();
+ }
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+//
+// io::XTruncate.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::truncate()
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedTruncate.is() )
+ {
+ m_xWrappedTruncate->truncate();
+ commitChanges();
+ }
+}
+
+//=========================================================================
+//
+// io::XInputStream.
+//
+//=========================================================================
+
+// virtual
+sal_Int32 SAL_CALL Stream::readBytes( uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->readBytes( aData, nBytesToRead );
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL Stream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedInputStream->skipBytes( nBytesToSkip );
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL Stream::available()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->available();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::closeInput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedInputStream->closeInput();
+}
+
+//=========================================================================
+//
+// lang::XComponent
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->dispose();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// Non-UNO
+//
+//=========================================================================
+
+void Stream::commitChanges()
+ throw( io::IOException )
+{
+ uno::Reference< embed::XTransactedObject >
+ xParentTA( getParentStorage(), uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ {
+ try
+ {
+ xParentTA->commit();
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ throw io::IOException(); // @@@
+ }
+ }
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.hxx b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
new file mode 100644
index 000000000000..9afa15abf994
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
@@ -0,0 +1,542 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_STGELEMS_HXX
+#define INCLUDED_TDOC_STGELEMS_HXX
+
+#include <memory>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implbase5.hxx"
+
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XStream.hpp"
+#include "com/sun/star/io/XTruncate.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+
+#include "tdoc_storage.hxx"
+
+namespace tdoc_ucp {
+
+struct MutexHolder
+{
+ osl::Mutex m_aMutex;
+};
+
+//=======================================================================
+
+class ParentStorageHolder : public MutexHolder
+{
+public:
+ ParentStorageHolder(
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri );
+
+ bool isParentARootStorage() const
+ { return m_bParentIsRootStorage; }
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ getParentStorage() const
+ { return m_xParentStorage; }
+ void setParentStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStg )
+ { osl::MutexGuard aGuard( m_aMutex ); m_xParentStorage = xStg; }
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > m_xParentStorage;
+ bool m_bParentIsRootStorage;
+};
+
+//=======================================================================
+
+typedef
+ cppu::WeakImplHelper2<
+ com::sun::star::embed::XStorage,
+ com::sun::star::embed::XTransactedObject > StorageUNOBase;
+
+class Storage : public StorageUNOBase, public ParentStorageHolder
+{
+public:
+ Storage(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< StorageElementFactory > & xFactory,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStorageToWrap );
+ virtual ~Storage();
+
+ bool isDocumentStorage() const { return m_bIsDocumentStorage; }
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire()
+ throw ();
+ virtual void SAL_CALL release()
+ throw ();
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XComponent ( one of XStorage bases )
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > & xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XNameAccess ( one of XStorage bases )
+ virtual com::sun::star::uno::Any SAL_CALL
+ getByName( const rtl::OUString& aName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString& aName )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XElementAccess (base of XNameAccess)
+ virtual com::sun::star::uno::Type SAL_CALL
+ getElementType()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasElements()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XStorage
+ virtual void SAL_CALL
+ copyToStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ openStreamElement( const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ openEncryptedStreamElement( const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode,
+ const ::rtl::OUString& aPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::NoEncryptionException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::embed::XStorage > SAL_CALL
+ openStorageElement( const ::rtl::OUString& aStorName,
+ sal_Int32 nOpenMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ cloneStreamElement( const ::rtl::OUString& aStreamName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ cloneEncryptedStreamElement( const ::rtl::OUString& aStreamName,
+ const ::rtl::OUString& aPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::NoEncryptionException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyLastCommitTo( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xTargetStorage )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyStorageElementLastCommitTo( const ::rtl::OUString& aStorName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > &
+ xTargetStorage )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isStreamElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::embed::InvalidStorageException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isStorageElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::embed::InvalidStorageException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ renameElement( const ::rtl::OUString& aEleName,
+ const ::rtl::OUString& aNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyElementTo( const ::rtl::OUString& aElementName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ moveElementTo( const ::rtl::OUString& aElementName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& rNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTransactedObject
+ virtual void SAL_CALL commit()
+ throw ( com::sun::star::io::IOException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL revert()
+ throw ( com::sun::star::io::IOException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+private:
+ Storage( const rtl::Reference< Storage > & rFactory ); // n.i.
+
+ rtl::Reference< StorageElementFactory > m_xFactory;
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > m_xWrappedStorage;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XTransactedObject > m_xWrappedTransObj;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+ bool m_bIsDocumentStorage;
+
+ StorageElementFactory::StorageMap::iterator m_aContainerIt;
+
+ friend class StorageElementFactory;
+ friend class std::auto_ptr< Storage >;
+};
+
+//=======================================================================
+
+typedef
+ cppu::WeakImplHelper2<
+ com::sun::star::io::XOutputStream,
+ com::sun::star::lang::XComponent > OutputStreamUNOBase;
+
+class OutputStream : public OutputStreamUNOBase, public ParentStorageHolder
+{
+public:
+ OutputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & xStreamToWrap );
+ virtual ~OutputStream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XOutputStream
+ virtual void SAL_CALL
+ writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ flush( )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ closeOutput( )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XComponent
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > m_xWrappedStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+};
+
+//=======================================================================
+
+typedef cppu::WeakImplHelper5< com::sun::star::io::XStream,
+ com::sun::star::io::XOutputStream,
+ com::sun::star::io::XTruncate,
+ com::sun::star::io::XInputStream,
+ com::sun::star::lang::XComponent >
+ StreamUNOBase;
+
+class Stream : public StreamUNOBase, public ParentStorageHolder
+{
+public:
+ Stream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XStream > & xStreamToWrap );
+
+ virtual ~Stream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XStream
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getInputStream()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > SAL_CALL
+ getOutputStream()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XOutputStream
+ virtual void SAL_CALL
+ writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ flush()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeOutput()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTruncate
+ virtual void SAL_CALL
+ truncate()
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL
+ readBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ readSomeBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ skipBytes( sal_Int32 nBytesToSkip )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ available()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeInput()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XComponent
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+private:
+ void commitChanges()
+ throw( com::sun::star::io::IOException );
+
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XStream > m_xWrappedStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > m_xWrappedOutputStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XTruncate > m_xWrappedTruncate;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > m_xWrappedInputStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_STGELEMS_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_storage.cxx b/ucb/source/ucp/tdoc/tdoc_storage.cxx
new file mode 100644
index 000000000000..8deb942900a8
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_storage.cxx
@@ -0,0 +1,712 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - remove root storage access workaround
+
+ *************************************************************************/
+
+#define ROOTSTORAGE_ACCESS_WORKAROUND 1
+
+#include <memory>
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+
+#include "tdoc_uri.hxx"
+#include "tdoc_docmgr.hxx"
+#include "tdoc_stgelems.hxx"
+
+#include "tdoc_storage.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+
+//=========================================================================
+//=========================================================================
+//
+// StorageElementFactory Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+StorageElementFactory::StorageElementFactory(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< OfficeDocumentsManager > & xDocsMgr )
+: m_xDocsMgr( xDocsMgr ),
+ m_xSMgr( xSMgr )
+{
+}
+
+//=========================================================================
+StorageElementFactory::~StorageElementFactory()
+{
+ OSL_ENSURE( m_aMap.size() == 0,
+ "StorageElementFactory::~StorageElementFactory - Dangling storages!" );
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+StorageElementFactory::createTemporaryStorage()
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xStorage;
+ uno::Reference< lang::XSingleServiceFactory > xStorageFac;
+ if ( m_xSMgr.is() )
+ {
+ xStorageFac = uno::Reference< lang::XSingleServiceFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.embed.StorageFactory" ) ) ),
+ uno::UNO_QUERY );
+ }
+
+ OSL_ENSURE( xStorageFac.is(), "Can't create storage factory!" );
+ if ( xStorageFac.is() )
+ xStorage = uno::Reference< embed::XStorage >(
+ xStorageFac->createInstance(),
+ uno::UNO_QUERY );
+
+ if ( !xStorage.is() )
+ throw uno::RuntimeException();
+
+ return xStorage;
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+StorageElementFactory::createStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ( eMode != READ ) &&
+ ( eMode != READ_WRITE_NOCREATE ) &&
+ ( eMode != READ_WRITE_CREATE ) )
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid open mode!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Root never has a storage!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 1 ) );
+ }
+
+ rtl::OUString aUriKey
+ ( ( rUri.getStr()[ rUri.getLength() - 1 ] == sal_Unicode( '/' ) )
+ ? rUri.copy( 0, rUri.getLength() - 1 )
+ : rUri );
+
+ StorageMap::iterator aIt ( m_aMap.begin() );
+ StorageMap::iterator aEnd( m_aMap.end() );
+
+ while ( aIt != aEnd )
+ {
+ if ( (*aIt).first.first == aUriKey )
+ {
+ // URI matches. Now, check open mode.
+ bool bMatch = true;
+ switch ( eMode )
+ {
+ case READ:
+ // No need to check; storage is at least readable.
+ bMatch = true;
+ break;
+
+ case READ_WRITE_NOCREATE:
+ case READ_WRITE_CREATE:
+ // If found storage is writable, it can be used.
+ // If not, a new one must be created.
+ bMatch = (*aIt).first.second;
+ break;
+ }
+
+ if ( bMatch )
+ break;
+ }
+ ++aIt;
+ }
+
+ if ( aIt == aEnd )
+ {
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ // documents never have a parent storage.
+ if ( !aUri.isDocument() )
+ {
+ xParentStorage = queryParentStorage( aUriKey, eMode );
+
+ if ( !xParentStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create parent storage!" );
+ return xParentStorage;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xStorage
+ = queryStorage( xParentStorage, aUriKey, eMode );
+
+ if ( !xStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create storage!" );
+ return xStorage;
+ }
+
+ bool bWritable = ( ( eMode == READ_WRITE_NOCREATE )
+ || ( eMode == READ_WRITE_CREATE ) );
+
+ std::auto_ptr< Storage > xElement(
+ new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage ) );
+
+ aIt = m_aMap.insert(
+ StorageMap::value_type(
+ std::pair< rtl::OUString, bool >( aUriKey, bWritable ),
+ xElement.get() ) ).first;
+
+ aIt->second->m_aContainerIt = aIt;
+ xElement.release();
+ return aIt->second;
+ }
+ else if ( osl_incrementInterlockedCount( &aIt->second->m_refCount ) > 1 )
+ {
+ rtl::Reference< Storage > xElement( aIt->second );
+ osl_decrementInterlockedCount( &aIt->second->m_refCount );
+ return aIt->second;
+ }
+ else
+ {
+ osl_decrementInterlockedCount( &aIt->second->m_refCount );
+ aIt->second->m_aContainerIt = m_aMap.end();
+
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ // documents never have a parent storage.
+ if ( !aUri.isDocument() )
+ {
+ xParentStorage = queryParentStorage( aUriKey, eMode );
+
+ if ( !xParentStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create parent storage!" );
+ return xParentStorage;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xStorage
+ = queryStorage( xParentStorage, aUriKey, eMode );
+
+ if ( !xStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create storage!" );
+ return xStorage;
+ }
+
+ aIt->second
+ = new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage );
+ aIt->second->m_aContainerIt = aIt;
+ return aIt->second;
+ }
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream >
+StorageElementFactory::createInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ return uno::Reference< io::XInputStream >();
+
+ uno::Reference< io::XStream > xStream
+ = queryStream( xParentStorage, rUri, rPassword, READ, false );
+
+ if ( !xStream.is() )
+ return uno::Reference< io::XInputStream >();
+
+ return xStream->getInputStream();
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream >
+StorageElementFactory::createOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ_WRITE_CREATE );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createOutputStream - "
+ "Unable to create parent storage!" );
+ return uno::Reference< io::XOutputStream >();
+ }
+
+ uno::Reference< io::XStream > xStream
+ = queryStream(
+ xParentStorage, rUri, rPassword, READ_WRITE_CREATE, bTruncate );
+
+ if ( !xStream.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createOutputStream - "
+ "Unable to create stream!" );
+ return uno::Reference< io::XOutputStream >();
+ }
+
+ // Note: We need a wrapper to hold a reference to the parent storage to
+ // ensure that nobody else owns it at the moment we want to commit
+ // our changes. (There can be only one writable instance at a time
+ // and even no writable instance if there is already another
+ // read-only instance!)
+ return uno::Reference< io::XOutputStream >(
+ new OutputStream(
+ m_xSMgr, rUri, xParentStorage, xStream->getOutputStream() ) );
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+StorageElementFactory::createStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ_WRITE_CREATE );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createStream - "
+ "Unable to create parent storage!" );
+ return uno::Reference< io::XStream >();
+ }
+
+ uno::Reference< io::XStream > xStream
+ = queryStream(
+ xParentStorage, rUri, rPassword, READ_WRITE_NOCREATE, bTruncate );
+
+ if ( !xStream.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createStream - "
+ "Unable to create stream!" );
+ return uno::Reference< io::XStream >();
+ }
+
+ return uno::Reference< io::XStream >(
+ new Stream( m_xSMgr, rUri, xParentStorage, xStream ) );
+}
+
+//=========================================================================
+void StorageElementFactory::releaseElement( Storage * pElement ) SAL_THROW( () )
+{
+ OSL_ASSERT( pElement );
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( pElement->m_aContainerIt != m_aMap.end() )
+ m_aMap.erase( pElement->m_aContainerIt );
+}
+
+//=========================================================================
+//
+// Non-UNO interface
+//
+//=========================================================================
+
+uno::Reference< embed::XStorage > StorageElementFactory::queryParentStorage(
+ const rtl::OUString & rUri, StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ Uri aUri( rUri );
+ Uri aParentUri( aUri.getParentUri() );
+ if ( !aParentUri.isRoot() )
+ {
+ xParentStorage = createStorage( aUri.getParentUri(), eMode );
+ OSL_ENSURE( xParentStorage.is()
+ // requested to create new storage, but failed?
+ || ( eMode != READ_WRITE_CREATE ),
+ "StorageElementFactory::queryParentStorage - No storage!" );
+ }
+ return xParentStorage;
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage > StorageElementFactory::queryStorage(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xStorage;
+
+ Uri aUri( rUri );
+
+ if ( !xParentStorage.is() )
+ {
+ // document storage
+
+ xStorage = m_xDocsMgr->queryStorage( aUri.getDocumentId() );
+
+ if ( !xStorage.is() )
+ {
+ if ( eMode == READ_WRITE_CREATE )
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid open mode: document storages cannot be "
+ "created!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ else
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid document id!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ // match xStorage's open mode against requested open mode
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ xStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xPropSet.is(),
+ "StorageElementFactory::queryStorage - "
+ "No XPropertySet interface!" );
+ try
+ {
+ uno::Any aPropValue = xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) );
+
+ sal_Int32 nOpenMode = 0;
+ if ( aPropValue >>= nOpenMode )
+ {
+ switch ( eMode )
+ {
+ case READ:
+ if ( !( nOpenMode & embed::ElementModes::READ ) )
+ {
+ // document opened, but not readable.
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Storage is open, but not readable!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ // storage okay
+ break;
+
+ case READ_WRITE_NOCREATE:
+ case READ_WRITE_CREATE:
+ if ( !( nOpenMode & embed::ElementModes::WRITE ) )
+ {
+ // document opened, but not writable.
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Storage is open, but not writable!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ // storage okay
+ break;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(
+ false, "Bug! Value of property OpenMode has wrong type!" );
+
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Bug! Value of property OpenMode has wrong type!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ OSL_ENSURE( false, "Property OpenMode not supported!" );
+
+ throw embed::StorageWrappedTargetException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Bug! Value of property OpenMode has wrong type!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+
+ throw embed::StorageWrappedTargetException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "WrappedTargetException during getPropertyValue!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+ }
+ else
+ {
+ // sub storage
+
+ const rtl::OUString & rName = aUri.getDecodedName();
+
+ if ( eMode == READ )
+ {
+ try
+ {
+ sal_Int32 nOpenMode = embed::ElementModes::READ
+ | embed::ElementModes::NOCREATE;
+ xStorage
+ = xParentStorage->openStorageElement( rName, nOpenMode );
+ }
+ catch ( io::IOException const & )
+ {
+ // Another chance: Try to clone storage.
+ xStorage = createTemporaryStorage();
+ xParentStorage->copyStorageElementLastCommitTo( rName,
+ xStorage );
+ }
+ }
+ else
+ {
+ sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+ if ( eMode == READ_WRITE_NOCREATE )
+ nOpenMode |= embed::ElementModes::NOCREATE;
+
+ xStorage = xParentStorage->openStorageElement( rName, nOpenMode );
+ }
+ }
+
+ OSL_ENSURE( xStorage.is() || ( eMode != READ_WRITE_CREATE ),
+ "StorageElementFactory::queryStorage - No storage!" );
+ return xStorage;
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+StorageElementFactory::queryStream(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ StorageAccessMode eMode,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !xParentStorage.is() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No parent storage!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Root never is a stream!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+ else if ( aUri.isDocument() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "A document never is a stream!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+
+ sal_Int32 nOpenMode;
+ switch ( eMode )
+ {
+ case READ:
+ nOpenMode = embed::ElementModes::READ
+ | embed::ElementModes::NOCREATE
+ | embed::ElementModes::SEEKABLE;
+ break;
+
+ case READ_WRITE_NOCREATE:
+ nOpenMode = embed::ElementModes::READWRITE
+ | embed::ElementModes::NOCREATE
+ | embed::ElementModes::SEEKABLE;
+
+ if ( bTruncate )
+ nOpenMode |= embed::ElementModes::TRUNCATE;
+
+ break;
+
+ case READ_WRITE_CREATE:
+ nOpenMode = embed::ElementModes::READWRITE
+ | embed::ElementModes::SEEKABLE;
+
+ if ( bTruncate )
+ nOpenMode |= embed::ElementModes::TRUNCATE;
+
+ break;
+
+ default:
+ OSL_ENSURE( false,
+ "StorageElementFactory::queryStream : Unknown open mode!" );
+
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unknown open mode!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ // No object re-usage mechanism; streams are seekable => not stateless.
+
+ uno::Reference< io::XStream > xStream;
+ if ( rPassword.getLength() > 0 )
+ {
+ if ( eMode == READ )
+ {
+ try
+ {
+ xStream = xParentStorage->cloneEncryptedStreamElement(
+ aUri.getDecodedName(),
+ rPassword );
+ }
+ catch ( packages::NoEncryptionException const & )
+ {
+ xStream
+ = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
+ }
+ }
+ else
+ {
+ try
+ {
+ xStream = xParentStorage->openEncryptedStreamElement(
+ aUri.getDecodedName(),
+ nOpenMode,
+ rPassword );
+ }
+ catch ( packages::NoEncryptionException const & )
+ {
+ xStream
+ = xParentStorage->openStreamElement( aUri.getDecodedName(),
+ nOpenMode );
+ }
+ }
+ }
+ else
+ {
+ if ( eMode == READ )
+ {
+ xStream = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
+ }
+ else
+ {
+ xStream = xParentStorage->openStreamElement( aUri.getDecodedName(),
+ nOpenMode );
+ }
+ }
+
+ if ( !xStream.is() )
+ {
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No stream!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ return xStream;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_storage.hxx b/ucb/source/ucp/tdoc/tdoc_storage.hxx
new file mode 100644
index 000000000000..39a95a5a7fe8
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_storage.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_STORAGE_HXX
+#define INCLUDED_TDOC_STORAGE_HXX
+
+#include <map>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "com/sun/star/embed/XStorage.hpp"
+
+namespace tdoc_ucp {
+
+ enum StorageAccessMode
+ {
+ READ, // Note: might be writable as well
+ READ_WRITE_NOCREATE,
+ READ_WRITE_CREATE
+ };
+
+ class Storage;
+ class OfficeDocumentsManager;
+
+ class StorageElementFactory : public salhelper::SimpleReferenceObject
+ {
+ public:
+ StorageElementFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< OfficeDocumentsManager > & xDocsMgr );
+ ~StorageElementFactory();
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ createTemporaryStorage()
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ createStorage( const rtl::OUString & rUri, StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ createInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >
+ createOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ createStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ private:
+ friend class Storage;
+
+ void releaseElement( Storage * pElement ) SAL_THROW(());
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryParentStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ queryStream( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rPassword,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode,
+ bool bTruncate /* ignored for read-only streams */ )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ struct ltstrbool
+ {
+ bool operator()(
+ const std::pair< rtl::OUString, bool > & s1,
+ const std::pair< rtl::OUString, bool > & s2 ) const
+ {
+ if ( s1.first < s2.first )
+ return true;
+ else if ( s1.first == s2.first )
+ return ( !s1.second && s2.second );
+ else
+ return false;
+ }
+ };
+
+ // key: pair< storageuri, iswritable >
+ typedef std::map<
+ std::pair< rtl::OUString, bool >, Storage *, ltstrbool > StorageMap;
+
+ StorageMap m_aMap;
+ osl::Mutex m_aMutex;
+ rtl::Reference< OfficeDocumentsManager > m_xDocsMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_STORAGE_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_uri.cxx b/ucb/source/ucp/tdoc/tdoc_uri.cxx
new file mode 100644
index 000000000000..712ced2d04f1
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_uri.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+#include "../inc/urihelper.hxx"
+
+#include "tdoc_uri.hxx"
+
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// Uri Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+void Uri::init() const
+{
+ // Already inited?
+ if ( m_eState == UNKNOWN )
+ {
+ m_eState = INVALID;
+
+ // Check for proper length: must be at least length of <sheme>:/
+ if ( ( m_aUri.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
+ {
+ // Invaild length (to short).
+ return;
+ }
+
+ // Check for proper scheme. (Scheme is case insensitive.)
+ rtl::OUString aScheme
+ = m_aUri.copy( 0, TDOC_URL_SCHEME_LENGTH ).toAsciiLowerCase();
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_URL_SCHEME ) ) )
+ {
+ // Invaild scheme.
+ return;
+ }
+
+ // Remember normalized scheme string.
+ m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme );
+
+ if ( m_aUri.getStr()[ TDOC_URL_SCHEME_LENGTH ]
+ != sal_Unicode( ':' ) )
+ {
+ // Invaild (no ':' after <scheme>).
+ return;
+ }
+
+ if ( m_aUri.getStr()[ TDOC_URL_SCHEME_LENGTH + 1 ]
+ != sal_Unicode( '/' ) )
+ {
+ // Invaild (no '/' after <scheme>:).
+ return;
+ }
+
+ m_aPath = m_aUri.copy( TDOC_URL_SCHEME_LENGTH + 1 );
+
+ // Note: There must be at least one slash; see above.
+ sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' );
+ bool bTrailingSlash = false;
+ if ( nLastSlash == m_aUri.getLength() - 1 )
+ {
+ // ignore trailing slash
+ bTrailingSlash = true;
+ nLastSlash = m_aUri.lastIndexOf( '/', nLastSlash );
+ }
+
+ if ( nLastSlash != -1 ) // -1 is valid for the root folder
+ {
+ m_aParentUri = m_aUri.copy( 0, nLastSlash + 1 );
+
+ if ( bTrailingSlash )
+ m_aName = m_aUri.copy( nLastSlash + 1,
+ m_aUri.getLength() - nLastSlash - 2 );
+ else
+ m_aName = m_aUri.copy( nLastSlash + 1 );
+
+ m_aDecodedName = ::ucb_impl::urihelper::decodeSegment( m_aName );
+
+ sal_Int32 nSlash = m_aPath.indexOf( '/', 1 );
+ if ( nSlash == -1 )
+ m_aDocId = m_aPath.copy( 1 );
+ else
+ m_aDocId = m_aPath.copy( 1, nSlash - 1 );
+ }
+
+ if ( m_aDocId.getLength() > 0 )
+ {
+ sal_Int32 nSlash = m_aPath.indexOf( '/', 1 );
+ if ( nSlash != - 1 )
+ m_aInternalPath = m_aPath.copy( nSlash );
+ else
+ m_aInternalPath = rtl::OUString::createFromAscii( "/" );
+ }
+
+ m_eState = VALID;
+ }
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_uri.hxx b/ucb/source/ucp/tdoc/tdoc_uri.hxx
new file mode 100644
index 000000000000..5f251cc55bee
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_uri.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_URI_HXX
+#define INCLUDED_TDOC_URI_HXX
+
+#include "rtl/ustring.hxx"
+
+namespace tdoc_ucp {
+
+//=========================================================================
+
+#define TDOC_URL_SCHEME "vnd.sun.star.tdoc"
+#define TDOC_URL_SCHEME_LENGTH 17
+
+//=========================================================================
+
+class Uri
+{
+ enum State { UNKNOWN, INVALID, VALID };
+
+ mutable ::rtl::OUString m_aUri;
+ mutable ::rtl::OUString m_aParentUri;
+ mutable ::rtl::OUString m_aPath;
+ mutable ::rtl::OUString m_aDocId;
+ mutable ::rtl::OUString m_aInternalPath;
+ mutable ::rtl::OUString m_aName;
+ mutable ::rtl::OUString m_aDecodedName;
+ mutable State m_eState;
+
+private:
+ void init() const;
+
+public:
+ Uri() : m_eState( UNKNOWN ) {}
+ Uri( const ::rtl::OUString & rUri )
+ : m_aUri( rUri ), m_eState( UNKNOWN ) {}
+
+ bool operator== ( const Uri & rOther ) const
+ { init(); return m_aUri == rOther.m_aUri; }
+
+ bool operator!= ( const Uri & rOther ) const
+ { return !operator==( rOther ); }
+
+ sal_Bool isValid() const
+ { init(); return m_eState == VALID; }
+
+ const ::rtl::OUString & getUri() const
+ { init(); return m_aUri; }
+
+ inline void setUri( const ::rtl::OUString & rUri );
+
+ const ::rtl::OUString & getParentUri() const
+ { init(); return m_aParentUri; }
+
+ const ::rtl::OUString & getPath() const
+ { init(); return m_aPath; }
+
+ const ::rtl::OUString & getDocumentId() const
+ { init(); return m_aDocId; }
+
+ const ::rtl::OUString & getInternalPath() const
+ { init(); return m_aInternalPath; }
+
+ const ::rtl::OUString & getName() const
+ { init(); return m_aName; }
+
+ const ::rtl::OUString & getDecodedName() const
+ { init(); return m_aDecodedName; }
+
+ inline sal_Bool isRoot() const;
+
+ inline sal_Bool isDocument() const;
+
+ inline sal_Bool isFolder() const;
+};
+
+inline void Uri::setUri( const ::rtl::OUString & rUri )
+{
+ m_eState = UNKNOWN;
+ m_aUri = rUri;
+ m_aParentUri = m_aDocId = m_aInternalPath = m_aPath = m_aName
+ = m_aDecodedName = rtl::OUString();
+}
+
+inline sal_Bool Uri::isRoot() const
+{
+ init();
+ return ( m_aPath.getLength() == 1 );
+}
+
+inline sal_Bool Uri::isDocument() const
+{
+ init();
+ return ( ( m_aDocId.getLength() > 0 ) /* not root */
+ && ( m_aPath.copy( m_aDocId.getLength() + 1 ).getLength() < 2 ) );
+}
+
+inline sal_Bool Uri::isFolder() const
+{
+ init();
+ return ( m_aPath.lastIndexOf( '/' ) == m_aPath.getLength() - 1 );
+}
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_URI_HXX */
diff --git a/ucb/source/ucp/tdoc/ucptdoc.xml b/ucb/source/ucp/tdoc/ucptdoc.xml
new file mode 100644
index 000000000000..b47249269470
--- /dev/null
+++ b/ucb/source/ucp/tdoc/ucptdoc.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucptdoc
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.TransientDocumentsContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal Content Broker.
+ It provides access to the hierachical structure of the documents that are active
+ in a running OpenOffice.org process.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.TransientDocumentsContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.frame.GlobalEventBroadcaster
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.reflection.ProxyFactory
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.embed.StorageFactory
+ </service-dependency>
+ </component-description>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.TransientDocumentsDocumentContentFactory
+ </name>
+ <description>
+ This component implements a factory for
+ 'com.sun.star.ucb.TransientDocumentsDocumentContent's.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.frame.TransientDocumentsDocumentContentFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.TransientDocumentsContentProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.Property </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.document.XStorageBasedDocument </type>
+ <type> com.sun.star.document.XEventBroadcaster </type>
+ <type> com.sun.star.document.XEventListener </type>
+ <type> com.sun.star.embed.ElementModes </type>
+ <type> com.sun.star.embed.XStorage </type>
+ <type> com.sun.star.embed.XTransactedObject </type>
+ <type> com.sun.star.frame.XTransientDocumentsDocumentContentFactory </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XActiveDataStreamer </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.io.XTruncate </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.reflection.XProxyFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.task.DocumentPasswordRequest </type>
+ <type> com.sun.star.task.XInteractionPassword </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.CommandInfo </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsupportedCommandException </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XAggregation </type>
+
+</module-description>
diff --git a/ucb/source/ucp/webdav/ContentProperties.cxx b/ucb/source/ucp/webdav/ContentProperties.cxx
new file mode 100644
index 000000000000..2285ad28a888
--- /dev/null
+++ b/ucb/source/ucp/webdav/ContentProperties.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <com/sun/star/util/DateTime.hpp>
+#include "NeonUri.hxx"
+#include "DAVResource.hxx"
+#include "DAVProperties.hxx"
+#include "DateTimeHelper.hxx"
+#include "webdavprovider.hxx"
+#include "ContentProperties.hxx"
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+/*
+=============================================================================
+
+ Property Mapping
+
+=============================================================================
+HTTP (entity header) WebDAV (property) UCB (property)
+=============================================================================
+
+Allow
+Content-Encoding
+Content-Language getcontentlanguage
+Content-Length getcontentlength Size
+Content-Location
+Content-MD5
+Content-Range
+Content-Type getcontenttype MediaType
+Expires
+Last-Modified getlastmodified DateModified
+ creationdate DateCreated
+ resourcetype IsFolder,IsDocument,ContentType
+ displayname
+ETag (actually getetag
+a response header )
+ lockdiscovery
+ supportedlock
+ source
+ Title (always taken from URI)
+
+=============================================================================
+
+Important: HTTP headers will not be mapped to DAV properties; only to UCB
+ properties. (Content-Length,Content-Type,Last-Modified)
+*/
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static member!
+uno::Any ContentProperties::m_aEmptyAny;
+
+ContentProperties::ContentProperties( const DAVResource& rResource )
+: m_xProps( new PropertyValueMap ),
+ m_bTrailingSlash( false )
+{
+ OSL_ENSURE( rResource.uri.getLength(),
+ "ContentProperties ctor - Empty resource URI!" );
+
+ // Title
+ try
+ {
+ NeonUri aURI( rResource.uri );
+ m_aEscapedTitle = aURI.GetPathBaseName();
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Title" ) ]
+ = PropertyValue(
+ uno::makeAny( aURI.GetPathBaseNameUnescaped() ), true );
+ }
+ catch ( DAVException const & )
+ {
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Title" ) ]
+ = PropertyValue(
+ uno::makeAny(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "*** unknown ***" ) ) ),
+ true );
+ }
+
+ std::vector< DAVPropertyValue >::const_iterator it
+ = rResource.properties.begin();
+ std::vector< DAVPropertyValue >::const_iterator end
+ = rResource.properties.end();
+
+ while ( it != end )
+ {
+ addProperty( (*it) );
+ ++it;
+ }
+
+ if ( rResource.uri.getStr()[ rResource.uri.getLength() - 1 ]
+ == sal_Unicode( '/' ) )
+ m_bTrailingSlash = sal_True;
+}
+
+//=========================================================================
+ContentProperties::ContentProperties(
+ const rtl::OUString & rTitle, sal_Bool bFolder )
+: m_xProps( new PropertyValueMap ),
+ m_bTrailingSlash( sal_False )
+{
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Title" ) ]
+ = PropertyValue( uno::makeAny( rTitle ), true );
+ (*m_xProps)[ rtl::OUString::createFromAscii( "IsFolder" ) ]
+ = PropertyValue( uno::makeAny( bFolder ), true );
+ (*m_xProps)[ rtl::OUString::createFromAscii( "IsDocument" ) ]
+ = PropertyValue( uno::makeAny( sal_Bool( !bFolder ) ), true );
+}
+
+//=========================================================================
+ContentProperties::ContentProperties( const rtl::OUString & rTitle )
+: m_xProps( new PropertyValueMap ),
+ m_bTrailingSlash( sal_False )
+{
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Title" ) ]
+ = PropertyValue( uno::makeAny( rTitle ), true );
+}
+
+//=========================================================================
+ContentProperties::ContentProperties( const ContentProperties & rOther )
+: m_aEscapedTitle( rOther.m_aEscapedTitle ),
+ m_xProps( rOther.m_xProps.get()
+ ? new PropertyValueMap( *rOther.m_xProps )
+ : new PropertyValueMap ),
+ m_bTrailingSlash( rOther.m_bTrailingSlash )
+{
+}
+
+//=========================================================================
+bool ContentProperties::contains( const rtl::OUString & rName ) const
+{
+ if ( get( rName ) )
+ return true;
+ else
+ return false;
+}
+
+//=========================================================================
+const uno::Any & ContentProperties::getValue(
+ const rtl::OUString & rName ) const
+{
+ const PropertyValue * pProp = get( rName );
+ if ( pProp )
+ return pProp->value();
+ else
+ return m_aEmptyAny;
+}
+
+//=========================================================================
+const PropertyValue * ContentProperties::get(
+ const rtl::OUString & rName ) const
+{
+ PropertyValueMap::const_iterator it = m_xProps->find( rName );
+ const PropertyValueMap::const_iterator end = m_xProps->end();
+
+ if ( it == end )
+ {
+ it = m_xProps->begin();
+ while ( it != end )
+ {
+ if ( (*it).first.equalsIgnoreAsciiCase( rName ) )
+ return &(*it).second;
+
+ ++it;
+ }
+ return 0;
+ }
+ else
+ return &(*it).second;
+}
+
+//=========================================================================
+// static
+void ContentProperties::UCBNamesToDAVNames(
+ const uno::Sequence< beans::Property > & rProps,
+ std::vector< rtl::OUString > & propertyNames,
+ bool bIncludeUnmatched /* = true */ )
+{
+ //////////////////////////////////////////////////////////////
+ // Assemble list of DAV properties to obtain from server.
+ // Append DAV properties needed to obtain requested UCB props.
+ //////////////////////////////////////////////////////////////
+
+ // DAV UCB
+ // creationdate <- DateCreated
+ // getlastmodified <- DateModified
+ // getcontenttype <- MediaType
+ // getcontentlength <- Size
+ // resourcetype <- IsFolder, IsDocument, ContentType
+ // (taken from URI) <- Title
+
+ sal_Bool bCreationDate = sal_False;
+ sal_Bool bLastModified = sal_False;
+ sal_Bool bContentType = sal_False;
+ sal_Bool bContentLength = sal_False;
+ sal_Bool bResourceType = sal_False;
+
+ sal_Int32 nCount = rProps.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property & rProp = rProps[ n ];
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ // Title is always obtained from resource's URI.
+ continue;
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) )
+ ||
+ ( rProp.Name == DAVProperties::CREATIONDATE ) )
+ {
+ if ( !bCreationDate )
+ {
+ propertyNames.push_back( DAVProperties::CREATIONDATE );
+ bCreationDate = sal_True;
+ }
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateModified" ) )
+ ||
+ ( rProp.Name == DAVProperties::GETLASTMODIFIED ) )
+ {
+ if ( !bLastModified )
+ {
+ propertyNames.push_back(
+ DAVProperties::GETLASTMODIFIED );
+ bLastModified = sal_True;
+ }
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) )
+ ||
+ ( rProp.Name == DAVProperties::GETCONTENTTYPE ) )
+ {
+ if ( !bContentType )
+ {
+ propertyNames.push_back(
+ DAVProperties::GETCONTENTTYPE );
+ bContentType = sal_True;
+ }
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Size" ) )
+ ||
+ ( rProp.Name == DAVProperties::GETCONTENTLENGTH ) )
+ {
+ if ( !bContentLength )
+ {
+ propertyNames.push_back(
+ DAVProperties::GETCONTENTLENGTH );
+ bContentLength = sal_True;
+ }
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) )
+ ||
+ rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) )
+ ||
+ rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) )
+ ||
+ ( rProp.Name == DAVProperties::RESOURCETYPE ) )
+ {
+ if ( !bResourceType )
+ {
+ propertyNames.push_back( DAVProperties::RESOURCETYPE );
+ bResourceType = sal_True;
+ }
+ }
+ else
+ {
+ if ( bIncludeUnmatched )
+ propertyNames.push_back( rProp.Name );
+ }
+ }
+}
+
+//=========================================================================
+// static
+void ContentProperties::UCBNamesToHTTPNames(
+ const uno::Sequence< beans::Property > & rProps,
+ std::vector< rtl::OUString > & propertyNames,
+ bool bIncludeUnmatched /* = true */ )
+{
+ //////////////////////////////////////////////////////////////
+ // Assemble list of HTTP header names to obtain from server.
+ // Append HTTP headers needed to obtain requested UCB props.
+ //////////////////////////////////////////////////////////////
+
+ // HTTP UCB
+ // Last-Modified <- DateModified
+ // Content-Type <- MediaType
+ // Content-Length <- Size
+
+ sal_Int32 nCount = rProps.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property & rProp = rProps[ n ];
+
+ if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
+ {
+ propertyNames.push_back(
+ rtl::OUString::createFromAscii( "Last-Modified" ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ propertyNames.push_back(
+ rtl::OUString::createFromAscii( "Content-Type" ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ propertyNames.push_back(
+ rtl::OUString::createFromAscii( "Content-Length" ) );
+ }
+ else
+ {
+ if ( bIncludeUnmatched )
+ propertyNames.push_back( rProp.Name );
+ }
+ }
+}
+
+//=========================================================================
+bool ContentProperties::containsAllNames(
+ const uno::Sequence< beans::Property >& rProps,
+ std::vector< rtl::OUString > & rNamesNotContained ) const
+{
+ rNamesNotContained.clear();
+
+ sal_Int32 nCount = rProps.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const rtl::OUString & rName = rProps[ n ].Name;
+ if ( !contains( rName ) )
+ {
+ // Not found.
+ rNamesNotContained.push_back( rName );
+ }
+ }
+
+ return ( rNamesNotContained.size() == 0 );
+}
+
+//=========================================================================
+void ContentProperties::addProperties(
+ const std::vector< rtl::OUString > & rProps,
+ const ContentProperties & rContentProps )
+{
+ std::vector< rtl::OUString >::const_iterator it = rProps.begin();
+ std::vector< rtl::OUString >::const_iterator end = rProps.end();
+
+ while ( it != end )
+ {
+ const rtl::OUString & rName = (*it);
+
+ if ( !contains( rName ) ) // ignore duplicates
+ {
+ const PropertyValue * pProp = rContentProps.get( rName );
+ if ( pProp )
+ {
+ // Add it.
+ addProperty( rName, pProp->value(), pProp->isCaseSensitive() );
+ }
+ else
+ {
+ addProperty( rName, uno::Any(), false );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+void ContentProperties::addProperties( const ContentProperties & rProps )
+{
+ PropertyValueMap::const_iterator it = rProps.m_xProps->begin();
+ const PropertyValueMap::const_iterator end = rProps.m_xProps->end();
+
+ while ( it != end )
+ {
+ addProperty(
+ (*it).first, (*it).second.value(), (*it).second.isCaseSensitive() );
+ ++it;
+ }
+}
+
+//=========================================================================
+void ContentProperties::addProperties(
+ const std::vector< DAVPropertyValue > & rProps )
+{
+ std::vector< DAVPropertyValue >::const_iterator it = rProps.begin();
+ std::vector< DAVPropertyValue >::const_iterator end = rProps.end();
+
+ while ( it != end )
+ {
+ addProperty( (*it) );
+ ++it;
+ }
+}
+
+//=========================================================================
+void ContentProperties::addProperty( const DAVPropertyValue & rProp )
+{
+ addProperty( rProp.Name, rProp.Value, rProp.IsCaseSensitive );
+}
+
+//=========================================================================
+void ContentProperties::addProperty( const rtl::OUString & rName,
+ const com::sun::star::uno::Any & rValue,
+ bool bIsCaseSensitive )
+{
+ if ( rName.equals( DAVProperties::CREATIONDATE ) )
+ {
+ // Map DAV:creationdate to UCP:DateCreated
+ rtl::OUString aValue;
+ rValue >>= aValue;
+ util::DateTime aDate;
+ DateTimeHelper::convert( aValue, aDate );
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "DateCreated" ) ]
+ = PropertyValue( uno::makeAny( aDate ), true );
+ }
+ // else if ( rName.equals( DAVProperties::DISPLAYNAME ) )
+ // {
+ // }
+ // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) )
+ // {
+ // }
+ else if ( rName.equals( DAVProperties::GETCONTENTLENGTH ) )
+ {
+ // Map DAV:getcontentlength to UCP:Size
+ rtl::OUString aValue;
+ rValue >>= aValue;
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Size" ) ]
+ = PropertyValue( uno::makeAny( aValue.toInt64() ), true );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Content-Length" ) ) )
+ {
+ // Do NOT map Content-Lenght entity header to DAV:getcontentlength!
+ // Only DAV resources have this property.
+
+ // Map Content-Length entity header to UCP:Size
+ rtl::OUString aValue;
+ rValue >>= aValue;
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "Size" ) ]
+ = PropertyValue( uno::makeAny( aValue.toInt64() ), true );
+ }
+ else if ( rName.equals( DAVProperties::GETCONTENTTYPE ) )
+ {
+ // Map DAV:getcontenttype to UCP:MediaType (1:1)
+ (*m_xProps)[ rtl::OUString::createFromAscii( "MediaType" ) ]
+ = PropertyValue( rValue, true );
+ }
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Type" ) ) )
+ {
+ // Do NOT map Content-Type entity header to DAV:getcontenttype!
+ // Only DAV resources have this property.
+
+ // Map DAV:getcontenttype to UCP:MediaType (1:1)
+ (*m_xProps)[ rtl::OUString::createFromAscii( "MediaType" ) ]
+ = PropertyValue( rValue, true );
+ }
+ // else if ( rName.equals( DAVProperties::GETETAG ) )
+ // {
+ // }
+ else if ( rName.equals( DAVProperties::GETLASTMODIFIED ) )
+ {
+ // Map the DAV:getlastmodified entity header to UCP:DateModified
+ rtl::OUString aValue;
+ rValue >>= aValue;
+ util::DateTime aDate;
+ DateTimeHelper::convert( aValue, aDate );
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "DateModified" ) ]
+ = PropertyValue( uno::makeAny( aDate ), true );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Last-Modified" ) ) )
+ {
+ // Do not map Last-Modified entity header to DAV:getlastmodified!
+ // Only DAV resources have this property.
+
+ // Map the Last-Modified entity header to UCP:DateModified
+ rtl::OUString aValue;
+ rValue >>= aValue;
+ util::DateTime aDate;
+ DateTimeHelper::convert( aValue, aDate );
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "DateModified" ) ]
+ = PropertyValue( uno::makeAny( aDate ), true );
+ }
+ // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) )
+ // {
+ // }
+ else if ( rName.equals( DAVProperties::RESOURCETYPE ) )
+ {
+ rtl::OUString aValue;
+ rValue >>= aValue;
+
+ // Map DAV:resourceype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType
+ sal_Bool bFolder =
+ aValue.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "collection" ) );
+
+ (*m_xProps)[ rtl::OUString::createFromAscii( "IsFolder" ) ]
+ = PropertyValue( uno::makeAny( bFolder ), true );
+ (*m_xProps)[ rtl::OUString::createFromAscii( "IsDocument" ) ]
+ = PropertyValue( uno::makeAny( sal_Bool( !bFolder ) ), true );
+ (*m_xProps)[ rtl::OUString::createFromAscii( "ContentType" ) ]
+ = PropertyValue( uno::makeAny( bFolder
+ ? rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE )
+ : rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE ) ), true );
+ }
+ // else if ( rName.equals( DAVProperties::SOURCE ) )
+ // {
+ // }
+ // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) )
+ // {
+ // }
+
+ // Save property.
+ (*m_xProps)[ rName ] = PropertyValue( rValue, bIsCaseSensitive );
+}
diff --git a/ucb/source/ucp/webdav/ContentProperties.hxx b/ucb/source/ucp/webdav/ContentProperties.hxx
new file mode 100644
index 000000000000..7819698bf667
--- /dev/null
+++ b/ucb/source/ucp/webdav/ContentProperties.hxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_CONTENTPROPERTIES_HXX
+#define _WEBDAV_UCP_CONTENTPROPERTIES_HXX
+
+#include <memory>
+#include <vector>
+#include <hash_map>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+} } } }
+
+namespace webdav_ucp
+{
+
+struct DAVResource;
+
+//=========================================================================
+
+struct equalString
+{
+ bool operator()( const rtl::OUString& s1, const rtl::OUString& s2 ) const
+ {
+ return !!( s1 == s2 );
+ }
+};
+
+struct hashString
+{
+ size_t operator()( const rtl::OUString & rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+//=========================================================================
+//
+// PropertyValueMap.
+//
+//=========================================================================
+
+class PropertyValue
+{
+private:
+ ::com::sun::star::uno::Any m_aValue;
+ bool m_bIsCaseSensitive;
+
+public:
+ PropertyValue()
+ : m_bIsCaseSensitive( true ) {}
+
+ PropertyValue( const ::com::sun::star::uno::Any & rValue,
+ bool bIsCaseSensitive )
+ : m_aValue( rValue),
+ m_bIsCaseSensitive( bIsCaseSensitive ) {}
+
+ bool isCaseSensitive() const { return m_bIsCaseSensitive; }
+ const ::com::sun::star::uno::Any & value() const { return m_aValue; }
+
+};
+
+typedef std::hash_map
+<
+ rtl::OUString,
+ PropertyValue,
+ hashString,
+ equalString
+>
+PropertyValueMap;
+
+struct DAVResource;
+
+class ContentProperties
+{
+public:
+ ContentProperties( const DAVResource& rResource );
+
+ // Mini props for transient contents.
+ ContentProperties( const rtl::OUString & rTitle, sal_Bool bFolder );
+
+ // Micro props for non-existing contents.
+ ContentProperties( const rtl::OUString & rTitle );
+
+ ContentProperties( const ContentProperties & rOther );
+
+ bool contains( const rtl::OUString & rName ) const;
+
+ const com::sun::star::uno::Any &
+ getValue( const rtl::OUString & rName ) const;
+
+ // Maps the UCB property names contained in rProps with their DAV property
+ // counterparts, if possible. All unmappable properties will be included
+ // unchanged in resulting vector unless bIncludeUnmatched is set to false.
+ // The vector filles by this method can directly be handed over to
+ // DAVResourceAccess::PROPFIND. The result from PROPFIND
+ // (vector< DAVResource >) can be used to create a ContentProperties
+ // instance which can map DAV properties back to UCB properties.
+ static void UCBNamesToDAVNames( const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property > &
+ rProps,
+ std::vector< rtl::OUString > & resources,
+ bool bIncludeUnmatched = true );
+
+ // Maps the UCB property names contained in rProps with their HTTP header
+ // counterparts, if possible. All unmappable properties will be included
+ // unchanged in resulting vector unless bIncludeUnmatched is set to false.
+ // The vector filles by this method can directly be handed over to
+ // DAVResourceAccess::HEAD. The result from HEAD (vector< DAVResource >)
+ // can be used to create a ContentProperties instance which can map header
+ // names back to UCB properties.
+ static void UCBNamesToHTTPNames( const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property > &
+ rProps,
+ std::vector< rtl::OUString > & resources,
+ bool bIncludeUnmatched = true );
+
+ // return true, if all properties contained in rProps are contained in
+ // this ContentProperties instance. Otherwiese, false will be returned.
+ // rNamesNotContained contain the missing names.
+ bool containsAllNames(
+ const com::sun::star::uno::Sequence<
+ com::sun::star::beans::Property >& rProps,
+ std::vector< rtl::OUString > & rNamesNotContained ) const;
+
+ // adds all properties described by rProps that are actually contained in
+ // rContentProps to this instance. In case of duplicates the value
+ // already contained in this will left unchanged.
+ void addProperties( const std::vector< rtl::OUString > & rProps,
+ const ContentProperties & rContentProps );
+
+ // overwrites probably existing entries.
+ void addProperties( const ContentProperties & rProps );
+
+ // overwrites probably existing entries.
+ void addProperties( const std::vector< DAVPropertyValue > & rProps );
+
+ // overwrites probably existing entry.
+ void addProperty( const rtl::OUString & rName,
+ const com::sun::star::uno::Any & rValue,
+ bool bIsCaseSensitive );
+
+ // overwrites probably existing entry.
+ void addProperty( const DAVPropertyValue & rProp );
+
+ bool isTrailingSlash() const { return m_bTrailingSlash; }
+
+ const rtl::OUString & getEscapedTitle() const { return m_aEscapedTitle; }
+
+ // Not good to expose implementation details, but this is actually an
+ // internal class.
+ const std::auto_ptr< PropertyValueMap > & getProperties() const
+ { return m_xProps; }
+
+private:
+ ::rtl::OUString m_aEscapedTitle; // escaped Title
+ std::auto_ptr< PropertyValueMap > m_xProps;
+ bool m_bTrailingSlash;
+
+ static com::sun::star::uno::Any m_aEmptyAny;
+
+ ContentProperties & operator=( const ContentProperties & ); // n.i.
+
+ const PropertyValue * get( const rtl::OUString & rName ) const;
+};
+
+}
+
+#endif /* !_WEBDAV_UCP_CONTENTPROPERTIES_HXX */
diff --git a/ucb/source/ucp/webdav/DAVAuthListener.hxx b/ucb/source/ucp/webdav/DAVAuthListener.hxx
new file mode 100644
index 000000000000..c092f9fd311f
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVAuthListener.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DAVAUTHLISTENER_HXX_
+#define _DAVAUTHLISTENER_HXX_
+
+#include <salhelper/simplereferenceobject.hxx>
+#include <rtl/ustring.hxx>
+
+#ifndef _COM_SUN_STAR_UCB_XREFERENCE_HPP_
+#include <com/sun/star/uno/XReference.hpp>
+#endif
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+
+namespace webdav_ucp
+{
+
+class DAVAuthListener : public salhelper::SimpleReferenceObject
+{
+ public:
+ virtual int authenticate(
+ const ::rtl::OUString & inRealm,
+ const ::rtl::OUString & inHostName,
+ ::rtl::OUString & inoutUserName,
+ ::rtl::OUString & outPassWord,
+ sal_Bool bAllowPersistentStoring,
+ sal_Bool bCanUseSystemCredentials ) = 0;
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVAUTHLISTENER_HXX_
diff --git a/ucb/source/ucp/webdav/DAVAuthListenerImpl.hxx b/ucb/source/ucp/webdav/DAVAuthListenerImpl.hxx
new file mode 100644
index 000000000000..3d03cc63952b
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVAuthListenerImpl.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVAUTHLISTENERIMPL_HXX_
+#define _DAVAUTHLISTENERIMPL_HXX_
+
+#include "DAVAuthListener.hxx"
+
+
+namespace webdav_ucp
+{
+
+//=========================================================================
+
+//=========================================================================
+//=========================================================================
+//
+// class DAVAuthListenerImpl.
+//
+//=========================================================================
+//=========================================================================
+
+
+ class DAVAuthListener_Impl : public DAVAuthListener
+ {
+ public:
+
+ DAVAuthListener_Impl(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment>& xEnv,
+ const ::rtl::OUString & inURL )
+ : m_xEnv( xEnv ), m_aURL( inURL )
+ {
+ }
+
+ virtual int authenticate( const ::rtl::OUString & inRealm,
+ const ::rtl::OUString & inHostName,
+ ::rtl::OUString & inoutUserName,
+ ::rtl::OUString & outPassWord,
+ sal_Bool bAllowPersistentStoring,
+ sal_Bool bCanUseSystemCredentials );
+ private:
+
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+ const rtl::OUString m_aURL;
+
+ rtl::OUString m_aPrevPassword;
+ rtl::OUString m_aPrevUsername;
+ };
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/DAVException.hxx b/ucb/source/ucp/webdav/DAVException.hxx
new file mode 100644
index 000000000000..c981eb404676
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVException.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVEXCEPTION_HXX_
+#define _DAVEXCEPTION_HXX_
+
+#include <rtl/ustring.hxx>
+
+namespace webdav_ucp
+{
+
+/////////////////////////////////////////////////////////////////////////////
+// HTTP/WebDAV status codes
+/////////////////////////////////////////////////////////////////////////////
+
+const sal_uInt16 SC_NONE = 0;
+
+// 1xx (Informational - no errors)
+const sal_uInt16 SC_CONTINUE = 100;
+const sal_uInt16 SC_SWITCHING_PROTOCOLS = 101;
+// DAV extensions
+const sal_uInt16 SC_PROCESSING = 102;
+
+//2xx (Successful - no errors)
+const sal_uInt16 SC_OK = 200;
+const sal_uInt16 SC_CREATED = 201;
+const sal_uInt16 SC_ACCEPTED = 202;
+const sal_uInt16 SC_NON_AUTHORITATIVE_INFORMATION = 203;
+const sal_uInt16 SC_NO_CONTENT = 204;
+const sal_uInt16 SC_RESET_CONTENT = 205;
+const sal_uInt16 SC_PARTIAL_CONTENT = 206;
+// DAV extensions
+const sal_uInt16 SC_MULTISTATUS = 207;
+
+//3xx (Redirection)
+const sal_uInt16 SC_MULTIPLE_CHOICES = 300;
+const sal_uInt16 SC_MOVED_PERMANENTLY = 301;
+const sal_uInt16 SC_MOVED_TEMPORARILY = 302;
+const sal_uInt16 SC_SEE_OTHER = 303;
+const sal_uInt16 SC_NOT_MODIFIED = 304;
+const sal_uInt16 SC_USE_PROXY = 305;
+const sal_uInt16 SC_TEMPORARY_REDIRECT = 307;
+
+//4xx (Client error)
+const sal_uInt16 SC_BAD_REQUEST = 400;
+const sal_uInt16 SC_UNAUTHORIZED = 401;
+const sal_uInt16 SC_PAYMENT_REQUIRED = 402;
+const sal_uInt16 SC_FORBIDDEN = 403;
+const sal_uInt16 SC_NOT_FOUND = 404;
+const sal_uInt16 SC_METHOD_NOT_ALLOWED = 405;
+const sal_uInt16 SC_NOT_ACCEPTABLE = 406;
+const sal_uInt16 SC_PROXY_AUTHENTICATION_REQUIRED = 407;
+const sal_uInt16 SC_REQUEST_TIMEOUT = 408;
+const sal_uInt16 SC_CONFLICT = 409;
+const sal_uInt16 SC_GONE = 410;
+const sal_uInt16 SC_LENGTH_REQUIRED = 411;
+const sal_uInt16 SC_PRECONDITION_FAILED = 412;
+const sal_uInt16 SC_REQUEST_ENTITY_TOO_LARGE = 413;
+const sal_uInt16 SC_REQUEST_URI_TOO_LONG = 414;
+const sal_uInt16 SC_UNSUPPORTED_MEDIA_TYPE = 415;
+const sal_uInt16 SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+const sal_uInt16 SC_EXPECTATION_FAILED = 417;
+// DAV extensions
+const sal_uInt16 SC_UNPROCESSABLE_ENTITY = 422;
+const sal_uInt16 SC_LOCKED = 423;
+const sal_uInt16 SC_FAILED_DEPENDENCY = 424;
+
+//5xx (Server error)
+const sal_uInt16 SC_INTERNAL_SERVER_ERROR = 500;
+const sal_uInt16 SC_NOT_IMPLEMENTED = 501;
+const sal_uInt16 SC_BAD_GATEWAY = 502;
+const sal_uInt16 SC_SERVICE_UNAVAILABLE = 503;
+const sal_uInt16 SC_GATEWAY_TIMEOUT = 504;
+const sal_uInt16 SC_HTTP_VERSION_NOT_SUPPORTED = 505;
+// DAV extensions
+const sal_uInt16 SC_INSUFFICIENT_STORAGE = 507;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class DAVException
+{
+ public:
+ enum ExceptionCode {
+ DAV_HTTP_ERROR = 0, // Generic error,
+ // mData = server error message,
+ // mStatusCode = HTTP status code
+ DAV_HTTP_LOOKUP, // Name lookup failed,
+ // mData = server[:port]
+ DAV_HTTP_AUTH, // User authentication failed on server,
+ // mData = server[:port]
+ DAV_HTTP_AUTHPROXY, // User authentication failed on proxy,
+ // mData = proxy server[:port]
+ DAV_HTTP_CONNECT, // Could not connect to server,
+ // mData = server[:port]
+ DAV_HTTP_TIMEOUT, // Connection timed out
+ // mData = server[:port]
+ DAV_HTTP_FAILED, // The precondition failed
+ // mData = server[:port]
+ DAV_HTTP_RETRY, // Retry request
+ // mData = server[:port]
+ DAV_HTTP_REDIRECT, // Request was redirected,
+ // mData = new URL
+ DAV_SESSION_CREATE, // session creation error,
+ // mData = server[:port]
+ DAV_INVALID_ARG, // invalid argument
+
+ DAV_LOCK_EXPIRED, // DAV lock expired
+
+ DAV_NOT_LOCKED, // not locked
+
+ DAV_LOCKED_SELF, // locked by this OOo session
+
+ DAV_LOCKED // locked by third party
+ };
+
+ private:
+ ExceptionCode mExceptionCode;
+ rtl::OUString mData;
+ sal_uInt16 mStatusCode;
+
+ public:
+ DAVException( ExceptionCode inExceptionCode ) :
+ mExceptionCode( inExceptionCode ), mStatusCode( SC_NONE ) {};
+ DAVException( ExceptionCode inExceptionCode,
+ const rtl::OUString & rData ) :
+ mExceptionCode( inExceptionCode ), mData( rData ),
+ mStatusCode( SC_NONE ) {};
+ DAVException( ExceptionCode inExceptionCode,
+ const rtl::OUString & rData,
+ sal_uInt16 nStatusCode ) :
+ mExceptionCode( inExceptionCode ), mData( rData ),
+ mStatusCode( nStatusCode ) {};
+ ~DAVException( ) {};
+
+ const ExceptionCode & getError() const { return mExceptionCode; }
+ const rtl::OUString & getData() const { return mData; }
+ sal_uInt16 getStatus() const { return mStatusCode; }
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVEXCEPTION_HXX_
diff --git a/ucb/source/ucp/webdav/DAVProperties.cxx b/ucb/source/ucp/webdav/DAVProperties.cxx
new file mode 100644
index 000000000000..1202fb75a59f
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVProperties.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include "DAVProperties.hxx"
+
+using namespace webdav_ucp;
+
+const ::rtl::OUString DAVProperties::CREATIONDATE =
+ ::rtl::OUString::createFromAscii( "DAV:creationdate" );
+const ::rtl::OUString DAVProperties::DISPLAYNAME =
+ ::rtl::OUString::createFromAscii( "DAV:displayname" );
+const ::rtl::OUString DAVProperties::GETCONTENTLANGUAGE =
+ ::rtl::OUString::createFromAscii( "DAV:getcontentlanguage" );
+const ::rtl::OUString DAVProperties::GETCONTENTLENGTH =
+ ::rtl::OUString::createFromAscii( "DAV:getcontentlength" );
+const ::rtl::OUString DAVProperties::GETCONTENTTYPE =
+ ::rtl::OUString::createFromAscii( "DAV:getcontenttype" );
+const ::rtl::OUString DAVProperties::GETETAG =
+ ::rtl::OUString::createFromAscii( "DAV:getetag" );
+const ::rtl::OUString DAVProperties::GETLASTMODIFIED =
+ ::rtl::OUString::createFromAscii( "DAV:getlastmodified" );
+const ::rtl::OUString DAVProperties::LOCKDISCOVERY =
+ ::rtl::OUString::createFromAscii( "DAV:lockdiscovery" );
+const ::rtl::OUString DAVProperties::RESOURCETYPE =
+ ::rtl::OUString::createFromAscii( "DAV:resourcetype" );
+const ::rtl::OUString DAVProperties::SOURCE =
+ ::rtl::OUString::createFromAscii( "DAV:source" );
+const ::rtl::OUString DAVProperties::SUPPORTEDLOCK =
+ ::rtl::OUString::createFromAscii( "DAV:supportedlock" );
+
+const ::rtl::OUString DAVProperties::EXECUTABLE =
+ ::rtl::OUString::createFromAscii(
+ "http://apache.org/dav/props/executable" );
+
+// -------------------------------------------------------------------
+// static
+void DAVProperties::createNeonPropName( const rtl::OUString & rFullName,
+ NeonPropName & rName )
+{
+ if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DAV:" ) ) == 0 )
+ {
+ rName.nspace = "DAV:";
+ rName.name
+ = strdup( rtl::OUStringToOString(
+ rFullName.copy( RTL_CONSTASCII_LENGTH( "DAV:" ) ),
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "http://apache.org/dav/props/" ) ) == 0 )
+ {
+ rName.nspace = "http://apache.org/dav/props/";
+ rName.name
+ = strdup( rtl::OUStringToOString(
+ rFullName.copy(
+ RTL_CONSTASCII_LENGTH(
+ "http://apache.org/dav/props/" ) ),
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
+ {
+ rName.nspace = "http://ucb.openoffice.org/dav/props/";
+ rName.name
+ = strdup( rtl::OUStringToOString(
+ rFullName.copy(
+ RTL_CONSTASCII_LENGTH(
+ "http://ucb.openoffice.org/dav/props/" ) ),
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "<prop:" ) ) == 0 )
+ {
+ // Support for 3rd party namespaces/props
+
+ rtl::OString aFullName
+ = rtl::OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 );
+
+ // Format: <prop:the_propname xmlns:prop="the_namespace">
+
+ sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
+ sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart;
+ rName.name = strdup( aFullName.copy( nStart, nLen ) );
+
+ nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after ="
+ nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart;
+ rName.nspace = strdup( aFullName.copy( nStart, nLen ) );
+ }
+ else
+ {
+ // Add our namespace to our own properties.
+ rName.nspace = "http://ucb.openoffice.org/dav/props/";
+ rName.name
+ = strdup( rtl::OUStringToOString( rFullName,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+}
+
+// -------------------------------------------------------------------
+// static
+void DAVProperties::createUCBPropName( const char * nspace,
+ const char * name,
+ rtl::OUString & rFullName )
+{
+ rtl::OUString aNameSpace
+ = rtl::OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 );
+ rtl::OUString aName
+ = rtl::OStringToOUString( name, RTL_TEXTENCODING_UTF8 );
+
+ if ( !aNameSpace.getLength() )
+ {
+ // Some servers send XML without proper namespaces. Assume "DAV:"
+ // in this case, if name is a well-known dav property name.
+ // Although this is not 100% correct, it solves many problems.
+
+ if ( DAVProperties::RESOURCETYPE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::SUPPORTEDLOCK.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::LOCKDISCOVERY.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::CREATIONDATE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::DISPLAYNAME.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTLANGUAGE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTLENGTH.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTTYPE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETETAG.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETLASTMODIFIED.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::SOURCE.matchIgnoreAsciiCase( aName, 4 ) )
+ aNameSpace = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DAV:" ) );
+ }
+
+ // Note: Concatenating strings BEFORE comparing against known namespaces
+ // is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
+ rFullName = aNameSpace;
+ rFullName += aName;
+
+ if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "DAV:" ) ) == 0 )
+ {
+ // Okay, Just concat strings.
+ }
+ else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "http://apache.org/dav/props/" ) ) == 0 )
+ {
+ // Okay, Just concat strings.
+ }
+ else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
+ "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
+ {
+ // Remove namespace from our own properties.
+ rFullName = rFullName.copy(
+ RTL_CONSTASCII_LENGTH(
+ "http://ucb.openoffice.org/dav/props/" ) );
+ }
+ else
+ {
+ // Create property name that encodes, namespace and name ( XML ).
+ rFullName = rtl::OUString::createFromAscii( "<prop:" );
+ rFullName += aName;
+ rFullName += rtl::OUString::createFromAscii( " xmlns:prop=\"" );
+ rFullName += aNameSpace;
+ rFullName += rtl::OUString::createFromAscii( "\">" );
+ }
+}
+
+// -------------------------------------------------------------------
+// static
+bool DAVProperties::isUCBDeadProperty( const NeonPropName & rName )
+{
+ return ( rName.nspace &&
+ ( rtl_str_compareIgnoreAsciiCase(
+ rName.nspace, "http://ucb.openoffice.org/dav/props/" )
+ == 0 ) );
+}
diff --git a/ucb/source/ucp/webdav/DAVProperties.hxx b/ucb/source/ucp/webdav/DAVProperties.hxx
new file mode 100644
index 000000000000..46effc84697c
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVProperties.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DAVPROPERTIES_HXX_
+#define _DAVPROPERTIES_HXX_
+
+#include <rtl/ustring.hxx>
+#include "NeonTypes.hxx"
+
+namespace webdav_ucp
+{
+
+struct DAVProperties
+{
+ static const ::rtl::OUString CREATIONDATE;
+ static const ::rtl::OUString DISPLAYNAME;
+ static const ::rtl::OUString GETCONTENTLANGUAGE;
+ static const ::rtl::OUString GETCONTENTLENGTH;
+ static const ::rtl::OUString GETCONTENTTYPE;
+ static const ::rtl::OUString GETETAG;
+ static const ::rtl::OUString GETLASTMODIFIED;
+ static const ::rtl::OUString LOCKDISCOVERY;
+ static const ::rtl::OUString RESOURCETYPE;
+ static const ::rtl::OUString SOURCE;
+ static const ::rtl::OUString SUPPORTEDLOCK;
+ static const ::rtl::OUString EXECUTABLE;
+
+ static void createNeonPropName( const rtl::OUString & rFullName,
+ NeonPropName & rName );
+ static void createUCBPropName ( const char * nspace,
+ const char * name,
+ rtl::OUString & rFullName );
+
+ static bool isUCBDeadProperty( const NeonPropName & rName );
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVPROPERTIES_HXX_
diff --git a/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx b/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
new file mode 100644
index 000000000000..96e3faaff62f
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DAVREQUESTENVIRONMENT_HXX_
+#define _DAVREQUESTENVIRONMENT_HXX_
+
+#include <vector>
+#include <rtl/ref.hxx>
+#include "DAVAuthListener.hxx"
+
+namespace webdav_ucp
+{
+ typedef std::pair< rtl::OUString, rtl::OUString > DAVRequestHeader;
+ typedef std::vector< DAVRequestHeader > DAVRequestHeaders;
+
+struct DAVRequestEnvironment
+{
+ rtl::OUString m_aRequestURI;
+ rtl::Reference< DAVAuthListener > m_xAuthListener;
+// rtl::Reference< DAVStatusListener > m_xStatusListener;
+// rtl::Reference< DAVProgressListener > m_xStatusListener;
+ DAVRequestHeaders m_aRequestHeaders;
+ uno::Reference< ucb::XCommandEnvironment > m_xEnv;
+
+DAVRequestEnvironment( const rtl::OUString & rRequestURI,
+ const rtl::Reference< DAVAuthListener > & xListener,
+ const DAVRequestHeaders & rRequestHeaders,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv)
+ : m_aRequestURI( rRequestURI ),
+ m_xAuthListener( xListener ),
+ m_aRequestHeaders( rRequestHeaders ),
+ m_xEnv( xEnv ){}
+
+ DAVRequestEnvironment() {}
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVREQUESTENVIRONMENT_HXX_
diff --git a/ucb/source/ucp/webdav/DAVResource.hxx b/ucb/source/ucp/webdav/DAVResource.hxx
new file mode 100644
index 000000000000..4a14dc262443
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVResource.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVRESOURCE_HXX_
+#define _DAVRESOURCE_HXX_
+
+#include <vector>
+
+#include "rtl/ustring.hxx"
+#include "com/sun/star/uno/Any.hxx"
+
+namespace webdav_ucp
+{
+
+struct DAVPropertyValue
+{
+ rtl::OUString Name;
+ com::sun::star::uno::Any Value;
+ bool IsCaseSensitive;
+
+ DAVPropertyValue() : IsCaseSensitive( true ) {}
+};
+
+struct DAVResource
+{
+ ::rtl::OUString uri;
+ std::vector< DAVPropertyValue > properties;
+
+ DAVResource() {}
+ DAVResource( const ::rtl::OUString & inUri ) : uri( inUri ) {}
+};
+
+struct DAVResourceInfo
+{
+ ::rtl::OUString uri;
+ std::vector < ::rtl::OUString > properties;
+
+ DAVResourceInfo( const ::rtl::OUString & inUri ) : uri( inUri ) {}
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVRESOURCE_HXX_
diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.cxx b/ucb/source/ucp/webdav/DAVResourceAccess.cxx
new file mode 100644
index 000000000000..4ffc8dd88cf5
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVResourceAccess.cxx
@@ -0,0 +1,1219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "osl/diagnose.h"
+
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/ucb/XWebDAVCommandEnvironment.hpp"
+
+#include "ucbhelper/simpleauthenticationrequest.hxx"
+#include "comphelper/seekableinput.hxx"
+
+#include "DAVAuthListenerImpl.hxx"
+#include "DAVResourceAccess.hxx"
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+//=========================================================================
+//=========================================================================
+//
+// DAVAuthListener_Impl Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+//=========================================================================
+// virtual
+int DAVAuthListener_Impl::authenticate(
+ const ::rtl::OUString & inRealm,
+ const ::rtl::OUString & inHostName,
+ ::rtl::OUString & inoutUserName,
+ ::rtl::OUString & outPassWord,
+ sal_Bool bAllowPersistentStoring,
+ sal_Bool bCanUseSystemCredentials )
+{
+ if ( m_xEnv.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = m_xEnv->getInteractionHandler();
+
+ if ( xIH.is() )
+ {
+ // #102871# - Supply username and password from previous try.
+ // Password container service depends on this!
+ if ( inoutUserName.getLength() == 0 )
+ inoutUserName = m_aPrevUsername;
+
+ if ( outPassWord.getLength() == 0 )
+ outPassWord = m_aPrevPassword;
+
+ rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
+ = new ucbhelper::SimpleAuthenticationRequest(
+ m_aURL, inHostName, inRealm, inoutUserName,
+ outPassWord, ::rtl::OUString(),
+ bAllowPersistentStoring, bCanUseSystemCredentials );
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( !xAbort.is() )
+ {
+ const rtl::Reference<
+ ucbhelper::InteractionSupplyAuthentication > & xSupp
+ = xRequest->getAuthenticationSupplier();
+
+ sal_Bool bUseSystemCredentials = sal_False;
+
+ if ( bCanUseSystemCredentials )
+ bUseSystemCredentials
+ = xSupp->getUseSystemCredentials();
+
+ if ( bUseSystemCredentials )
+ {
+ // This is the (strange) way to tell neon to use
+ // system credentials.
+ inoutUserName = rtl::OUString();
+ outPassWord = rtl::OUString();
+ }
+ else
+ {
+ inoutUserName = xSupp->getUserName();
+ outPassWord = xSupp->getPassword();
+ }
+
+ // #102871# - Remember username and password.
+ m_aPrevUsername = inoutUserName;
+ m_aPrevPassword = outPassWord;
+
+ // go on.
+ return 0;
+ }
+ }
+ }
+ }
+ // Abort.
+ return -1;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DAVResourceAccess Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+//=========================================================================
+DAVResourceAccess::DAVResourceAccess(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr,
+ rtl::Reference< DAVSessionFactory > const & rSessionFactory,
+ const rtl::OUString & rURL )
+: m_aURL( rURL ),
+ m_xSessionFactory( rSessionFactory ),
+ m_xSMgr( rSMgr )
+{
+}
+
+//=========================================================================
+DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther )
+: m_aURL( rOther.m_aURL ),
+ m_aPath( rOther.m_aPath ),
+ m_xSession( rOther.m_xSession ),
+ m_xSessionFactory( rOther.m_xSessionFactory ),
+ m_xSMgr( rOther.m_xSMgr ),
+ m_aRedirectURIs( rOther.m_aRedirectURIs )
+{
+}
+
+//=========================================================================
+DAVResourceAccess & DAVResourceAccess::operator=(
+ const DAVResourceAccess & rOther )
+{
+ m_aURL = rOther.m_aURL;
+ m_aPath = rOther.m_aPath;
+ m_xSession = rOther.m_xSession;
+ m_xSessionFactory = rOther.m_xSessionFactory;
+ m_xSMgr = rOther.m_xSMgr;
+ m_aRedirectURIs = rOther.m_aRedirectURIs;
+
+ return *this;
+}
+
+#if 0 // currently not used, but please don't remove code
+//=========================================================================
+void DAVResourceAccess::OPTIONS(
+ DAVCapabilities & rCapabilities,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ bool bRetry;
+ int errorCount = 0;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii(
+ "OPTIONS" ),
+ aHeaders );
+
+ m_xSession->OPTIONS( getRequestURI(),
+ rCapabilities,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+#endif
+
+//=========================================================================
+void DAVResourceAccess::PROPFIND(
+ const Depth nDepth,
+ const std::vector< rtl::OUString > & rPropertyNames,
+ std::vector< DAVResource > & rResources,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii(
+ "PROPFIND" ),
+ aHeaders );
+
+ m_xSession->PROPFIND( getRequestURI(),
+ nDepth,
+ rPropertyNames,
+ rResources,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::PROPFIND(
+ const Depth nDepth,
+ std::vector< DAVResourceInfo > & rResInfo,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii(
+ "PROPFIND" ),
+ aHeaders );
+
+ m_xSession->PROPFIND( getRequestURI(),
+ nDepth,
+ rResInfo,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) ) ;
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::PROPPATCH(
+ const std::vector< ProppatchValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii(
+ "PROPPATCH" ),
+ aHeaders );
+
+ m_xSession->PROPPATCH( getRequestURI(),
+ rValues,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::HEAD(
+ const std::vector< rtl::OUString > & rHeaderNames,
+ DAVResource & rResource,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "HEAD" ),
+ aHeaders );
+
+ m_xSession->HEAD( getRequestURI(),
+ rHeaderNames,
+ rResource,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > DAVResourceAccess::GET(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ uno::Reference< io::XInputStream > xStream;
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "GET" ),
+ aHeaders );
+
+ xStream = m_xSession->GET( getRequestURI(),
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+
+ return xStream;
+}
+
+//=========================================================================
+void DAVResourceAccess::GET(
+ uno::Reference< io::XOutputStream > & rStream,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "GET" ),
+ aHeaders );
+
+ m_xSession->GET( getRequestURI(),
+ rStream,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > DAVResourceAccess::GET(
+ const std::vector< rtl::OUString > & rHeaderNames,
+ DAVResource & rResource,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ uno::Reference< io::XInputStream > xStream;
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "GET" ),
+ aHeaders );
+
+ xStream = m_xSession->GET( getRequestURI(),
+ rHeaderNames,
+ rResource,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+
+ return xStream;
+}
+
+//=========================================================================
+void DAVResourceAccess::GET(
+ uno::Reference< io::XOutputStream > & rStream,
+ const std::vector< rtl::OUString > & rHeaderNames,
+ DAVResource & rResource,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ bool bRetry;
+ int errorCount = 0;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "GET" ),
+ aHeaders );
+
+ m_xSession->GET( getRequestURI(),
+ rStream,
+ rHeaderNames,
+ rResource,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::abort()
+ throw( DAVException )
+{
+ // 17.11.09 (tkr): abort currently disabled caused by issue i106766
+ // initialize();
+ // m_xSession->abort();
+ OSL_TRACE( "Not implemented. -> #i106766#" );
+}
+
+//=========================================================================
+namespace {
+
+ void resetInputStream( const uno::Reference< io::XInputStream > & rStream )
+ throw( DAVException )
+ {
+ try
+ {
+ uno::Reference< io::XSeekable > xSeekable(
+ rStream, uno::UNO_QUERY );
+ if ( xSeekable.is() )
+ {
+ xSeekable->seek( 0 );
+ return;
+ }
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ }
+ catch ( io::IOException const & )
+ {
+ }
+
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ }
+
+} // namespace
+
+//=========================================================================
+void DAVResourceAccess::PUT(
+ const uno::Reference< io::XInputStream > & rStream,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ // Make stream seekable, if it not. Needed, if request must be retried.
+ uno::Reference< io::XInputStream > xSeekableStream
+ = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
+ rStream, m_xSMgr );
+
+ int errorCount = 0;
+ bool bRetry = false;
+ do
+ {
+ if ( bRetry )
+ resetInputStream( xSeekableStream );
+
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "PUT" ),
+ aHeaders );
+
+ m_xSession->PUT( getRequestURI(),
+ xSeekableStream,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > DAVResourceAccess::POST(
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const uno::Reference< io::XInputStream > & rInputStream,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ // Make stream seekable, if it not. Needed, if request must be retried.
+ uno::Reference< io::XInputStream > xSeekableStream
+ = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
+ rInputStream, m_xSMgr );
+
+ uno::Reference< io::XInputStream > xStream;
+ int errorCount = 0;
+ bool bRetry = false;
+ do
+ {
+ if ( bRetry )
+ {
+ resetInputStream( xSeekableStream );
+ bRetry = false;
+ }
+
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "POST" ),
+ aHeaders );
+
+ xStream = m_xSession->POST( getRequestURI(),
+ rContentType,
+ rReferer,
+ xSeekableStream,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+
+ if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
+ {
+ // #i74980# - Upon POST redirect, do a GET.
+ return GET( xEnv );
+ }
+ }
+ }
+ while ( bRetry );
+
+ return xStream;
+}
+
+//=========================================================================
+void DAVResourceAccess::POST(
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const uno::Reference< io::XInputStream > & rInputStream,
+ uno::Reference< io::XOutputStream > & rOutputStream,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ // Make stream seekable, if it not. Needed, if request must be retried.
+ uno::Reference< io::XInputStream > xSeekableStream
+ = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
+ rInputStream, m_xSMgr );
+
+ int errorCount = 0;
+ bool bRetry = false;
+ do
+ {
+ if ( bRetry )
+ {
+ resetInputStream( xSeekableStream );
+ bRetry = false;
+ }
+
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "POST" ),
+ aHeaders );
+
+ m_xSession->POST( getRequestURI(),
+ rContentType,
+ rReferer,
+ xSeekableStream,
+ rOutputStream,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+
+ if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
+ {
+ // #i74980# - Upon POST redirect, do a GET.
+ GET( rOutputStream, xEnv );
+ return;
+ }
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::MKCOL(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "MKCOL" ),
+ aHeaders );
+
+ m_xSession->MKCOL( getRequestURI(),
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::COPY(
+ const ::rtl::OUString & rSourcePath,
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "COPY" ),
+ aHeaders );
+
+ m_xSession->COPY( rSourcePath,
+ rDestinationURI,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ),
+ bOverwrite );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::MOVE(
+ const ::rtl::OUString & rSourcePath,
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "MOVE" ),
+ aHeaders );
+
+ m_xSession->MOVE( rSourcePath,
+ rDestinationURI,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ),
+ bOverwrite );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::DESTROY(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii(
+ "DESTROY" ),
+ aHeaders );
+
+ m_xSession->DESTROY( getRequestURI(),
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+// set new lock.
+void DAVResourceAccess::LOCK(
+ ucb::Lock & inLock,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "LOCK" ),
+ aHeaders );
+
+ m_xSession->LOCK( getRequestURI(),
+ inLock,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+#if 0 // currently not used, but please don't remove code
+//=========================================================================
+// refresh existing lock.
+sal_Int64 DAVResourceAccess::LOCK(
+ sal_Int64 nTimeout,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ sal_Int64 nNewTimeout = 0;
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "LOCK" ),
+ aHeaders );
+
+ nNewTimeout = m_xSession->LOCK( getRequestURI(),
+ nTimeout,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+
+ return nNewTimeout;
+}
+#endif
+
+//=========================================================================
+void DAVResourceAccess::UNLOCK(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "UNLOCK" ),
+ aHeaders );
+
+ m_xSession->UNLOCK( getRequestURI(),
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+}
+
+//=========================================================================
+void DAVResourceAccess::setURL( const rtl::OUString & rNewURL )
+ throw( DAVException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_aURL = rNewURL;
+ m_aPath = rtl::OUString(); // Next initialize() will create new session.
+}
+
+//=========================================================================
+// init dav session and path
+void DAVResourceAccess::initialize()
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( m_aPath.getLength() == 0 )
+ {
+ NeonUri aURI( m_aURL );
+ rtl::OUString aPath( aURI.GetPath() );
+
+ /* #134089# - Check URI */
+ if ( !aPath.getLength() )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ /* #134089# - Check URI */
+ if ( !aURI.GetHost().getLength() )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL ) )
+ {
+ m_xSession.clear();
+
+ // create new webdav session
+ m_xSession
+ = m_xSessionFactory->createDAVSession( m_aURL, m_xSMgr );
+
+ if ( !m_xSession.is() )
+ return;
+ }
+
+ // Own URI is needed for redirect cycle detection.
+ m_aRedirectURIs.push_back( aURI );
+
+ // Success.
+ m_aPath = aPath;
+
+ // Not only the path has to be encoded
+ m_aURL = aURI.GetURI();
+ }
+}
+
+//=========================================================================
+const rtl::OUString & DAVResourceAccess::getRequestURI() const
+{
+ OSL_ENSURE( m_xSession.is(),
+ "DAVResourceAccess::getRequestURI - Not initialized!" );
+
+ // In case a proxy is used we have to use the absolute URI for a request.
+ if ( m_xSession->UsesProxy() )
+ return m_aURL;
+
+ return m_aPath;
+}
+
+//=========================================================================
+// static
+void DAVResourceAccess::getUserRequestHeaders(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ const rtl::OUString & rURI,
+ const rtl::OUString & rMethod,
+ DAVRequestHeaders & rRequestHeaders )
+{
+ if ( xEnv.is() )
+ {
+ uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv(
+ xEnv, uno::UNO_QUERY );
+
+ if ( xDAVEnv.is() )
+ {
+ uno::Sequence< beans::NamedValue > aRequestHeaders
+ = xDAVEnv->getUserRequestHeaders( rURI, rMethod );
+
+ for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n )
+ {
+ rtl::OUString aValue;
+ sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue;
+
+ if ( !isString )
+ {
+ OSL_ENSURE( isString,
+ "DAVResourceAccess::getUserRequestHeaders :"
+ "Value is not a string! Ignoring..." );
+ }
+
+ rRequestHeaders.push_back(
+ DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) );
+ }
+ }
+ }
+}
+
+//=========================================================================
+sal_Bool DAVResourceAccess::detectRedirectCycle(
+ const rtl::OUString& rRedirectURL )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ NeonUri aUri( rRedirectURL );
+
+ std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
+ std::vector< NeonUri >::const_iterator end = m_aRedirectURIs.end();
+
+ while ( it != end )
+ {
+ if ( aUri == (*it) )
+ return sal_True;
+
+ it++;
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+void DAVResourceAccess::resetUri()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( m_aRedirectURIs.size() > 0 )
+ {
+ std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
+
+ NeonUri aUri( (*it) );
+ m_aRedirectURIs.clear();
+ setURL ( aUri.GetURI() );
+ initialize();
+ }
+}
+
+//=========================================================================
+sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount )
+ throw ( DAVException )
+{
+ switch ( e.getError() )
+ {
+ case DAVException::DAV_HTTP_REDIRECT:
+ if ( !detectRedirectCycle( e.getData() ) )
+ {
+ // set new URL and path.
+ setURL( e.getData() );
+ initialize();
+ return sal_True;
+ }
+ return sal_False;
+ // --> tkr #67048# copy & paste images doesn't display.
+ // if we have a bad connection try again. Up to three times.
+ case DAVException::DAV_HTTP_ERROR:
+ // retry up to three times, if not a client-side error.
+ if ( e.getStatus() > 0 &&
+ ( e.getStatus() < 400 || e.getStatus() > 499 ) &&
+ errorCount < 3 )
+ {
+ return sal_True;
+ }
+ return sal_False;
+ // <--
+ // --> tkr: if connection has said retry then retry!
+ case DAVException::DAV_HTTP_RETRY:
+ return sal_True;
+ // <--
+ default:
+ return sal_False; // Abort
+ }
+}
diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.hxx b/ucb/source/ucp/webdav/DAVResourceAccess.hxx
new file mode 100644
index 000000000000..53a98847078b
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVResourceAccess.hxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVRESOURCEACCESS_HXX_
+#define _DAVRESOURCEACCESS_HXX_
+
+#include <vector>
+#include <rtl/ustring.hxx>
+#include <rtl/ref.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/ucb/Lock.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include "DAVAuthListener.hxx"
+#include "DAVException.hxx"
+#include "DAVSession.hxx"
+#include "DAVResource.hxx"
+#include "DAVTypes.hxx"
+#include "NeonUri.hxx"
+
+namespace webdav_ucp
+{
+
+class DAVSessionFactory;
+
+class DAVResourceAccess
+{
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aURL;
+ rtl::OUString m_aPath;
+ rtl::Reference< DAVSession > m_xSession;
+ rtl::Reference< DAVSessionFactory > m_xSessionFactory;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ std::vector< NeonUri > m_aRedirectURIs;
+
+public:
+ DAVResourceAccess() : m_xSessionFactory( 0 ) {}
+ DAVResourceAccess( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr,
+ rtl::Reference<
+ DAVSessionFactory > const & rSessionFactory,
+ const rtl::OUString & rURL );
+ DAVResourceAccess( const DAVResourceAccess & rOther );
+
+ DAVResourceAccess & operator=( const DAVResourceAccess & rOther );
+
+ void setURL( const rtl::OUString & rNewURL )
+ throw ( DAVException );
+
+ void resetUri();
+
+ const rtl::OUString & getURL() const { return m_aURL; }
+
+ rtl::Reference< DAVSessionFactory > getSessionFactory() const
+ { return m_xSessionFactory; }
+
+ // DAV methods
+ //
+
+#if 0 // currently not used, but please don't remove code
+ void
+ OPTIONS( DAVCapabilities & rCapabilities,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+#endif
+
+ // allprop & named
+ void
+ PROPFIND( const Depth nDepth,
+ const std::vector< rtl::OUString > & rPropertyNames,
+ std::vector< DAVResource > & rResources,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ // propnames
+ void
+ PROPFIND( const Depth nDepth,
+ std::vector< DAVResourceInfo > & rResInfo,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ PROPPATCH( const std::vector< ProppatchValue > & rValues,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
+
+ void
+ HEAD( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
+ DAVResource & rResource,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ GET( com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & rStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
+ DAVResource & rResource,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ GET( com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & rStream,
+ const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
+ DAVResource & rResource,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ PUT( const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & rStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ POST( const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & rInputStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
+
+ void
+ POST( const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & rInputStream,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & rOutputStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
+
+ void
+ MKCOL( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ COPY( const ::rtl::OUString & rSourcePath,
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ MOVE( const ::rtl::OUString & rSourcePath,
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ DESTROY( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ // set new lock.
+ void
+ LOCK( com::sun::star::ucb::Lock & inLock,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException );
+
+#if 0 // currently not used, but please don't remove code
+ // refresh existing lock.
+ sal_Int64
+ LOCK( sal_Int64 nTimeout,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+#endif
+
+ void
+ UNLOCK( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+
+ void
+ abort()
+ throw ( DAVException );
+
+ // helper
+ static void
+ getUserRequestHeaders(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv,
+ const rtl::OUString & rURI,
+ const rtl::OUString & rMethod,
+ DAVRequestHeaders & rRequestHeaders );
+
+private:
+ const rtl::OUString & getRequestURI() const;
+ sal_Bool detectRedirectCycle( const rtl::OUString& rRedirectURL )
+ throw ( DAVException );
+ sal_Bool handleException( DAVException & e, int errorCount )
+ throw ( DAVException );
+ void initialize()
+ throw ( DAVException );
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVRESOURCEACCESS_HXX_
diff --git a/ucb/source/ucp/webdav/DAVSession.hxx b/ucb/source/ucp/webdav/DAVSession.hxx
new file mode 100644
index 000000000000..4ea24f372c12
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVSession.hxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVSESSION_HXX_
+#define _DAVSESSION_HXX_
+
+#include <memory>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "DAVException.hxx"
+#include "DAVProperties.hxx"
+#include "DAVResource.hxx"
+#include "DAVSessionFactory.hxx"
+#include "DAVTypes.hxx"
+#include "DAVRequestEnvironment.hxx"
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ struct Lock;
+} } } }
+
+namespace webdav_ucp
+{
+
+class DAVAuthListener;
+
+class DAVSession
+{
+public:
+ inline void acquire() SAL_THROW(())
+ {
+ osl_incrementInterlockedCount( &m_nRefCount );
+ }
+
+ void release() SAL_THROW(())
+ {
+ if ( osl_decrementInterlockedCount( &m_nRefCount ) == 0 )
+ {
+ m_xFactory->releaseElement( this );
+ delete this;
+ }
+ }
+
+ virtual sal_Bool CanUse( const ::rtl::OUString & inPath ) = 0;
+
+ virtual sal_Bool UsesProxy() = 0;
+
+ // DAV methods
+ //
+
+ virtual void OPTIONS( const ::rtl::OUString & inPath,
+ DAVCapabilities & outCapabilities,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ // allprop & named
+ virtual void PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ const std::vector< ::rtl::OUString > & inPropertyNames,
+ std::vector< DAVResource > & ioResources,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ // propnames
+ virtual void PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo > & ioResInfo,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void PROPPATCH( const ::rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void HEAD( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream >& o,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& o,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void PUT( const ::rtl::OUString & inPath,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >& s,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & oOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void MKCOL( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ virtual void COPY( const ::rtl::OUString & inSource,
+ const ::rtl::OUString & inDestination,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverwrite = false )
+ throw( DAVException ) = 0;
+
+ virtual void MOVE( const ::rtl::OUString & inSource,
+ const ::rtl::OUString & inDestination,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverwrite = false )
+ throw( DAVException ) = 0;
+
+ virtual void DESTROY( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException ) = 0;
+
+ // set new lock.
+ virtual void LOCK( const ::rtl::OUString & inPath,
+ com::sun::star::ucb::Lock & inLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ // refresh existing lock.
+ virtual sal_Int64 LOCK( const ::rtl::OUString & inPath,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void UNLOCK( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void abort()
+ throw( DAVException ) = 0;
+
+protected:
+ rtl::Reference< DAVSessionFactory > m_xFactory;
+
+ DAVSession( rtl::Reference< DAVSessionFactory > const & rFactory )
+ : m_xFactory( rFactory ), m_nRefCount( 0 ) {}
+
+ virtual ~DAVSession() {}
+
+private:
+ DAVSessionFactory::Map::iterator m_aContainerIt;
+ oslInterlockedCount m_nRefCount;
+
+ friend class DAVSessionFactory;
+#if defined WNT && _MSC_VER < 1310
+ friend struct std::auto_ptr< DAVSession >;
+ // work around compiler bug...
+#else // WNT
+ friend class std::auto_ptr< DAVSession >;
+#endif // WNT
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVSESSION_HXX_
diff --git a/ucb/source/ucp/webdav/DAVSessionFactory.cxx b/ucb/source/ucp/webdav/DAVSessionFactory.cxx
new file mode 100644
index 000000000000..86d513f23fd6
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVSessionFactory.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "DAVSessionFactory.hxx"
+#include "NeonSession.hxx"
+#include "NeonUri.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+DAVSessionFactory::~DAVSessionFactory()
+{
+}
+
+rtl::Reference< DAVSession > DAVSessionFactory::createDAVSession(
+ const ::rtl::OUString & inUri,
+ const uno::Reference< lang::XMultiServiceFactory > & rxSMgr )
+ throw( DAVException )
+{
+ m_xMSF = rxSMgr;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_xProxyDecider.get() )
+ m_xProxyDecider.reset( new ucbhelper::InternetProxyDecider( rxSMgr ) );
+
+ Map::iterator aIt( m_aMap.begin() );
+ Map::iterator aEnd( m_aMap.end() );
+
+ while ( aIt != aEnd )
+ {
+ if ( (*aIt).second->CanUse( inUri ) )
+ break;
+
+ ++aIt;
+ }
+
+ if ( aIt == aEnd )
+ {
+ NeonUri aURI( inUri );
+
+ std::auto_ptr< DAVSession > xElement(
+ new NeonSession( this, inUri, *m_xProxyDecider.get() ) );
+
+ aIt = m_aMap.insert( Map::value_type( inUri, xElement.get() ) ).first;
+ aIt->second->m_aContainerIt = aIt;
+ xElement.release();
+ return aIt->second;
+ }
+ else if ( osl_incrementInterlockedCount( &aIt->second->m_nRefCount ) > 1 )
+ {
+ rtl::Reference< DAVSession > xElement( aIt->second );
+ osl_decrementInterlockedCount( &aIt->second->m_nRefCount );
+ return xElement;
+ }
+ else
+ {
+ osl_decrementInterlockedCount( &aIt->second->m_nRefCount );
+ aIt->second->m_aContainerIt = m_aMap.end();
+
+ // If URL scheme is different from http or https we definitely
+ // have to use a proxy and therefore can optimize the getProxy
+ // call a little:
+ NeonUri aURI( inUri );
+
+ aIt->second = new NeonSession( this, inUri, *m_xProxyDecider.get() );
+ aIt->second->m_aContainerIt = aIt;
+ return aIt->second;
+ }
+}
+
+void DAVSessionFactory::releaseElement( DAVSession * pElement ) SAL_THROW(())
+{
+ OSL_ASSERT( pElement );
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( pElement->m_aContainerIt != m_aMap.end() )
+ m_aMap.erase( pElement->m_aContainerIt );
+}
+
diff --git a/ucb/source/ucp/webdav/DAVSessionFactory.hxx b/ucb/source/ucp/webdav/DAVSessionFactory.hxx
new file mode 100644
index 000000000000..eb1f22ace925
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVSessionFactory.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DAVSESSIONFACTORY_HXX_
+#define _DAVSESSIONFACTORY_HXX_
+
+#ifdef min
+#undef min // GNU libstdc++ <memory> includes <limit> which defines methods called min...
+#endif
+#include <map>
+#include <memory>
+#include <osl/mutex.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <rtl/ref.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <ucbhelper/proxydecider.hxx>
+#include "DAVException.hxx"
+
+using namespace com::sun::star;
+
+namespace com { namespace sun { namespace star { namespace lang {
+ class XMultiServiceFactory;
+} } } }
+
+namespace webdav_ucp
+{
+
+class DAVSession;
+
+class DAVSessionFactory : public salhelper::SimpleReferenceObject
+{
+public:
+ ~DAVSessionFactory() SAL_THROW(());
+
+ rtl::Reference< DAVSession >
+ createDAVSession( const ::rtl::OUString & inUri,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >&
+ rxSMgr )
+ throw( DAVException );
+
+ ::uno::Reference< ::lang::XMultiServiceFactory > getServiceFactory() { return m_xMSF; }
+private:
+ typedef std::map< rtl::OUString, DAVSession * > Map;
+
+ Map m_aMap;
+ osl::Mutex m_aMutex;
+ std::auto_ptr< ucbhelper::InternetProxyDecider > m_xProxyDecider;
+
+ ::uno::Reference< ::lang::XMultiServiceFactory > m_xMSF;
+
+ void releaseElement( DAVSession * pElement ) SAL_THROW(());
+
+ friend class DAVSession;
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVSESSIONFACTORY_HXX_
diff --git a/ucb/source/ucp/webdav/DAVTypes.hxx b/ucb/source/ucp/webdav/DAVTypes.hxx
new file mode 100644
index 000000000000..04da2fefed0c
--- /dev/null
+++ b/ucb/source/ucp/webdav/DAVTypes.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DAVTYPES_HXX_
+#define _DAVTYPES_HXX_
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+namespace webdav_ucp
+{
+/* RFC 2518
+
+15.1 Class 1
+
+ A class 1 compliant resource MUST meet all "MUST" requirements in all
+ sections of this document.
+
+ Class 1 compliant resources MUST return, at minimum, the value "1" in
+ the DAV header on all responses to the OPTIONS method.
+
+15.2 Class 2
+
+ A class 2 compliant resource MUST meet all class 1 requirements and
+ support the LOCK method, the supportedlock property, the
+ lockdiscovery property, the Time-Out response header and the Lock-
+ Token request header. A class "2" compliant resource SHOULD also
+ support the Time-Out request header and the owner XML element.
+
+ Class 2 compliant resources MUST return, at minimum, the values "1"
+ and "2" in the DAV header on all responses to the OPTIONS method.
+*/
+
+struct DAVCapabilities
+{
+ bool class1;
+ bool class2;
+ bool executable; // supports "executable" property (introduced by mod_dav)
+
+ DAVCapabilities() : class1( false ), class2( false ), executable( false ) {}
+};
+
+enum Depth { DAVZERO = 0, DAVONE = 1, DAVINFINITY = -1 };
+
+enum ProppatchOperation { PROPSET = 0, PROPREMOVE = 1 };
+
+struct ProppatchValue
+{
+ ProppatchOperation operation;
+ rtl::OUString name;
+ com::sun::star::uno::Any value;
+
+ ProppatchValue( const ProppatchOperation o,
+ const rtl::OUString & n,
+ const com::sun::star::uno::Any & v )
+ : operation( o ), name( n ), value( v ) {}
+};
+
+} // namespace webdav_ucp
+
+#endif // _DAVTYPES_HXX_
diff --git a/ucb/source/ucp/webdav/DateTimeHelper.cxx b/ucb/source/ucp/webdav/DateTimeHelper.cxx
new file mode 100644
index 000000000000..41caac39f64b
--- /dev/null
+++ b/ucb/source/ucp/webdav/DateTimeHelper.cxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <stdio.h>
+#include <osl/time.h>
+#include <com/sun/star/util/DateTime.hpp>
+#include "DateTimeHelper.hxx"
+
+using namespace com::sun::star::util;
+using namespace rtl;
+
+using namespace webdav_ucp;
+
+bool DateTimeHelper::ISO8601_To_DateTime (const OUString& s,
+ DateTime& dateTime)
+{
+ OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
+
+ int year, month, day, hours, minutes, off_hours, off_minutes, fix;
+ double seconds;
+
+ // 2001-01-01T12:30:00Z
+ int n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lfZ",
+ &year, &month, &day, &hours, &minutes, &seconds );
+ if ( n == 6 )
+ {
+ fix = 0;
+ }
+ else
+ {
+ // 2001-01-01T12:30:00+03:30
+ n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d",
+ &year, &month, &day, &hours, &minutes, &seconds,
+ &off_hours, &off_minutes );
+ if ( n == 8 )
+ {
+ fix = - off_hours * 3600 - off_minutes * 60;
+ }
+ else
+ {
+ // 2001-01-01T12:30:00-03:30
+ n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d",
+ &year, &month, &day, &hours, &minutes, &seconds,
+ &off_hours, &off_minutes );
+ if ( n == 8 )
+ {
+ fix = off_hours * 3600 + off_minutes * 60;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ // Convert to local time...
+
+ oslDateTime aDateTime;
+ aDateTime.NanoSeconds = 0;
+ aDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(seconds); // 0-59
+ aDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(minutes); // 0-59
+ aDateTime.Hours = sal::static_int_cast< sal_uInt16 >(hours); // 0-23
+ aDateTime.Day = sal::static_int_cast< sal_uInt16 >(day); // 1-31
+ aDateTime.DayOfWeek = 0; // 0-6, 0 = Sunday
+ aDateTime.Month = sal::static_int_cast< sal_uInt16 >(month); // 1-12
+ aDateTime.Year = sal::static_int_cast< sal_uInt16 >(year);
+
+ TimeValue aTimeValue;
+ if ( osl_getTimeValueFromDateTime( &aDateTime, &aTimeValue ) )
+ {
+ aTimeValue.Seconds += fix;
+
+ if ( osl_getLocalTimeFromSystemTime( &aTimeValue, &aTimeValue ) )
+ {
+ if ( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) )
+ {
+ dateTime.Year = aDateTime.Year;
+ dateTime.Month = aDateTime.Month;
+ dateTime.Day = aDateTime.Day;
+ dateTime.Hours = aDateTime.Hours;
+ dateTime.Minutes = aDateTime.Minutes;
+ dateTime.Seconds = aDateTime.Seconds;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/*
+sal_Int32 DateTimeHelper::convertDayToInt (const OUString& day)
+{
+ if (day.compareToAscii ("Sun") == 0)
+ return 0;
+ else if (day.compareToAscii ("Mon") == 0)
+ return 1;
+ else if (day.compareToAscii ("Tue") == 0)
+ return 2;
+ else if (day.compareToAscii ("Wed") == 0)
+ return 3;
+ else if (day.compareToAscii ("Thu") == 0)
+ return 4;
+ else if (day.compareToAscii ("Fri") == 0)
+ return 5;
+ else if (day.compareToAscii ("Sat") == 0)
+ return 6;
+ else
+ return -1;
+}
+*/
+
+sal_Int32 DateTimeHelper::convertMonthToInt (const OUString& month)
+{
+ if (month.compareToAscii ("Jan") == 0)
+ return 1;
+ else if (month.compareToAscii ("Feb") == 0)
+ return 2;
+ else if (month.compareToAscii ("Mar") == 0)
+ return 3;
+ else if (month.compareToAscii ("Apr") == 0)
+ return 4;
+ else if (month.compareToAscii ("May") == 0)
+ return 5;
+ else if (month.compareToAscii ("Jun") == 0)
+ return 6;
+ else if (month.compareToAscii ("Jul") == 0)
+ return 7;
+ else if (month.compareToAscii ("Aug") == 0)
+ return 8;
+ else if (month.compareToAscii ("Sep") == 0)
+ return 9;
+ else if (month.compareToAscii ("Oct") == 0)
+ return 10;
+ else if (month.compareToAscii ("Nov") == 0)
+ return 11;
+ else if (month.compareToAscii ("Dec") == 0)
+ return 12;
+ else
+ return 0;
+}
+
+bool DateTimeHelper::RFC2068_To_DateTime (const OUString& s,
+ DateTime& dateTime)
+{
+ int year;
+ int day;
+ int hours;
+ int minutes;
+ int seconds;
+ sal_Char string_month[3 + 1];
+ sal_Char string_day[3 + 1];
+
+ sal_Int32 found = s.indexOf (',');
+ if (found != -1)
+ {
+ OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
+
+ // RFC 1123
+ found = sscanf (aDT.getStr(), "%3s, %2d %3s %4d %2d:%2d:%2d GMT",
+ string_day, &day, string_month, &year, &hours, &minutes, &seconds);
+ if (found != 7)
+ {
+ // RFC 1036
+ found = sscanf (aDT.getStr(), "%3s, %2d-%3s-%2d %2d:%2d:%2d GMT",
+ string_day, &day, string_month, &year, &hours, &minutes, &seconds);
+ }
+ found = (found == 7) ? 1 : 0;
+ }
+ else
+ {
+ OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
+
+ // ANSI C's asctime () format
+ found = sscanf (aDT.getStr(), "%3s %3s %d %2d:%2d:%2d %4d",
+ string_day, string_month,
+ &day, &hours, &minutes, &seconds, &year);
+ found = (found == 7) ? 1 : 0;
+ }
+
+ if (found)
+ {
+ found = 0;
+
+ int month = DateTimeHelper::convertMonthToInt (
+ OUString::createFromAscii (string_month));
+ if (month)
+ {
+ // Convert to local time...
+
+ oslDateTime aDateTime;
+ aDateTime.NanoSeconds = 0;
+ aDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(seconds);
+ // 0-59
+ aDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(minutes);
+ // 0-59
+ aDateTime.Hours = sal::static_int_cast< sal_uInt16 >(hours);
+ // 0-23
+ aDateTime.Day = sal::static_int_cast< sal_uInt16 >(day);
+ // 1-31
+ aDateTime.DayOfWeek = 0; //dayofweek; // 0-6, 0 = Sunday
+ aDateTime.Month = sal::static_int_cast< sal_uInt16 >(month);
+ // 1-12
+ aDateTime.Year = sal::static_int_cast< sal_uInt16 >(year);
+
+ TimeValue aTimeValue;
+ if ( osl_getTimeValueFromDateTime( &aDateTime,
+ &aTimeValue ) )
+ {
+ if ( osl_getLocalTimeFromSystemTime( &aTimeValue,
+ &aTimeValue ) )
+ {
+ if ( osl_getDateTimeFromTimeValue( &aTimeValue,
+ &aDateTime ) )
+ {
+ dateTime.Year = aDateTime.Year;
+ dateTime.Month = aDateTime.Month;
+ dateTime.Day = aDateTime.Day;
+ dateTime.Hours = aDateTime.Hours;
+ dateTime.Minutes = aDateTime.Minutes;
+ dateTime.Seconds = aDateTime.Seconds;
+
+ found = 1;
+ }
+ }
+ }
+ }
+ }
+
+ return (found) ? true : false;
+}
+
+bool DateTimeHelper::convert (const OUString& s, DateTime& dateTime)
+{
+ if (ISO8601_To_DateTime (s, dateTime))
+ return true;
+ else if (RFC2068_To_DateTime (s, dateTime))
+ return true;
+ else
+ return false;
+}
+
diff --git a/ucb/source/ucp/webdav/DateTimeHelper.hxx b/ucb/source/ucp/webdav/DateTimeHelper.hxx
new file mode 100644
index 000000000000..c857457d0534
--- /dev/null
+++ b/ucb/source/ucp/webdav/DateTimeHelper.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_DATETIME_HELPER_HXX
+#define _WEBDAV_DATETIME_HELPER_HXX
+
+#include <sal/types.h>
+
+namespace com { namespace sun { namespace star { namespace util {
+ struct DateTime;
+} } } }
+
+namespace rtl {
+ class OUString;
+}
+
+namespace webdav_ucp
+{
+
+class DateTimeHelper
+{
+private:
+ static sal_Int32 convertMonthToInt (const ::rtl::OUString& );
+
+ static bool ISO8601_To_DateTime (const ::rtl::OUString&,
+ ::com::sun::star::util::DateTime& );
+
+ static bool RFC2068_To_DateTime (const ::rtl::OUString&,
+ ::com::sun::star::util::DateTime& );
+
+public:
+ static bool convert (const ::rtl::OUString&,
+ ::com::sun::star::util::DateTime& );
+};
+
+} // namespace webdav_ucp
+
+#endif
+
diff --git a/ucb/source/ucp/webdav/LinkSequence.cxx b/ucb/source/ucp/webdav/LinkSequence.cxx
new file mode 100644
index 000000000000..39d8d9cecc38
--- /dev/null
+++ b/ucb/source/ucp/webdav/LinkSequence.cxx
@@ -0,0 +1,223 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include <ne_xml.h>
+
+#ifndef _LINKSEQUENCE_HXX_
+#include "LinkSequence.hxx"
+#endif
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////
+
+struct LinkSequenceParseContext
+{
+ ucb::Link * pLink;
+ bool hasSource;
+ bool hasDestination;
+
+ LinkSequenceParseContext()
+ : pLink( 0 ), hasSource( false ), hasDestination( false ) {}
+ ~LinkSequenceParseContext() { delete pLink; }
+};
+
+#define STATE_TOP (1)
+
+#define STATE_LINK (STATE_TOP)
+#define STATE_DST (STATE_TOP + 1)
+#define STATE_SRC (STATE_TOP + 2)
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LinkSequence_startelement_callback(
+ void *,
+ int parent,
+ const char * /*nspace*/,
+ const char *name,
+ const char ** )
+{
+ if ( name != 0 )
+ {
+ switch ( parent )
+ {
+ case NE_XML_STATEROOT:
+ if ( strcmp( name, "link" ) == 0 )
+ return STATE_LINK;
+ break;
+
+ case STATE_LINK:
+ if ( strcmp( name, "dst" ) == 0 )
+ return STATE_DST;
+ else if ( strcmp( name, "src" ) == 0 )
+ return STATE_SRC;
+ break;
+ }
+ }
+ return NE_XML_DECLINE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LinkSequence_chardata_callback(
+ void *userdata,
+ int state,
+ const char *buf,
+ size_t len )
+{
+ LinkSequenceParseContext * pCtx
+ = static_cast< LinkSequenceParseContext * >( userdata );
+ if ( !pCtx->pLink )
+ pCtx->pLink = new ucb::Link;
+
+ switch ( state )
+ {
+ case STATE_DST:
+ pCtx->pLink->Destination
+ = rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ pCtx->hasDestination = true;
+ break;
+
+ case STATE_SRC:
+ pCtx->pLink->Source
+ = rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ pCtx->hasSource = true;
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LinkSequence_endelement_callback(
+ void *userdata,
+ int state,
+ const char *,
+ const char * )
+{
+ LinkSequenceParseContext * pCtx
+ = static_cast< LinkSequenceParseContext * >( userdata );
+ if ( !pCtx->pLink )
+ pCtx->pLink = new ucb::Link;
+
+ switch ( state )
+ {
+ case STATE_LINK:
+ if ( !pCtx->hasDestination || !pCtx->hasSource )
+ return 1; // abort
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool LinkSequence::createFromXML( const rtl::OString & rInData,
+ uno::Sequence< ucb::Link > & rOutData )
+{
+ const sal_Int32 TOKEN_LENGTH = 7; // </link>
+ bool success = true;
+
+ // rInData may contain multiple <link>...</link> tags.
+ sal_Int32 nCount = 0;
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = rInData.indexOf( "</link>" );
+ while ( nEnd > -1 )
+ {
+ ne_xml_parser * parser = ne_xml_create();
+ if ( !parser )
+ {
+ success = false;
+ break;
+ }
+
+ LinkSequenceParseContext aCtx;
+ ne_xml_push_handler( parser,
+ LinkSequence_startelement_callback,
+ LinkSequence_chardata_callback,
+ LinkSequence_endelement_callback,
+ &aCtx );
+
+ ne_xml_parse( parser,
+ rInData.getStr() + nStart,
+ nEnd - nStart + TOKEN_LENGTH );
+
+#if NEON_VERSION >= 0x0250
+ success = !ne_xml_failed( parser );
+#else
+ success = !!ne_xml_valid( parser );
+#endif
+
+ ne_xml_destroy( parser );
+
+ if ( !success )
+ break;
+
+ if ( aCtx.pLink )
+ {
+ nCount++;
+ if ( nCount > rOutData.getLength() )
+ rOutData.realloc( rOutData.getLength() + 1 );
+
+ rOutData[ nCount - 1 ] = *aCtx.pLink;
+ }
+
+ nStart = nEnd + TOKEN_LENGTH;
+ nEnd = rInData.indexOf( "</link>", nStart );
+ }
+
+ return success;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool LinkSequence::toXML( const uno::Sequence< ucb::Link > & rInData,
+ rtl::OUString & rOutData )
+{
+ // <link><src>value</src><dst>value</dst></link><link><src>....
+
+ sal_Int32 nCount = rInData.getLength();
+ if ( nCount )
+ {
+ rtl::OUString aPre( rtl::OUString::createFromAscii( "<link><src>" ) );
+ rtl::OUString aMid( rtl::OUString::createFromAscii( "</src><dst>" ) );
+ rtl::OUString aEnd( rtl::OUString::createFromAscii( "</dst></link>" ) );
+
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ rOutData += aPre;
+ rOutData += rInData[ n ].Source;
+ rOutData += aMid;
+ rOutData += rInData[ n ].Destination;
+ rOutData += aEnd;
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/ucb/source/ucp/webdav/LinkSequence.hxx b/ucb/source/ucp/webdav/LinkSequence.hxx
new file mode 100644
index 000000000000..49bf883f1099
--- /dev/null
+++ b/ucb/source/ucp/webdav/LinkSequence.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LINKSEQUENCE_HXX_
+#define _LINKKSEQUENCE_HXX_
+
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/ucb/Link.hpp>
+
+namespace webdav_ucp
+{
+
+class LinkSequence
+{
+public:
+ static bool createFromXML( const rtl::OString & rInData,
+ com::sun::star::uno::Sequence<
+ com::sun::star::ucb::Link > & rOutData );
+ static bool toXML( const com::sun::star::uno::Sequence<
+ com::sun::star::ucb::Link > & rInData,
+ rtl::OUString & rOutData );
+};
+
+}
+
+#endif /* _LINKSEQUENCE_HXX_ */
diff --git a/ucb/source/ucp/webdav/LockEntrySequence.cxx b/ucb/source/ucp/webdav/LockEntrySequence.cxx
new file mode 100644
index 000000000000..762170e7e057
--- /dev/null
+++ b/ucb/source/ucp/webdav/LockEntrySequence.cxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include <ne_xml.h>
+#include "LockEntrySequence.hxx"
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////
+
+struct LockEntrySequenceParseContext
+{
+ ucb::LockEntry * pEntry;
+ bool hasScope;
+ bool hasType;
+
+ LockEntrySequenceParseContext()
+ : pEntry( 0 ), hasScope( false ), hasType( false ) {}
+ ~LockEntrySequenceParseContext() { delete pEntry; }
+};
+
+#define STATE_TOP (1)
+
+#define STATE_LOCKENTRY (STATE_TOP)
+#define STATE_LOCKSCOPE (STATE_TOP + 1)
+#define STATE_EXCLUSIVE (STATE_TOP + 2)
+#define STATE_SHARED (STATE_TOP + 3)
+#define STATE_LOCKTYPE (STATE_TOP + 4)
+#define STATE_WRITE (STATE_TOP + 5)
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockEntrySequence_startelement_callback(
+ void *,
+ int parent,
+ const char * /*nspace*/,
+ const char *name,
+ const char ** )
+{
+ if ( name != 0 )
+ {
+ switch ( parent )
+ {
+ case NE_XML_STATEROOT:
+ if ( strcmp( name, "lockentry" ) == 0 )
+ return STATE_LOCKENTRY;
+ break;
+
+ case STATE_LOCKENTRY:
+ if ( strcmp( name, "lockscope" ) == 0 )
+ return STATE_LOCKSCOPE;
+ else if ( strcmp( name, "locktype" ) == 0 )
+ return STATE_LOCKTYPE;
+
+#define IIS_BUGS_WORKAROUND
+
+#ifdef IIS_BUGS_WORKAROUND
+ /* IIS (6) returns XML violating RFC 4918
+ for DAV:supportedlock property value.
+
+ <lockentry>
+ <write></write>
+ <shared></shared>
+ </lockentry>
+ <lockentry>
+ <write></write>
+ <exclusive></exclusive>
+ </lockentry>
+
+ Bother...
+ */
+ else if ( strcmp( name, "exclusive" ) == 0 )
+ return STATE_EXCLUSIVE;
+ else if ( strcmp( name, "shared" ) == 0 )
+ return STATE_SHARED;
+ else if ( strcmp( name, "write" ) == 0 )
+ return STATE_WRITE;
+#endif
+ break;
+
+ case STATE_LOCKSCOPE:
+ if ( strcmp( name, "exclusive" ) == 0 )
+ return STATE_EXCLUSIVE;
+ else if ( strcmp( name, "shared" ) == 0 )
+ return STATE_SHARED;
+ break;
+
+ case STATE_LOCKTYPE:
+ if ( strcmp( name, "write" ) == 0 )
+ return STATE_WRITE;
+ break;
+ }
+ }
+ return NE_XML_DECLINE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockEntrySequence_chardata_callback(
+ void *,
+ int,
+ const char *,
+ size_t )
+{
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockEntrySequence_endelement_callback(
+ void *userdata,
+ int state,
+ const char *,
+ const char * )
+{
+ LockEntrySequenceParseContext * pCtx
+ = static_cast< LockEntrySequenceParseContext * >( userdata );
+ if ( !pCtx->pEntry )
+ pCtx->pEntry = new ucb::LockEntry;
+
+ switch ( state )
+ {
+ case STATE_EXCLUSIVE:
+ pCtx->pEntry->Scope = ucb::LockScope_EXCLUSIVE;
+ pCtx->hasScope = true;
+ break;
+
+ case STATE_SHARED:
+ pCtx->pEntry->Scope = ucb::LockScope_SHARED;
+ pCtx->hasScope = true;
+ break;
+
+ case STATE_WRITE:
+ pCtx->pEntry->Type = ucb::LockType_WRITE;
+ pCtx->hasType = true;
+ break;
+
+ case STATE_LOCKSCOPE:
+ if ( !pCtx->hasScope )
+ return 1; // abort
+ break;
+
+ case STATE_LOCKTYPE:
+ if ( !pCtx->hasType )
+ return 1; // abort
+ break;
+
+ case STATE_LOCKENTRY:
+ if ( !pCtx->hasType || !pCtx->hasType )
+ return 1; // abort
+ break;
+
+ default:
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool LockEntrySequence::createFromXML( const rtl::OString & rInData,
+ uno::Sequence<
+ ucb::LockEntry > & rOutData )
+{
+ const sal_Int32 TOKEN_LENGTH = 12; // </lockentry>
+ bool success = true;
+
+ // rInData may contain multiple <lockentry>...</lockentry> tags.
+ sal_Int32 nCount = 0;
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = rInData.indexOf( "</lockentry>" );
+ while ( nEnd > -1 )
+ {
+ ne_xml_parser * parser = ne_xml_create();
+ if ( !parser )
+ {
+ success = false;
+ break;
+ }
+
+ LockEntrySequenceParseContext aCtx;
+ ne_xml_push_handler( parser,
+ LockEntrySequence_startelement_callback,
+ LockEntrySequence_chardata_callback,
+ LockEntrySequence_endelement_callback,
+ &aCtx );
+
+ ne_xml_parse( parser,
+ rInData.getStr() + nStart,
+ nEnd - nStart + TOKEN_LENGTH );
+
+#if NEON_VERSION >= 0x0250
+ success = !ne_xml_failed( parser );
+#else
+ success = !!ne_xml_valid( parser );
+#endif
+
+ ne_xml_destroy( parser );
+
+ if ( !success )
+ break;
+
+ if ( aCtx.pEntry )
+ {
+ nCount++;
+ if ( nCount > rOutData.getLength() )
+ rOutData.realloc( rOutData.getLength() + 2 );
+
+ rOutData[ nCount - 1 ] = *aCtx.pEntry;
+ }
+
+ nStart = nEnd + TOKEN_LENGTH;
+ nEnd = rInData.indexOf( "</lockentry>", nStart );
+ }
+
+ rOutData.realloc( nCount );
+ return success;
+}
diff --git a/ucb/source/ucp/webdav/LockEntrySequence.hxx b/ucb/source/ucp/webdav/LockEntrySequence.hxx
new file mode 100644
index 000000000000..12c407100ecf
--- /dev/null
+++ b/ucb/source/ucp/webdav/LockEntrySequence.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LOCKENTRYSEQUENCE_HXX_
+#define _LOCKENTRYSEQUENCE_HXX_
+
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/ucb/LockEntry.hpp>
+
+namespace webdav_ucp
+{
+
+class LockEntrySequence
+{
+public:
+ static bool createFromXML( const rtl::OString & rInData,
+ com::sun::star::uno::Sequence<
+ com::sun::star::ucb::LockEntry > & rOutData );
+};
+
+}
+
+#endif /* _LOCKENTRYSEQUENCE_HXX_ */
diff --git a/ucb/source/ucp/webdav/LockSequence.cxx b/ucb/source/ucp/webdav/LockSequence.cxx
new file mode 100644
index 000000000000..cd5f12708d58
--- /dev/null
+++ b/ucb/source/ucp/webdav/LockSequence.cxx
@@ -0,0 +1,351 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include <ne_xml.h>
+#include "LockSequence.hxx"
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////
+
+struct LockSequenceParseContext
+{
+ ucb::Lock * pLock;
+ bool hasLockScope;
+ bool hasLockType;
+ bool hasDepth;
+ bool hasHREF;
+ bool hasTimeout;
+
+ LockSequenceParseContext()
+ : pLock( 0 ), hasLockScope( false ), hasLockType( false ),
+ hasDepth( false ), hasHREF( false ), hasTimeout( false ) {}
+
+ ~LockSequenceParseContext() { delete pLock; }
+};
+
+#define STATE_TOP (1)
+
+#define STATE_ACTIVELOCK (STATE_TOP)
+#define STATE_LOCKSCOPE (STATE_TOP + 1)
+#define STATE_LOCKTYPE (STATE_TOP + 2)
+#define STATE_DEPTH (STATE_TOP + 3)
+#define STATE_OWNER (STATE_TOP + 4)
+#define STATE_TIMEOUT (STATE_TOP + 5)
+#define STATE_LOCKTOKEN (STATE_TOP + 6)
+#define STATE_EXCLUSIVE (STATE_TOP + 7)
+#define STATE_SHARED (STATE_TOP + 8)
+#define STATE_WRITE (STATE_TOP + 9)
+#define STATE_HREF (STATE_TOP + 10)
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockSequence_startelement_callback(
+ void *,
+ int parent,
+ const char * /*nspace*/,
+ const char *name,
+ const char ** )
+{
+ if ( name != 0 )
+ {
+ switch ( parent )
+ {
+ case NE_XML_STATEROOT:
+ if ( strcmp( name, "activelock" ) == 0 )
+ return STATE_ACTIVELOCK;
+ break;
+
+ case STATE_ACTIVELOCK:
+ if ( strcmp( name, "lockscope" ) == 0 )
+ return STATE_LOCKSCOPE;
+ else if ( strcmp( name, "locktype" ) == 0 )
+ return STATE_LOCKTYPE;
+ else if ( strcmp( name, "depth" ) == 0 )
+ return STATE_DEPTH;
+ else if ( strcmp( name, "owner" ) == 0 )
+ return STATE_OWNER;
+ else if ( strcmp( name, "timeout" ) == 0 )
+ return STATE_TIMEOUT;
+ else if ( strcmp( name, "locktoken" ) == 0 )
+ return STATE_LOCKTOKEN;
+ break;
+
+ case STATE_LOCKSCOPE:
+ if ( strcmp( name, "exclusive" ) == 0 )
+ return STATE_EXCLUSIVE;
+ else if ( strcmp( name, "shared" ) == 0 )
+ return STATE_SHARED;
+ break;
+
+ case STATE_LOCKTYPE:
+ if ( strcmp( name, "write" ) == 0 )
+ return STATE_WRITE;
+ break;
+
+ case STATE_LOCKTOKEN:
+ if ( strcmp( name, "href" ) == 0 )
+ return STATE_HREF;
+ break;
+
+ case STATE_OWNER:
+ // owner elem contains ANY. Accept anything; no state change.
+ return STATE_OWNER;
+ }
+ }
+ return NE_XML_DECLINE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockSequence_chardata_callback(
+ void *userdata,
+ int state,
+ const char *buf,
+ size_t len )
+{
+ LockSequenceParseContext * pCtx
+ = static_cast< LockSequenceParseContext * >( userdata );
+ if ( !pCtx->pLock )
+ pCtx->pLock = new ucb::Lock;
+
+ switch ( state )
+ {
+ case STATE_DEPTH:
+ if ( rtl_str_compareIgnoreAsciiCase_WithLength(
+ buf, len, "0", 1 ) == 0 )
+ {
+ pCtx->pLock->Depth = ucb::LockDepth_ZERO;
+ pCtx->hasDepth = true;
+ }
+ else if ( rtl_str_compareIgnoreAsciiCase_WithLength(
+ buf, len, "1", 1 ) == 0 )
+ {
+ pCtx->pLock->Depth = ucb::LockDepth_ONE;
+ pCtx->hasDepth = true;
+ }
+ else if ( rtl_str_compareIgnoreAsciiCase_WithLength(
+ buf, len, "infinity", 8 ) == 0 )
+ {
+ pCtx->pLock->Depth = ucb::LockDepth_INFINITY;
+ pCtx->hasDepth = true;
+ }
+ else
+ OSL_ENSURE( sal_False,
+ "LockSequence_chardata_callback - Unknown depth!" );
+ break;
+
+ case STATE_OWNER:
+ {
+ // collect raw XML data... (owner contains ANY)
+ rtl::OUString aValue;
+ pCtx->pLock->Owner >>= aValue;
+ aValue += rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ pCtx->pLock->Owner <<= aValue;
+ break;
+ }
+
+ case STATE_TIMEOUT:
+ //
+ // RFC2518, RFC2616:
+ //
+ // TimeType = ("Second-" DAVTimeOutVal | "Infinite" | Other)
+ // DAVTimeOutVal = 1*digit
+ // Other = "Extend" field-value
+ // field-value = *( field-content | LWS )
+ // field-content = <the OCTETs making up the field-value
+ // and consisting of either *TEXT or combinations
+ // of token, separators, and quoted-string>
+
+ if ( rtl_str_compareIgnoreAsciiCase_WithLength(
+ buf, len, "Infinite", 8 ) == 0 )
+ {
+ pCtx->pLock->Timeout = sal_Int64( -1 );
+ pCtx->hasTimeout = true;
+ }
+ else if ( rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
+ buf, len, "Second-", 7, 7 ) == 0 )
+ {
+ pCtx->pLock->Timeout
+ = rtl::OString( buf + 7, len - 7 ).toInt64();
+ pCtx->hasTimeout = true;
+ }
+// else if ( rtl_str_shortenedCompareIgnoreCase_WithLength(
+// buf, len, "Extend", 6, 6 ) == 0 )
+// {
+// @@@
+// }
+ else
+ {
+ pCtx->pLock->Timeout = sal_Int64( -1 );
+ pCtx->hasTimeout = true;
+ OSL_ENSURE( sal_False,
+ "LockSequence_chardata_callback - Unknown timeout!" );
+ }
+ break;
+
+ case STATE_HREF:
+ {
+ // collect hrefs.
+ sal_Int32 nPos = pCtx->pLock->LockTokens.getLength();
+ pCtx->pLock->LockTokens.realloc( nPos + 1 );
+ pCtx->pLock->LockTokens[ nPos ]
+ = rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ pCtx->hasHREF = true;
+ break;
+ }
+
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int LockSequence_endelement_callback(
+ void *userdata,
+ int state,
+ const char *,
+ const char * )
+{
+ LockSequenceParseContext * pCtx
+ = static_cast< LockSequenceParseContext * >( userdata );
+ if ( !pCtx->pLock )
+ pCtx->pLock = new ucb::Lock;
+
+ switch ( state )
+ {
+ case STATE_EXCLUSIVE:
+ pCtx->pLock->Scope = ucb::LockScope_EXCLUSIVE;
+ pCtx->hasLockScope = true;
+ break;
+
+ case STATE_SHARED:
+ pCtx->pLock->Scope = ucb::LockScope_SHARED;
+ pCtx->hasLockScope = true;
+ break;
+
+ case STATE_WRITE:
+ pCtx->pLock->Type = ucb::LockType_WRITE;
+ pCtx->hasLockType = true;
+ break;
+
+ case STATE_DEPTH:
+ if ( !pCtx->hasDepth )
+ return 1; // abort
+ break;
+
+ case STATE_HREF:
+ if ( !pCtx->hasHREF )
+ return 1; // abort
+ break;
+
+ case STATE_TIMEOUT:
+ if ( !pCtx->hasTimeout )
+ return 1; // abort
+ break;
+
+ case STATE_LOCKSCOPE:
+ if ( !pCtx->hasLockScope )
+ return 1; // abort
+ break;
+
+ case STATE_LOCKTYPE:
+ if ( !pCtx->hasLockType )
+ return 1; // abort
+ break;
+
+ case STATE_ACTIVELOCK:
+ if ( !pCtx->hasLockType || !pCtx->hasLockType || !pCtx->hasDepth )
+ return 1; // abort
+ break;
+
+ default:
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool LockSequence::createFromXML( const rtl::OString & rInData,
+ uno::Sequence< ucb::Lock > & rOutData )
+{
+ const sal_Int32 TOKEN_LENGTH = 13; // </activelock>
+ bool success = true;
+
+ // rInData may contain multiple <activelock>...</activelock> tags.
+ sal_Int32 nCount = 0;
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = rInData.indexOf( "</activelock>" );
+ while ( nEnd > -1 )
+ {
+ ne_xml_parser * parser = ne_xml_create();
+ if ( !parser )
+ {
+ success = false;
+ break;
+ }
+
+ LockSequenceParseContext aCtx;
+ ne_xml_push_handler( parser,
+ LockSequence_startelement_callback,
+ LockSequence_chardata_callback,
+ LockSequence_endelement_callback,
+ &aCtx );
+
+ ne_xml_parse( parser,
+ rInData.getStr() + nStart,
+ nEnd - nStart + TOKEN_LENGTH );
+
+#if NEON_VERSION >= 0x0250
+ success = !ne_xml_failed( parser );
+#else
+ success = !!ne_xml_valid( parser );
+#endif
+
+ ne_xml_destroy( parser );
+
+ if ( !success )
+ break;
+
+ if ( aCtx.pLock )
+ {
+ nCount++;
+ if ( nCount > rOutData.getLength() )
+ rOutData.realloc( rOutData.getLength() + 1 );
+
+ rOutData[ nCount - 1 ] = *aCtx.pLock;
+ }
+
+ nStart = nEnd + TOKEN_LENGTH;
+ nEnd = rInData.indexOf( "</activelock>", nStart );
+ }
+
+ return success;
+}
diff --git a/ucb/source/ucp/webdav/LockSequence.hxx b/ucb/source/ucp/webdav/LockSequence.hxx
new file mode 100644
index 000000000000..85d4cdee77f5
--- /dev/null
+++ b/ucb/source/ucp/webdav/LockSequence.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LOCKSEQUENCE_HXX_
+#define _LOCKSEQUENCE_HXX_
+
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/ucb/Lock.hpp>
+
+namespace webdav_ucp
+{
+
+class LockSequence
+{
+public:
+ static bool createFromXML( const rtl::OString & rInData,
+ com::sun::star::uno::Sequence<
+ com::sun::star::ucb::Lock > & rOutData );
+};
+
+}
+
+#endif /* _LOCKSEQUENCE_HXX_ */
diff --git a/ucb/source/ucp/webdav/NeonHeadRequest.cxx b/ucb/source/ucp/webdav/NeonHeadRequest.cxx
new file mode 100644
index 000000000000..2880a86a727d
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonHeadRequest.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include "NeonHeadRequest.hxx"
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+namespace {
+
+#if NEON_VERSION >= 0x0250
+void process_headers(ne_request *req,
+ DAVResource &rResource,
+ const std::vector< ::rtl::OUString > &rHeaderNames)
+{
+ void *cursor = NULL;
+ const char *name, *value;
+
+ while ((cursor = ne_response_header_iterate(req, cursor,
+ &name, &value)) != NULL) {
+ rtl::OUString aHeaderName( rtl::OUString::createFromAscii( name ) );
+ rtl::OUString aHeaderValue( rtl::OUString::createFromAscii( value ) );
+
+ // Note: Empty vector means that all headers are requested.
+ bool bIncludeIt = ( rHeaderNames.size() == 0 );
+
+ if ( !bIncludeIt )
+ {
+ // Check whether this header was requested.
+ std::vector< ::rtl::OUString >::const_iterator it(
+ rHeaderNames.begin() );
+ const std::vector< ::rtl::OUString >::const_iterator end(
+ rHeaderNames.end() );
+
+ while ( it != end )
+ {
+ if ( (*it) == aHeaderName )
+ break;
+
+ ++it;
+ }
+
+ if ( it != end )
+ bIncludeIt = true;
+ }
+
+ if ( bIncludeIt )
+ {
+ // Create & set the PropertyValue
+ DAVPropertyValue thePropertyValue;
+ thePropertyValue.Name = aHeaderName;
+ thePropertyValue.IsCaseSensitive = false;
+ thePropertyValue.Value <<= aHeaderValue;
+
+ // Add the newly created PropertyValue
+ rResource.properties.push_back( thePropertyValue );
+ }
+ }
+}
+#else
+struct NeonHeadRequestContext
+{
+ DAVResource * pResource;
+ const std::vector< ::rtl::OUString > * pHeaderNames;
+
+ NeonHeadRequestContext( DAVResource * p,
+ const std::vector< ::rtl::OUString > * pHeaders )
+ : pResource( p ), pHeaderNames( pHeaders ) {}
+};
+
+extern "C" void NHR_ResponseHeaderCatcher( void * userdata,
+ const char * value )
+{
+ rtl::OUString aHeader( rtl::OUString::createFromAscii( value ) );
+ sal_Int32 nPos = aHeader.indexOf( ':' );
+
+ if ( nPos != -1 )
+ {
+ rtl::OUString aHeaderName( aHeader.copy( 0, nPos ) );
+
+ NeonHeadRequestContext * pCtx
+ = static_cast< NeonHeadRequestContext * >( userdata );
+
+ // Note: Empty vector means that all headers are requested.
+ bool bIncludeIt = ( pCtx->pHeaderNames->size() == 0 );
+
+ if ( !bIncludeIt )
+ {
+ // Check whether this header was requested.
+ std::vector< ::rtl::OUString >::const_iterator it(
+ pCtx->pHeaderNames->begin() );
+ const std::vector< ::rtl::OUString >::const_iterator end(
+ pCtx->pHeaderNames->end() );
+
+ while ( it != end )
+ {
+ if ( (*it) == aHeaderName )
+ break;
+
+ ++it;
+ }
+
+ if ( it != end )
+ bIncludeIt = true;
+ }
+
+ if ( bIncludeIt )
+ {
+ // Create & set the PropertyValue
+ DAVPropertyValue thePropertyValue;
+ thePropertyValue.Name = aHeaderName;
+ thePropertyValue.IsCaseSensitive = false;
+
+ if ( nPos < aHeader.getLength() )
+ thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim();
+
+ // Add the newly created PropertyValue
+ pCtx->pResource->properties.push_back( thePropertyValue );
+ }
+ }
+}
+#endif
+
+} // namespace
+
+// -------------------------------------------------------------------
+// Constructor
+// -------------------------------------------------------------------
+
+NeonHeadRequest::NeonHeadRequest( HttpSession* inSession,
+ const rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > &
+ inHeaderNames,
+ DAVResource & ioResource,
+ int & nError )
+{
+ ioResource.uri = inPath;
+ ioResource.properties.clear();
+
+ // Create and dispatch HEAD request. Install catcher for all response
+ // header fields.
+ ne_request * req = ne_request_create( inSession,
+ "HEAD",
+ rtl::OUStringToOString(
+ inPath,
+ RTL_TEXTENCODING_UTF8 ) );
+
+#if NEON_VERSION < 0x0250
+ NeonHeadRequestContext aCtx( &ioResource, &inHeaderNames );
+ ne_add_response_header_catcher( req, NHR_ResponseHeaderCatcher, &aCtx );
+#endif
+
+ nError = ne_request_dispatch( req );
+
+#if NEON_VERSION >= 0x0250
+ process_headers(req, ioResource, inHeaderNames);
+#endif
+
+ if ( nError == NE_OK && ne_get_status( req )->klass != 2 )
+ nError = NE_ERROR;
+
+ ne_request_destroy( req );
+}
+
+// -------------------------------------------------------------------
+// Destructor
+// -------------------------------------------------------------------
+NeonHeadRequest::~NeonHeadRequest()
+{
+}
+
diff --git a/ucb/source/ucp/webdav/NeonHeadRequest.hxx b/ucb/source/ucp/webdav/NeonHeadRequest.hxx
new file mode 100644
index 000000000000..eb79ae7658c2
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonHeadRequest.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NEONHEADREQUEST_HXX_
+#define _NEONHEADREQUEST_HXX_
+
+#include <vector>
+#include "NeonTypes.hxx"
+#include "DAVResource.hxx"
+
+namespace webdav_ucp
+{
+
+class NeonHeadRequest
+{
+public:
+ // named / allprop
+ NeonHeadRequest( HttpSession* inSession,
+ const rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ int & nError );
+ ~NeonHeadRequest();
+};
+
+} // namespace webdav_ucp
+
+#endif // _NEONHEADREQUEST_HXX_
+
diff --git a/ucb/source/ucp/webdav/NeonInputStream.cxx b/ucb/source/ucp/webdav/NeonInputStream.cxx
new file mode 100644
index 000000000000..2e142af955c8
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonInputStream.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include "NeonInputStream.hxx"
+#include <rtl/memory.h>
+
+using namespace cppu;
+using namespace rtl;
+using namespace com::sun::star::io;
+using namespace com::sun::star::uno;
+using namespace webdav_ucp;
+
+
+// -------------------------------------------------------------------
+// Constructor
+// -------------------------------------------------------------------
+NeonInputStream::NeonInputStream( void )
+: mLen( 0 ),
+ mPos( 0 )
+{
+}
+
+// -------------------------------------------------------------------
+// Destructor
+// -------------------------------------------------------------------
+NeonInputStream::~NeonInputStream( void )
+{
+}
+
+// -------------------------------------------------------------------
+// AddToStream
+// Allows the caller to add some data to the "end" of the stream
+// -------------------------------------------------------------------
+void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen )
+{
+ mInputBuffer.realloc( sal::static_int_cast<sal_Int32>(mLen) + inLen );
+ rtl_copyMemory( mInputBuffer.getArray() + mLen, inBuf, inLen );
+ mLen += inLen;
+}
+
+// -------------------------------------------------------------------
+// queryInterface
+// -------------------------------------------------------------------
+Any NeonInputStream::queryInterface( const Type &type )
+ throw( RuntimeException )
+{
+ Any aRet = ::cppu::queryInterface( type,
+ static_cast< XInputStream * >( this ),
+ static_cast< XSeekable * >( this ) );
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
+}
+
+// -------------------------------------------------------------------
+// readBytes
+// "Reads" the specified number of bytes from the stream
+// -------------------------------------------------------------------
+sal_Int32 SAL_CALL NeonInputStream::readBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ // Work out how much we're actually going to write
+ sal_Int32 theBytes2Read = nBytesToRead;
+ sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(mLen - mPos);
+ if ( theBytes2Read > theBytesLeft )
+ theBytes2Read = theBytesLeft;
+
+ // Realloc buffer.
+ aData.realloc( theBytes2Read );
+
+ // Write the data
+ rtl_copyMemory(
+ aData.getArray(), mInputBuffer.getConstArray() + mPos, theBytes2Read );
+
+ // Update our stream position for next time
+ mPos += theBytes2Read;
+
+ return theBytes2Read;
+}
+
+// -------------------------------------------------------------------
+// readSomeBytes
+// -------------------------------------------------------------------
+sal_Int32 SAL_CALL NeonInputStream::readSomeBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ // Warning: What should this be doing ?
+ return readBytes( aData, nMaxBytesToRead );
+}
+
+// -------------------------------------------------------------------
+// skipBytes
+// Moves the current stream position forward
+// -------------------------------------------------------------------
+void SAL_CALL NeonInputStream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ mPos += nBytesToSkip;
+ if ( mPos >= mLen )
+ mPos = mLen;
+}
+
+// -------------------------------------------------------------------
+// available
+// Returns the number of unread bytes currently remaining on the stream
+// -------------------------------------------------------------------
+sal_Int32 SAL_CALL NeonInputStream::available( )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ return sal::static_int_cast<sal_Int32>(mLen - mPos);
+}
+
+// -------------------------------------------------------------------
+// closeInput
+// -------------------------------------------------------------------
+void SAL_CALL NeonInputStream::closeInput( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+}
+
+// -------------------------------------------------------------------
+// seek
+// -------------------------------------------------------------------
+void SAL_CALL NeonInputStream::seek( sal_Int64 location )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ if ( location < 0 )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ if ( location <= mLen )
+ mPos = location;
+ else
+ throw ::com::sun::star::lang::IllegalArgumentException();
+}
+
+// -------------------------------------------------------------------
+// getPosition
+// -------------------------------------------------------------------
+sal_Int64 SAL_CALL NeonInputStream::getPosition()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ return mPos;
+}
+
+// -------------------------------------------------------------------
+// getLength
+// -------------------------------------------------------------------
+sal_Int64 SAL_CALL NeonInputStream::getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ return mLen;
+}
diff --git a/ucb/source/ucp/webdav/NeonInputStream.hxx b/ucb/source/ucp/webdav/NeonInputStream.hxx
new file mode 100644
index 000000000000..55bf64b1bfcc
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonInputStream.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _NEONINPUTSTREAM_HXX_
+#define _NEONINPUTSTREAM_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/weak.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+
+namespace webdav_ucp
+{
+
+// -------------------------------------------------------------------
+// NeonInputStream
+// A simple XInputStream implementation provided specifically for use
+// by the DAVSession::GET method.
+// -------------------------------------------------------------------
+class NeonInputStream : public ::com::sun::star::io::XInputStream,
+ public ::com::sun::star::io::XSeekable,
+ public ::cppu::OWeakObject
+{
+ private:
+ com::sun::star::uno::Sequence< sal_Int8 > mInputBuffer;
+ sal_Int64 mLen;
+ sal_Int64 mPos;
+
+ public:
+ NeonInputStream( void );
+ virtual ~NeonInputStream();
+
+ // Add some data to the end of the stream
+ void AddToStream( const char * inBuf, sal_Int32 inLen );
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+ const ::com::sun::star::uno::Type & type )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL acquire( void )
+ throw ()
+ { OWeakObject::acquire(); }
+
+ virtual void SAL_CALL release( void )
+ throw()
+ { OWeakObject::release(); }
+
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL readBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL readSomeBytes(
+ ::com::sun::star::uno::Sequence< sal_Int8 > & aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::BufferSizeExceededException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL available( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL closeInput( void )
+ throw( ::com::sun::star::io::NotConnectedException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XSeekable
+ virtual void SAL_CALL seek( sal_Int64 location )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getPosition()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int64 SAL_CALL getLength()
+ throw( ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+} // namespace webdav_ucp
+#endif // _NEONINPUTSTREAM_HXX_
diff --git a/ucb/source/ucp/webdav/NeonLockStore.cxx b/ucb/source/ucp/webdav/NeonLockStore.cxx
new file mode 100644
index 000000000000..82510fcc9b71
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonLockStore.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <ne_locks.h>
+#include <ne_uri.h>
+#include "rtl/ustring.hxx"
+#include "osl/time.h"
+#include "osl/thread.hxx"
+#include "NeonSession.hxx"
+#include "NeonLockStore.hxx"
+
+using namespace webdav_ucp;
+
+namespace webdav_ucp {
+
+class TickerThread : public osl::Thread
+{
+ bool m_bFinish;
+ NeonLockStore & m_rLockStore;
+
+public:
+
+ TickerThread( NeonLockStore & rLockStore )
+ : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {}
+
+ void finish() { m_bFinish = true; }
+
+protected:
+
+ virtual void SAL_CALL run();
+};
+
+} // namespace webdav_ucp
+
+// -------------------------------------------------------------------
+void TickerThread::run()
+{
+ OSL_TRACE( "TickerThread: start." );
+
+ // we have to go through the loop more often to be able to finish ~quickly
+ const int nNth = 25;
+
+ int nCount = nNth;
+ while ( !m_bFinish )
+ {
+ if ( nCount-- <= 0 )
+ {
+ m_rLockStore.refreshLocks();
+ nCount = nNth;
+ }
+
+ TimeValue aTV;
+ aTV.Seconds = 0;
+ aTV.Nanosec = 1000000000 / nNth;
+ wait( aTV );
+ }
+
+ OSL_TRACE( "TickerThread: stop." );
+}
+
+// -------------------------------------------------------------------
+NeonLockStore::NeonLockStore()
+ : m_pNeonLockStore( ne_lockstore_create() ),
+ m_pTickerThread( 0 )
+{
+ OSL_ENSURE( m_pNeonLockStore, "Unable to create neon lock store!" );
+}
+
+// -------------------------------------------------------------------
+NeonLockStore::~NeonLockStore()
+{
+ stopTicker();
+
+ // release active locks, if any.
+ OSL_ENSURE( m_aLockInfoMap.size() == 0,
+ "NeonLockStore::~NeonLockStore - Releasing active locks!" );
+
+ LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
+ const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
+ while ( it != end )
+ {
+ NeonLock * pLock = (*it).first;
+ (*it).second.xSession->UNLOCK( pLock );
+
+ ne_lockstore_remove( m_pNeonLockStore, pLock );
+ ne_lock_destroy( pLock );
+
+ ++it;
+ }
+
+ ne_lockstore_destroy( m_pNeonLockStore );
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::startTicker()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pTickerThread )
+ {
+ m_pTickerThread = new TickerThread( *this );
+ m_pTickerThread->create();
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::stopTicker()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pTickerThread )
+ {
+ m_pTickerThread->finish();
+ m_pTickerThread->join();
+ delete m_pTickerThread;
+ m_pTickerThread = 0;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::registerSession( HttpSession * pHttpSession )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_lockstore_register( m_pNeonLockStore, pHttpSession );
+}
+
+// -------------------------------------------------------------------
+NeonLock * NeonLockStore::findByUri( rtl::OUString const & rUri )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_uri aUri;
+ ne_uri_parse( rtl::OUStringToOString(
+ rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri );
+ return ne_lockstore_findbyuri( m_pNeonLockStore, &aUri );
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::addLock( NeonLock * pLock,
+ rtl::Reference< NeonSession > const & xSession,
+ sal_Int32 nLastChanceToSendRefreshRequest )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_lockstore_add( m_pNeonLockStore, pLock );
+ m_aLockInfoMap[ pLock ]
+ = LockInfo( xSession, nLastChanceToSendRefreshRequest );
+
+ startTicker();
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::updateLock( NeonLock * pLock,
+ sal_Int32 nLastChanceToSendRefreshRequest )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
+ OSL_ENSURE( it != m_aLockInfoMap.end(),
+ "NeonLockStore::updateLock: lock not found!" );
+
+ if ( it != m_aLockInfoMap.end() )
+ {
+ (*it).second.nLastChanceToSendRefreshRequest
+ = nLastChanceToSendRefreshRequest;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::removeLock( NeonLock * pLock )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ m_aLockInfoMap.erase( pLock );
+ ne_lockstore_remove( m_pNeonLockStore, pLock );
+
+ if ( m_aLockInfoMap.size() == 0 )
+ stopTicker();
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::refreshLocks()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ LockInfoMap::iterator it( m_aLockInfoMap.begin() );
+ const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
+ while ( it != end )
+ {
+ LockInfo & rInfo = (*it).second;
+ if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
+ {
+ // 30 seconds or less remaining until lock expires?
+ TimeValue t1;
+ osl_getSystemTime( &t1 );
+ if ( rInfo.nLastChanceToSendRefreshRequest - 30
+ <= sal_Int32( t1.Seconds ) )
+ {
+ // refresh the lock.
+ sal_Int32 nlastChanceToSendRefreshRequest = -1;
+ if ( rInfo.xSession->LOCK(
+ (*it).first,
+ /* out param */ nlastChanceToSendRefreshRequest ) )
+ {
+ rInfo.nLastChanceToSendRefreshRequest
+ = nlastChanceToSendRefreshRequest;
+ }
+ else
+ {
+ // refresh failed. stop auto-refresh.
+ rInfo.nLastChanceToSendRefreshRequest = -1;
+ }
+ }
+ }
+ ++it;
+ }
+}
diff --git a/ucb/source/ucp/webdav/NeonLockStore.hxx b/ucb/source/ucp/webdav/NeonLockStore.hxx
new file mode 100644
index 000000000000..66f771f61901
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonLockStore.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_NEONLOCKSTORE_HXX
+#define INCLUDED_NEONLOCKSTORE_HXX
+
+#include <map>
+#include "ne_locks.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "NeonTypes.hxx"
+
+namespace webdav_ucp
+{
+
+class TickerThread;
+class NeonSession;
+
+struct ltptr
+{
+ bool operator()( const NeonLock * p1, const NeonLock * p2 ) const
+ {
+ return p1 < p2;
+ }
+};
+
+typedef struct _LockInfo
+{
+ rtl::Reference< NeonSession > xSession;
+ sal_Int32 nLastChanceToSendRefreshRequest;
+
+ _LockInfo()
+ : nLastChanceToSendRefreshRequest( -1 ) {}
+
+ _LockInfo( rtl::Reference< NeonSession > const & _xSession,
+ sal_Int32 _nLastChanceToSendRefreshRequest )
+ : xSession( _xSession ),
+ nLastChanceToSendRefreshRequest( _nLastChanceToSendRefreshRequest ) {}
+
+} LockInfo;
+
+typedef std::map< NeonLock *, LockInfo, ltptr > LockInfoMap;
+
+class NeonLockStore
+{
+ osl::Mutex m_aMutex;
+ ne_lock_store * m_pNeonLockStore;
+ TickerThread * m_pTickerThread;
+ LockInfoMap m_aLockInfoMap;
+
+public:
+ NeonLockStore();
+ ~NeonLockStore();
+
+ void registerSession( HttpSession * pHttpSession );
+
+ NeonLock * findByUri( rtl::OUString const & rUri );
+
+ void addLock( NeonLock * pLock,
+ rtl::Reference< NeonSession > const & xSession,
+ // time in seconds since Jan 1 1970
+ // -1: infinite lock, no refresh
+ sal_Int32 nLastChanceToSendRefreshRequest );
+
+ void updateLock( NeonLock * pLock,
+ sal_Int32 nLastChanceToSendRefreshRequest );
+
+ void removeLock( NeonLock * pLock );
+
+ void refreshLocks();
+
+private:
+ void startTicker();
+ void stopTicker();
+};
+
+} // namespace webdav_ucp
+
+#endif // INCLUDED_NEONLOCKSTORE_HXX
diff --git a/ucb/source/ucp/webdav/NeonPropFindRequest.cxx b/ucb/source/ucp/webdav/NeonPropFindRequest.cxx
new file mode 100644
index 000000000000..85b5ea0393e0
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonPropFindRequest.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "osl/diagnose.h"
+#include "rtl/strbuf.hxx"
+#include "NeonTypes.hxx"
+#include "DAVException.hxx"
+#include "DAVProperties.hxx"
+#include "NeonPropFindRequest.hxx"
+#include "LinkSequence.hxx"
+#include "LockSequence.hxx"
+#include "LockEntrySequence.hxx"
+#include "UCBDeadPropertyValue.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace std;
+using namespace webdav_ucp;
+
+// -------------------------------------------------------------------
+namespace
+{
+ // strip "DAV:" namespace from XML snippets to avoid
+ // parser error (undeclared namespace) later on.
+ rtl::OString stripDavNamespace( const rtl::OString & in )
+ {
+ const rtl::OString inXML( in.toAsciiLowerCase() );
+
+ rtl::OStringBuffer buf;
+ sal_Int32 start = 0;
+ sal_Int32 end = inXML.indexOf( "dav:" );
+ while ( end != -1 )
+ {
+ if ( inXML[ end - 1 ] == '<' ||
+ inXML[ end - 1 ] == '/' )
+ {
+ // copy from original buffer - preserve case.
+ buf.append( in.copy( start, end - start ) );
+ }
+ else
+ {
+ // copy from original buffer - preserve case.
+ buf.append( in.copy( start, end - start + 4 ) );
+ }
+ start = end + 4;
+ end = inXML.indexOf( "dav:", start );
+ }
+ buf.append( inXML.copy( start ) );
+
+ return rtl::OString( buf.makeStringAndClear() );
+ }
+}
+
+// -------------------------------------------------------------------
+extern "C" int NPFR_propfind_iter( void* userdata,
+ const NeonPropName* pname,
+ const char* value,
+ const HttpStatus* status )
+{
+ /*
+ HTTP Response Status Classes:
+
+ - 1: Informational - Request received, continuing process
+
+ - 2: Success - The action was successfully received,
+ understood, and accepted
+
+ - 3: Redirection - Further action must be taken in order to
+ complete the request
+
+ - 4: Client Error - The request contains bad syntax or cannot
+ be fulfilled
+
+ - 5: Server Error - The server failed to fulfill an apparently
+ valid request
+ */
+
+ if ( status->klass > 2 )
+ return 0; // Error getting this property. Go on.
+
+ // Create & set the PropertyValue
+ DAVPropertyValue thePropertyValue;
+ thePropertyValue.IsCaseSensitive = true;
+
+ OSL_ENSURE( pname->nspace, "NPFR_propfind_iter - No namespace!" );
+
+ DAVProperties::createUCBPropName( pname->nspace,
+ pname->name,
+ thePropertyValue.Name );
+ bool bHasValue = false;
+ if ( DAVProperties::isUCBDeadProperty( *pname ) )
+ {
+ // DAV dead property added by WebDAV UCP?
+ if ( UCBDeadPropertyValue::createFromXML(
+ value, thePropertyValue.Value ) )
+ {
+ OSL_ENSURE( thePropertyValue.Value.hasValue(),
+ "NPFR_propfind_iter - No value!" );
+ bHasValue = true;
+ }
+ }
+
+ if ( !bHasValue )
+ {
+ if ( rtl_str_compareIgnoreAsciiCase(
+ pname->name, "resourcetype" ) == 0 )
+ {
+ OString aValue( value );
+ aValue = aValue.trim(); // #107358# remove leading/trailing spaces
+ if ( aValue.getLength() )
+ {
+ aValue = stripDavNamespace( aValue ).toAsciiLowerCase();
+ if ( aValue.compareTo(
+ RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
+ {
+ thePropertyValue.Value
+ <<= OUString::createFromAscii( "collection" );
+ }
+ }
+
+ if ( !thePropertyValue.Value.hasValue() )
+ {
+ // Take over the value exactly as supplied by the server.
+ thePropertyValue.Value <<= OUString::createFromAscii( value );
+ }
+ }
+ else if ( rtl_str_compareIgnoreAsciiCase(
+ pname->name, "supportedlock" ) == 0 )
+ {
+ Sequence< LockEntry > aEntries;
+ LockEntrySequence::createFromXML(
+ stripDavNamespace( value ), aEntries );
+ thePropertyValue.Value <<= aEntries;
+ }
+ else if ( rtl_str_compareIgnoreAsciiCase(
+ pname->name, "lockdiscovery" ) == 0 )
+ {
+ Sequence< Lock > aLocks;
+ LockSequence::createFromXML(
+ stripDavNamespace( value ), aLocks );
+ thePropertyValue.Value <<= aLocks;
+ }
+ else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
+ {
+ Sequence< Link > aLinks;
+ LinkSequence::createFromXML(
+ stripDavNamespace( value ), aLinks );
+ thePropertyValue.Value <<= aLinks;
+ }
+ else
+ {
+ thePropertyValue.Value
+ <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
+ }
+ }
+
+ // Add the newly created PropertyValue
+ DAVResource* theResource = static_cast< DAVResource * >( userdata );
+ theResource->properties.push_back( thePropertyValue );
+
+ return 0; // Go on.
+}
+
+// -------------------------------------------------------------------
+extern "C" void NPFR_propfind_results( void* userdata,
+#if NEON_VERSION >= 0x0260
+ const ne_uri* uri,
+#else
+ const char* href,
+#endif
+ const NeonPropFindResultSet* set )
+{
+ // @@@ href is not the uri! DAVResource ctor wants uri!
+
+#if NEON_VERSION >= 0x0260
+ DAVResource theResource(
+ OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
+#else
+ DAVResource theResource(
+ OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
+#endif
+
+ ne_propset_iterate( set, NPFR_propfind_iter, &theResource );
+
+ // Add entry to resources list.
+ vector< DAVResource > * theResources
+ = static_cast< vector< DAVResource > * >( userdata );
+ theResources->push_back( theResource );
+}
+// -------------------------------------------------------------------
+extern "C" int NPFR_propnames_iter( void* userdata,
+ const NeonPropName* pname,
+ const char* /*value*/,
+ const HttpStatus* /*status*/ )
+{
+ OUString aFullName;
+ DAVProperties::createUCBPropName( pname->nspace,
+ pname->name,
+ aFullName );
+
+ DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
+ theResource->properties.push_back( aFullName );
+ return 0;
+}
+
+// -------------------------------------------------------------------
+extern "C" void NPFR_propnames_results( void* userdata,
+#if NEON_VERSION >= 0x0260
+ const ne_uri* uri,
+#else
+ const char* href,
+#endif
+ const NeonPropFindResultSet* results )
+{
+ // @@@ href is not the uri! DAVResourceInfo ctor wants uri!
+ // Create entry for the resource.
+#if NEON_VERSION >= 0x0260
+ DAVResourceInfo theResource(
+ OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
+#else
+ DAVResourceInfo theResource(
+ OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
+#endif
+
+ // Fill entry.
+ ne_propset_iterate( results, NPFR_propnames_iter, &theResource );
+
+ // Add entry to resources list.
+ vector< DAVResourceInfo > * theResources
+ = static_cast< vector< DAVResourceInfo > * >( userdata );
+ theResources->push_back( theResource );
+}
+
+// -------------------------------------------------------------------
+// Constructor
+// -------------------------------------------------------------------
+
+NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
+ const char* inPath,
+ const Depth inDepth,
+ const vector< OUString >& inPropNames,
+ vector< DAVResource >& ioResources,
+ int & nError )
+{
+ // Generate the list of properties we're looking for
+ int thePropCount = inPropNames.size();
+ if ( thePropCount > 0 )
+ {
+ NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
+ int theIndex;
+
+ for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
+ {
+ // Split fullname into namespace and name!
+ DAVProperties::createNeonPropName(
+ inPropNames[ theIndex ], thePropNames[ theIndex ] );
+ }
+ thePropNames[ theIndex ].nspace = NULL;
+ thePropNames[ theIndex ].name = NULL;
+
+ nError = ne_simple_propfind( inSession,
+ inPath,
+ inDepth,
+ thePropNames,
+ NPFR_propfind_results,
+ &ioResources );
+
+ for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
+ free( (void *)thePropNames[ theIndex ].name );
+
+ delete [] thePropNames;
+ }
+ else
+ {
+ // ALLPROP
+ nError = ne_simple_propfind( inSession,
+ inPath,
+ inDepth,
+ NULL, // 0 == allprop
+ NPFR_propfind_results,
+ &ioResources );
+ }
+
+ // #87585# - Sometimes neon lies (because some servers lie).
+ if ( ( nError == NE_OK ) && ioResources.empty() )
+ nError = NE_ERROR;
+}
+
+// -------------------------------------------------------------------
+// Constructor
+// - obtains property names
+// -------------------------------------------------------------------
+
+NeonPropFindRequest::NeonPropFindRequest(
+ HttpSession* inSession,
+ const char* inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo > & ioResInfo,
+ int & nError )
+{
+ nError = ne_propnames( inSession,
+ inPath,
+ inDepth,
+ NPFR_propnames_results,
+ &ioResInfo );
+
+ // #87585# - Sometimes neon lies (because some servers lie).
+ if ( ( nError == NE_OK ) && ioResInfo.empty() )
+ nError = NE_ERROR;
+}
+
+// -------------------------------------------------------------------
+// Destructor
+// -------------------------------------------------------------------
+NeonPropFindRequest::~NeonPropFindRequest( )
+{
+}
diff --git a/ucb/source/ucp/webdav/NeonPropFindRequest.hxx b/ucb/source/ucp/webdav/NeonPropFindRequest.hxx
new file mode 100644
index 000000000000..26e8793e2b96
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonPropFindRequest.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NEONPROPFINDREQUEST_HXX_
+#define _NEONPROPFINDREQUEST_HXX_
+
+#include <vector>
+#include <rtl/ustring.hxx>
+#include "NeonTypes.hxx"
+#include "DAVTypes.hxx"
+#include "DAVResource.hxx"
+
+namespace webdav_ucp
+{
+
+class NeonPropFindRequest
+{
+public:
+ // named / allprop
+ NeonPropFindRequest( HttpSession* inSession,
+ const char* inPath,
+ const Depth inDepth,
+ const std::vector< ::rtl::OUString > & inPropNames,
+ std::vector< DAVResource > & ioResources,
+ int & nError );
+ // propnames
+ NeonPropFindRequest( HttpSession* inSession,
+ const char* inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo > & ioResInfo,
+ int & nError );
+
+ ~NeonPropFindRequest();
+};
+
+} // namespace webdav_ucp
+
+#endif // _NEONPROPFINDREQUEST_HXX_
diff --git a/ucb/source/ucp/webdav/NeonSession.cxx b/ucb/source/ucp/webdav/NeonSession.cxx
new file mode 100644
index 000000000000..8fc1730ba018
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonSession.cxx
@@ -0,0 +1,2205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <hash_map>
+#include <vector>
+#include <string.h>
+#include "osl/diagnose.h"
+#include "osl/time.h"
+#include <rtl/string.h>
+#include <ne_socket.h>
+#include <ne_auth.h>
+#include <ne_redirect.h>
+#include <ne_ssl.h>
+#include <ne_compress.h>
+#include "libxml/parser.h"
+#include "rtl/ustrbuf.hxx"
+#include "comphelper/sequence.hxx"
+#include "ucbhelper/simplecertificatevalidationrequest.hxx"
+
+#include "DAVAuthListener.hxx"
+#include "NeonTypes.hxx"
+#include "NeonSession.hxx"
+#include "NeonInputStream.hxx"
+#include "NeonPropFindRequest.hxx"
+#include "NeonHeadRequest.hxx"
+#include "NeonUri.hxx"
+#include "LinkSequence.hxx"
+#include "UCBDeadPropertyValue.hxx"
+
+#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/security/CertificateValidity.hpp>
+#include <com/sun/star/security/CertificateContainerStatus.hpp>
+#include <com/sun/star/security/CertificateContainer.hpp>
+#include <com/sun/star/security/XCertificateContainer.hpp>
+#include <com/sun/star/task/XMasterPasswordHandling.hpp>
+#include <com/sun/star/ucb/Lock.hpp>
+#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+#define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
+
+#ifndef EOL
+# define EOL "\r\n"
+#endif
+
+// -------------------------------------------------------------------
+// RequestData
+// -------------------------------------------------------------------
+
+struct RequestData
+{
+ // POST
+ rtl::OUString aContentType;
+ rtl::OUString aReferer;
+
+ RequestData() {}
+ RequestData( const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer )
+ : aContentType( rContentType ), aReferer( rReferer ) {}
+};
+
+// -------------------------------------------------------------------
+// RequestDataMap
+// -------------------------------------------------------------------
+
+struct equalPtr
+{
+ bool operator()( const ne_request* p1, const ne_request* p2 ) const
+ {
+ return p1 == p2;
+ }
+};
+
+struct hashPtr
+{
+ size_t operator()( const ne_request* p ) const
+ {
+ return (size_t)p;
+ }
+};
+
+typedef std::hash_map
+<
+ ne_request*,
+ RequestData,
+ hashPtr,
+ equalPtr
+>
+RequestDataMap;
+
+// -------------------------------------------------------------------
+// Helper fuction
+// -------------------------------------------------------------------
+static sal_uInt16 makeStatusCode( const rtl::OUString & rStatusText )
+{
+ // Extract status code from session error string. Unfortunately
+ // neon provides no direct access to the status code...
+
+ if ( rStatusText.getLength() < 3 )
+ {
+ OSL_ENSURE(
+ sal_False, "makeStatusCode - status text string to short!" );
+ return 0;
+ }
+
+ sal_Int32 nPos = rStatusText.indexOf( ' ' );
+ if ( nPos == -1 )
+ {
+ OSL_ENSURE( sal_False, "makeStatusCode - wrong status text format!" );
+ return 0;
+ }
+
+ return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() );
+}
+
+// -------------------------------------------------------------------
+struct NeonRequestContext
+{
+ uno::Reference< io::XOutputStream > xOutputStream;
+ rtl::Reference< NeonInputStream > xInputStream;
+ const std::vector< ::rtl::OUString > * pHeaderNames;
+ DAVResource * pResource;
+
+ NeonRequestContext( uno::Reference< io::XOutputStream > & xOutStrm )
+ : xOutputStream( xOutStrm ), xInputStream( 0 ),
+ pHeaderNames( 0 ), pResource( 0 ) {}
+
+ NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm )
+ : xOutputStream( 0 ), xInputStream( xInStrm ),
+ pHeaderNames( 0 ), pResource( 0 ) {}
+
+ NeonRequestContext( uno::Reference< io::XOutputStream > & xOutStrm,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource )
+ : xOutputStream( xOutStrm ), xInputStream( 0 ),
+ pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {}
+
+ NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource )
+ : xOutputStream( 0 ), xInputStream( xInStrm ),
+ pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {}
+};
+
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+//
+// Callback functions
+//
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+// ResponseBlockReader
+// A simple Neon response_block_reader for use with an XInputStream
+// -------------------------------------------------------------------
+
+#if NEON_VERSION >= 0x0250
+extern "C" int NeonSession_ResponseBlockReader(void * inUserData,
+#else
+extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
+#endif
+ const char * inBuf,
+ size_t inLen )
+{
+ // neon sometimes calls this function with (inLen == 0)...
+ if ( inLen > 0 )
+ {
+ NeonRequestContext * pCtx
+ = static_cast< NeonRequestContext * >( inUserData );
+
+ rtl::Reference< NeonInputStream > xInputStream(
+ pCtx->xInputStream );
+
+ if ( xInputStream.is() )
+ xInputStream->AddToStream( inBuf, inLen );
+ }
+#if NEON_VERSION >= 0x0250
+ return 0;
+#endif
+}
+
+// -------------------------------------------------------------------
+// ResponseBlockWriter
+// A simple Neon response_block_reader for use with an XOutputStream
+// -------------------------------------------------------------------
+
+#if NEON_VERSION >= 0x0250
+extern "C" int NeonSession_ResponseBlockWriter( void * inUserData,
+#else
+extern "C" void NeonSession_ResponseBlockWriter( void * inUserData,
+#endif
+ const char * inBuf,
+ size_t inLen )
+{
+ // neon calls this function with (inLen == 0)...
+ if ( inLen > 0 )
+ {
+ NeonRequestContext * pCtx
+ = static_cast< NeonRequestContext * >( inUserData );
+ uno::Reference< io::XOutputStream > xOutputStream
+ = pCtx->xOutputStream;
+
+ if ( xOutputStream.is() )
+ {
+ const uno::Sequence< sal_Int8 > aSeq( (sal_Int8 *)inBuf, inLen );
+ xOutputStream->writeBytes( aSeq );
+ }
+ }
+#if NEON_VERSION >= 0x0250
+ return 0;
+#endif
+}
+
+// -------------------------------------------------------------------
+extern "C" int NeonSession_NeonAuth( void * inUserData,
+#ifdef NE_FEATURE_SSPI
+ const char * inAuthProtocol,
+#endif
+ const char * inRealm,
+ int attempt,
+ char * inoutUserName,
+ char * inoutPassWord )
+{
+/* The callback used to request the username and password in the given
+ * realm. The username and password must be copied into the buffers
+ * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero
+ * on the first call to the callback, and increases by one each time
+ * an attempt to authenticate fails.
+ *
+ * The callback must return zero to indicate that authentication
+ * should be attempted with the username/password, or non-zero to
+ * cancel the request. (if non-zero, username and password are
+ * ignored.) */
+
+#if 0
+ // Give'em only a limited mumber of retries..
+ if ( attempt > 9 )
+ {
+ // abort
+ return -1;
+ }
+#endif
+
+ NeonSession * theSession = static_cast< NeonSession * >( inUserData );
+ DAVAuthListener * pListener
+ = theSession->getRequestEnvironment().m_xAuthListener.get();
+ if ( !pListener )
+ {
+ // abort
+ return -1;
+ }
+ rtl::OUString theUserName;
+ rtl::OUString thePassWord;
+
+ if ( attempt == 0 )
+ {
+ // neon does not handle username supplied with request URI (for
+ // instance when doing FTP over proxy - last checked: 0.23.5 )
+
+ try
+ {
+ NeonUri uri( theSession->getRequestEnvironment().m_aRequestURI );
+ rtl::OUString aUserInfo( uri.GetUserInfo() );
+ if ( aUserInfo.getLength() )
+ {
+ sal_Int32 nPos = aUserInfo.indexOf( '@' );
+ if ( nPos == -1 )
+ {
+ theUserName = aUserInfo;
+ }
+ else
+ {
+ theUserName = aUserInfo.copy( 0, nPos );
+ thePassWord = aUserInfo.copy( nPos + 1 );
+ }
+ }
+ }
+ catch ( DAVException const & )
+ {
+ // abort
+ return -1;
+ }
+ }
+ else
+ {
+ // username buffer is prefilled with user name from last attempt.
+ theUserName = rtl::OUString::createFromAscii( inoutUserName );
+ // @@@ Neon does not initialize password buffer (last checked: 0.22.0).
+ //thePassWord = rtl::OUString::createFromAscii( inoutPassWord );
+ }
+
+ bool bCanUseSystemCreds = false;
+
+#ifdef NE_FEATURE_SSPI
+ bCanUseSystemCreds
+ = (attempt == 0) && // avoid endless loops
+ ne_has_support( NE_FEATURE_SSPI ) && // Windows-only feature.
+ ( ( ne_strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
+ ( ne_strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
+#endif
+
+ // #i97003# (tkr): Ask XMasterPasswordHandling if we should store the
+ // credentials persistently and give this information to the auth listener
+ uno::Reference< task::XMasterPasswordHandling > xMasterPasswordHandling;
+ try
+ {
+ xMasterPasswordHandling =
+ uno::Reference< task::XMasterPasswordHandling >(
+ theSession->getMSF()->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.task.PasswordContainer" ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ int theRetVal = pListener->authenticate(
+ rtl::OUString::createFromAscii( inRealm ),
+ theSession->getHostName(),
+ theUserName,
+ thePassWord,
+ xMasterPasswordHandling.is()
+ ? xMasterPasswordHandling->
+ isPersistentStoringAllowed()
+ : sal_False,
+ bCanUseSystemCreds);
+
+ rtl::OString aUser(
+ rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ) );
+ if ( aUser.getLength() > ( NE_ABUFSIZ - 1 ) )
+ {
+ OSL_ENSURE(
+ sal_False, "NeonSession_NeonAuth - username to long!" );
+ return -1;
+ }
+
+ rtl::OString aPass(
+ rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ) );
+ if ( aPass.getLength() > ( NE_ABUFSIZ - 1 ) )
+ {
+ OSL_ENSURE(
+ sal_False, "NeonSession_NeonAuth - password to long!" );
+ return -1;
+ }
+
+ strcpy( inoutUserName, // #100211# - checked
+ rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ) );
+
+ strcpy( inoutPassWord, // #100211# - checked
+ rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ) );
+
+ return theRetVal;
+}
+
+// -------------------------------------------------------------------
+
+namespace {
+ // -------------------------------------------------------------------
+ // Helper function
+ ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString )
+ {
+ ::rtl::OUString sPart;
+ ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" );
+ sal_Int32 nContStart = _rRawString.indexOf( sPartId );
+ if ( nContStart != -1 )
+ {
+ nContStart = nContStart + sPartId.getLength();
+ sal_Int32 nContEnd
+ = _rRawString.indexOf( sal_Unicode( ',' ), nContStart );
+ sPart = _rRawString.copy( nContStart, nContEnd - nContStart );
+ }
+ return sPart;
+ }
+} // namespace
+
+// -------------------------------------------------------------------
+extern "C" int NeonSession_CertificationNotify( void *userdata,
+ int failures,
+ const ne_ssl_certificate *cert )
+{
+ OSL_ASSERT( cert );
+
+ NeonSession * pSession = static_cast< NeonSession * >( userdata );
+ uno::Reference< security::XCertificateContainer > xCertificateContainer;
+ try
+ {
+ xCertificateContainer
+ = uno::Reference< security::XCertificateContainer >(
+ pSession->getMSF()->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.security.CertificateContainer" ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ if ( !xCertificateContainer.is() )
+ return 1;
+
+ failures = 0;
+
+ char * dn = ne_ssl_readable_dname( ne_ssl_cert_subject( cert ) );
+ rtl::OUString cert_subject( dn, strlen( dn ), RTL_TEXTENCODING_UTF8, 0 );
+
+ ne_free( dn );
+
+ security::CertificateContainerStatus certificateContainer(
+ xCertificateContainer->hasCertificate(
+ pSession->getHostName(), cert_subject ) );
+
+ if ( certificateContainer != security::CertificateContainerStatus_NOCERT )
+ return
+ certificateContainer == security::CertificateContainerStatus_TRUSTED
+ ? 0
+ : 1;
+
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
+ try
+ {
+ xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
+ pSession->getMSF()->createInstance(
+ rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ if ( !xSEInitializer.is() )
+ return 1;
+
+ uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext(
+ xSEInitializer->createSecurityContext( rtl::OUString() ) );
+
+ uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv(
+ xSecurityContext->getSecurityEnvironment() );
+
+ //The end entity certificate
+ char * eeCertB64 = ne_ssl_cert_export( cert );
+
+ rtl::OString sEECertB64( eeCertB64 );
+
+ uno::Reference< security::XCertificate > xEECert(
+ xSecurityEnv->createCertificateFromAscii(
+ rtl::OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) ) );
+
+ ne_free( eeCertB64 );
+ eeCertB64 = 0;
+
+ std::vector< uno::Reference< security::XCertificate > > vecCerts;
+ const ne_ssl_certificate * issuerCert = cert;
+ do
+ {
+ //get the intermediate certificate
+ //the returned value is const ! Therfore it does not need to be freed
+ //with ne_ssl_cert_free, which takes a non-const argument
+ issuerCert = ne_ssl_cert_signedby( issuerCert );
+ if ( NULL == issuerCert )
+ break;
+
+ char * imCertB64 = ne_ssl_cert_export( issuerCert );
+ rtl::OString sInterMediateCertB64( imCertB64 );
+ ne_free( imCertB64 );
+
+ uno::Reference< security::XCertificate> xImCert(
+ xSecurityEnv->createCertificateFromAscii(
+ rtl::OStringToOUString(
+ sInterMediateCertB64, RTL_TEXTENCODING_ASCII_US ) ) );
+ if ( xImCert.is() )
+ vecCerts.push_back( xImCert );
+ }
+ while ( 1 );
+
+ sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xEECert,
+ ::comphelper::containerToSequence( vecCerts ) );
+
+ if ( pSession->isDomainMatch(
+ GetHostnamePart( xEECert.get()->getSubjectName() ) ) )
+ {
+ // if host name matched with certificate then look if the
+ // certificate was ok
+ if( certValidity == security::CertificateValidity::VALID )
+ return 0;
+ }
+
+ const uno::Reference< ucb::XCommandEnvironment > xEnv(
+ pSession->getRequestEnvironment().m_xEnv );
+ if ( xEnv.is() )
+ {
+ failures = static_cast< int >( certValidity );
+
+ uno::Reference< task::XInteractionHandler > xIH(
+ xEnv->getInteractionHandler() );
+ if ( xIH.is() )
+ {
+ rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
+ xRequest( new ucbhelper::SimpleCertificateValidationRequest(
+ (sal_Int32)failures, xEECert, pSession->getHostName() ) );
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ uno::Reference< task::XInteractionApprove > xApprove(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xApprove.is() )
+ {
+ xCertificateContainer->addCertificate(
+ pSession->getHostName(), cert_subject, sal_True );
+ return 0;
+ }
+ else
+ {
+ // Don't trust cert
+ xCertificateContainer->addCertificate(
+ pSession->getHostName(), cert_subject, sal_False );
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ // Don't trust cert
+ xCertificateContainer->addCertificate(
+ pSession->getHostName(), cert_subject, sal_False );
+ return 1;
+ }
+ }
+ return 1;
+}
+
+// -------------------------------------------------------------------
+extern "C" void NeonSession_PreSendRequest( ne_request * req,
+ void * userdata,
+ ne_buffer * headers )
+{
+ // userdata -> value returned by 'create'
+
+ NeonSession * pSession = static_cast< NeonSession * >( userdata );
+ if ( pSession )
+ {
+ // If there is a proxy server in between, it shall never use
+ // cached data. We always want 'up-to-date' data.
+ ne_buffer_concat( headers, "Pragma: no-cache", EOL, NULL );
+ // alternative, but understoud by HTTP 1.1 servers only:
+ // ne_buffer_concat( headers, "Cache-Control: max-age=0", EOL, NULL );
+
+ const RequestDataMap * pRequestData
+ = static_cast< const RequestDataMap* >(
+ pSession->getRequestData() );
+
+ RequestDataMap::const_iterator it = pRequestData->find( req );
+ if ( it != pRequestData->end() )
+ {
+ if ( (*it).second.aContentType.getLength() )
+ {
+ char * pData = headers->data;
+ if ( strstr( pData, "Content-Type:" ) == NULL )
+ {
+ rtl::OString aType
+ = rtl::OUStringToOString( (*it).second.aContentType,
+ RTL_TEXTENCODING_UTF8 );
+ ne_buffer_concat( headers, "Content-Type: ",
+ aType.getStr(), EOL, NULL );
+ }
+ }
+
+ if ( (*it).second.aReferer.getLength() )
+ {
+ char * pData = headers->data;
+ if ( strstr( pData, "Referer:" ) == NULL )
+ {
+ rtl::OString aReferer
+ = rtl::OUStringToOString( (*it).second.aReferer,
+ RTL_TEXTENCODING_UTF8 );
+ ne_buffer_concat( headers, "Referer: ",
+ aReferer.getStr(), EOL, NULL );
+ }
+ }
+ }
+
+ const DAVRequestHeaders & rHeaders
+ = pSession->getRequestEnvironment().m_aRequestHeaders;
+
+ DAVRequestHeaders::const_iterator it1( rHeaders.begin() );
+ const DAVRequestHeaders::const_iterator end1( rHeaders.end() );
+
+ while ( it1 != end1 )
+ {
+ rtl::OString aHeader
+ = rtl::OUStringToOString( (*it1).first,
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OString aValue
+ = rtl::OUStringToOString( (*it1).second,
+ RTL_TEXTENCODING_UTF8 );
+ ne_buffer_concat( headers, aHeader.getStr(), ": ",
+ aValue.getStr(), EOL, NULL );
+
+ ++it1;
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+// static members!
+bool NeonSession::m_bGlobalsInited = false;
+osl::Mutex NeonSession::m_aGlobalMutex;
+NeonLockStore NeonSession::m_aNeonLockStore;
+
+// -------------------------------------------------------------------
+// Constructor
+// -------------------------------------------------------------------
+NeonSession::NeonSession(
+ const rtl::Reference< DAVSessionFactory > & rSessionFactory,
+ const rtl::OUString& inUri,
+ const ucbhelper::InternetProxyDecider & rProxyDecider )
+ throw ( DAVException )
+: DAVSession( rSessionFactory ),
+ m_pHttpSession( 0 ),
+ m_pRequestData( new RequestDataMap ),
+ m_rProxyDecider( rProxyDecider )
+{
+ NeonUri theUri( inUri );
+ m_aScheme = theUri.GetScheme();
+ m_aHostName = theUri.GetHost();
+ m_nPort = theUri.GetPort();
+}
+
+// -------------------------------------------------------------------
+// Destructor
+// -------------------------------------------------------------------
+NeonSession::~NeonSession( )
+{
+ if ( m_pHttpSession )
+ {
+ ne_session_destroy( m_pHttpSession );
+ m_pHttpSession = 0;
+ }
+ delete static_cast< RequestDataMap * >( m_pRequestData );
+}
+
+// -------------------------------------------------------------------
+void NeonSession::Init( const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+ m_aEnv = rEnv;
+ Init();
+}
+
+// -------------------------------------------------------------------
+void NeonSession::Init()
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ bool bCreateNewSession = false;
+
+ if ( m_pHttpSession == 0 )
+ {
+ // Ensure that Neon sockets are initialized
+
+ // --> tkr #151111# crashed if copy and pasted pictures from the internet
+ // ne_sock_init() was executed by two threads at the same time.
+ osl::Guard< osl::Mutex > theGlobalGuard( m_aGlobalMutex );
+ // <--
+ if ( !m_bGlobalsInited )
+ {
+ if ( ne_sock_init() != 0 )
+ throw DAVException( DAVException::DAV_SESSION_CREATE,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ // #122205# - libxml2 needs to be initialized once if used by
+ // multithreaded programs like OOo.
+ xmlInitParser();
+#if 0
+ // for more debug flags see ne_utils.h; NE_DEBUGGING must be defined
+ // while compiling neon in order to actually activate neon debug
+ // output.
+ ne_debug_init( stderr, NE_DBG_FLUSH
+ | NE_DBG_HTTP
+ // | NE_DBG_HTTPBODY
+ // | NE_DBG_HTTPAUTH
+ // | NE_DBG_XML
+ // | NE_DBG_XMLPARSE
+ // | NE_DBG_LOCKS
+ );
+#endif
+ m_bGlobalsInited = true;
+ }
+
+ const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
+
+ m_aProxyName = rProxyCfg.aName;
+ m_nProxyPort = rProxyCfg.nPort;
+
+ // Not yet initialized. Create new session.
+ bCreateNewSession = true;
+ }
+ else
+ {
+ // #112271# Check whether proxy settings are still valid (They may
+ // change at any time). If not, create new Neon session.
+
+ const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
+
+ if ( ( rProxyCfg.aName != m_aProxyName )
+ || ( rProxyCfg.nPort != m_nProxyPort ) )
+ {
+ m_aProxyName = rProxyCfg.aName;
+ m_nProxyPort = rProxyCfg.nPort;
+
+ // new session needed, destroy old first
+ ne_session_destroy( m_pHttpSession );
+ m_pHttpSession = 0;
+ bCreateNewSession = true;
+ }
+ }
+
+ if ( bCreateNewSession )
+ {
+ // @@@ For FTP over HTTP proxy inUserInfo is needed to be able to
+ // build the complete request URI (including user:pass), but
+ // currently (0.22.0) neon does not allow to pass the user info
+ // to the session
+
+ m_pHttpSession = ne_session_create(
+ rtl::OUStringToOString( m_aScheme,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ /* theUri.GetUserInfo(),
+ @@@ for FTP via HTTP proxy, but not supported by Neon */
+ rtl::OUStringToOString( m_aHostName,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ m_nPort );
+
+ if ( m_pHttpSession == 0 )
+ throw DAVException( DAVException::DAV_SESSION_CREATE,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ // Register the session with the lock store
+ m_aNeonLockStore.registerSession( m_pHttpSession );
+
+ if ( m_aScheme.equalsIgnoreAsciiCase(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ) )
+ {
+ // Set a failure callback for certificate check
+ ne_ssl_set_verify(
+ m_pHttpSession, NeonSession_CertificationNotify, this);
+ }
+
+ // Add hooks (i.e. for adding additional headers to the request)
+
+#if 0
+ /* Hook called when a request is created. */
+ //typedef void (*ne_create_request_fn)(ne_request *req, void *userdata,
+ // const char *method, const char *path);
+
+ ne_hook_create_request( m_pHttpSession, create_req_hook_fn, this );
+#endif
+
+ /* Hook called before the request is sent. 'header' is the raw HTTP
+ * header before the trailing CRLF is added: add in more here. */
+ //typedef void (*ne_pre_send_fn)(ne_request *req, void *userdata,
+ // ne_buffer *header);
+
+ ne_hook_pre_send( m_pHttpSession, NeonSession_PreSendRequest, this );
+#if 0
+ /* Hook called after the request is sent. May return:
+ * NE_OK everything is okay
+ * NE_RETRY try sending the request again.
+ * anything else signifies an error, and the request is failed. The
+ * return code is passed back the _dispatch caller, so the session error
+ * must also be set appropriately (ne_set_error).
+ */
+ //typedef int (*ne_post_send_fn)(ne_request *req, void *userdata,
+ // const ne_status *status);
+
+ ne_hook_post_send( m_pHttpSession, post_send_req_hook_fn, this );
+
+ /* Hook called when the request is destroyed. */
+ //typedef void (*ne_destroy_req_fn)(ne_request *req, void *userdata);
+
+ ne_hook_destroy_request( m_pHttpSession, destroy_req_hook_fn, this );
+
+ /* Hook called when the session is destroyed. */
+ //typedef void (*ne_destroy_sess_fn)(void *userdata);
+
+ ne_hook_destroy_session( m_pHttpSession, destroy_sess_hook_fn, this );
+#endif
+
+ if ( m_aProxyName.getLength() )
+ {
+ ne_session_proxy( m_pHttpSession,
+ rtl::OUStringToOString(
+ m_aProxyName,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ m_nProxyPort );
+ }
+
+ // Register for redirects.
+ ne_redirect_register( m_pHttpSession );
+
+ // authentication callbacks.
+ ne_add_server_auth(
+ m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
+ ne_add_proxy_auth(
+ m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
+ }
+}
+
+// -------------------------------------------------------------------
+// virtual
+sal_Bool NeonSession::CanUse( const rtl::OUString & inUri )
+{
+ try
+ {
+ NeonUri theUri( inUri );
+ if ( ( theUri.GetPort() == m_nPort ) &&
+ ( theUri.GetHost() == m_aHostName ) &&
+ ( theUri.GetScheme() == m_aScheme ) )
+ return sal_True;
+ }
+ catch ( DAVException const & )
+ {
+ return sal_False;
+ }
+ return sal_False;
+}
+
+// -------------------------------------------------------------------
+// virtual
+sal_Bool NeonSession::UsesProxy()
+{
+ Init();
+ return ( m_aProxyName.getLength() > 0 );
+}
+
+// -------------------------------------------------------------------
+// OPTIONS
+// -------------------------------------------------------------------
+void NeonSession::OPTIONS( const rtl::OUString & inPath,
+ DAVCapabilities & outCapabilities,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ HttpServerCapabilities servercaps;
+ memset( &servercaps, 0, sizeof( servercaps ) );
+
+ int theRetVal = ne_options( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ &servercaps );
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ outCapabilities.class1 = !!servercaps.dav_class1;
+ outCapabilities.class2 = !!servercaps.dav_class2;
+ outCapabilities.executable = !!servercaps.dav_executable;
+}
+
+// -------------------------------------------------------------------
+// PROPFIND - allprop & named
+// -------------------------------------------------------------------
+void NeonSession::PROPFIND( const rtl::OUString & inPath,
+ const Depth inDepth,
+ const std::vector< rtl::OUString > & inPropNames,
+ std::vector< DAVResource > & ioResources,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ int theRetVal = NE_OK;
+ NeonPropFindRequest theRequest( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ inDepth,
+ inPropNames,
+ ioResources,
+ theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// PROPFIND - propnames
+// -------------------------------------------------------------------
+void NeonSession::PROPFIND( const rtl::OUString & inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo > & ioResInfo,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ int theRetVal = NE_OK;
+ NeonPropFindRequest theRequest( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ inDepth,
+ ioResInfo,
+ theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// PROPPATCH
+// -------------------------------------------------------------------
+void NeonSession::PROPPATCH( const rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException )
+{
+ /* @@@ Which standard live properties can be set by the client?
+ This is a known WebDAV RFC issue ( verified: 04/10/2001 )
+ --> http://www.ics.uci.edu/pub/ietf/webdav/protocol/issues.html
+
+ mod_dav implementation:
+
+ creationdate r ( File System prop )
+ displayname w
+ getcontentlanguage r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS )
+ getcontentlength r ( File System prop )
+ getcontenttype r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS )
+ getetag r ( File System prop )
+ getlastmodified r ( File System prop )
+ lockdiscovery r
+ resourcetype r
+ source w
+ supportedlock r
+ executable w ( #ifndef WIN32 )
+
+ All dead properties are of course writable.
+ */
+
+ int theRetVal = NE_OK;
+
+ int n; // for the "for" loop
+
+ // Generate the list of properties we want to set.
+ int nPropCount = inValues.size();
+ ne_proppatch_operation* pItems
+ = new ne_proppatch_operation[ nPropCount + 1 ];
+ for ( n = 0; n < nPropCount; ++n )
+ {
+ const ProppatchValue & rValue = inValues[ n ];
+
+ // Split fullname into namespace and name!
+ ne_propname * pName = new ne_propname;
+ DAVProperties::createNeonPropName( rValue.name, *pName );
+ pItems[ n ].name = pName;
+
+ if ( rValue.operation == PROPSET )
+ {
+ pItems[ n ].type = ne_propset;
+
+ rtl::OUString aStringValue;
+ if ( DAVProperties::isUCBDeadProperty( *pName ) )
+ {
+ // DAV dead property added by WebDAV UCP?
+ if ( !UCBDeadPropertyValue::toXML( rValue.value,
+ aStringValue ) )
+ {
+ // Error!
+ pItems[ n ].value = 0;
+ theRetVal = NE_ERROR;
+ nPropCount = n + 1;
+ break;
+ }
+ }
+ else if ( !( rValue.value >>= aStringValue ) )
+ {
+ // complex properties...
+ if ( rValue.name == DAVProperties::SOURCE )
+ {
+ uno::Sequence< ucb::Link > aLinks;
+ if ( rValue.value >>= aLinks )
+ {
+ LinkSequence::toXML( aLinks, aStringValue );
+ }
+ else
+ {
+ // Error!
+ pItems[ n ].value = 0;
+ theRetVal = NE_ERROR;
+ nPropCount = n + 1;
+ break;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "NeonSession::PROPPATCH - unsupported type!" );
+ // Error!
+ pItems[ n ].value = 0;
+ theRetVal = NE_ERROR;
+ nPropCount = n + 1;
+ break;
+ }
+ }
+ pItems[ n ].value
+ = strdup( rtl::OUStringToOString( aStringValue,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ pItems[ n ].type = ne_propremove;
+ pItems[ n ].value = 0;
+ }
+ }
+
+ if ( theRetVal == NE_OK )
+ {
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ pItems[ n ].name = 0;
+
+ theRetVal = ne_proppatch( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ pItems );
+ }
+
+ for ( n = 0; n < nPropCount; ++n )
+ {
+ free( (void *)pItems[ n ].name->name );
+ delete pItems[ n ].name;
+ free( (void *)pItems[ n ].value );
+ }
+
+ delete [] pItems;
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// HEAD
+// -------------------------------------------------------------------
+void NeonSession::HEAD( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ int theRetVal = NE_OK;
+ NeonHeadRequest theRequest( m_pHttpSession,
+ inPath,
+ inHeaderNames,
+ ioResource,
+ theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// GET
+// -------------------------------------------------------------------
+uno::Reference< io::XInputStream >
+NeonSession::GET( const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
+ NeonRequestContext aCtx( xInputStream );
+ int theRetVal = GET( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ NeonSession_ResponseBlockReader,
+ false,
+ &aCtx );
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ return uno::Reference< io::XInputStream >( xInputStream.get() );
+}
+
+// -------------------------------------------------------------------
+// GET
+// -------------------------------------------------------------------
+void NeonSession::GET( const rtl::OUString & inPath,
+ uno::Reference< io::XOutputStream > & ioOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ NeonRequestContext aCtx( ioOutputStream );
+ int theRetVal = GET( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ NeonSession_ResponseBlockWriter,
+ false,
+ &aCtx );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// GET
+// -------------------------------------------------------------------
+uno::Reference< io::XInputStream >
+NeonSession::GET( const rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ ioResource.uri = inPath;
+ ioResource.properties.clear();
+
+ rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
+ NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource );
+ int theRetVal = GET( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ NeonSession_ResponseBlockReader,
+ true,
+ &aCtx );
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ return uno::Reference< io::XInputStream >( xInputStream.get() );
+}
+
+// -------------------------------------------------------------------
+// GET
+// -------------------------------------------------------------------
+void NeonSession::GET( const rtl::OUString & inPath,
+ uno::Reference< io::XOutputStream > & ioOutputStream,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ ioResource.uri = inPath;
+ ioResource.properties.clear();
+
+ NeonRequestContext aCtx( ioOutputStream, inHeaderNames, ioResource );
+ int theRetVal = GET( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ NeonSession_ResponseBlockWriter,
+ true,
+ &aCtx );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// PUT
+// -------------------------------------------------------------------
+void NeonSession::PUT( const rtl::OUString & inPath,
+ const uno::Reference< io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ uno::Sequence< sal_Int8 > aDataToSend;
+ if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ Init( rEnv );
+
+ int theRetVal = PUT( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ reinterpret_cast< const char * >(
+ aDataToSend.getConstArray() ),
+ aDataToSend.getLength() );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// POST
+// -------------------------------------------------------------------
+uno::Reference< io::XInputStream >
+NeonSession::POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const uno::Reference< io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ uno::Sequence< sal_Int8 > aDataToSend;
+ if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ Init( rEnv );
+
+ rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
+ NeonRequestContext aCtx( xInputStream );
+ int theRetVal = POST( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ reinterpret_cast< const char * >(
+ aDataToSend.getConstArray() ),
+ NeonSession_ResponseBlockReader,
+ &aCtx,
+ rContentType,
+ rReferer );
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ return uno::Reference< io::XInputStream >( xInputStream.get() );
+}
+
+// -------------------------------------------------------------------
+// POST
+// -------------------------------------------------------------------
+void NeonSession::POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const uno::Reference< io::XInputStream > & inInputStream,
+ uno::Reference< io::XOutputStream > & oOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ uno::Sequence< sal_Int8 > aDataToSend;
+ if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ Init( rEnv );
+
+ NeonRequestContext aCtx( oOutputStream );
+ int theRetVal = POST( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ),
+ reinterpret_cast< const char * >(
+ aDataToSend.getConstArray() ),
+ NeonSession_ResponseBlockWriter,
+ &aCtx,
+ rContentType,
+ rReferer );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// MKCOL
+// -------------------------------------------------------------------
+void NeonSession::MKCOL( const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ int theRetVal = ne_mkcol( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// COPY
+// -------------------------------------------------------------------
+void NeonSession::COPY( const rtl::OUString & inSourceURL,
+ const rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ NeonUri theSourceUri( inSourceURL );
+ NeonUri theDestinationUri( inDestinationURL );
+
+ int theRetVal = ne_copy( m_pHttpSession,
+ inOverWrite ? 1 : 0,
+ NE_DEPTH_INFINITE,
+ rtl::OUStringToOString(
+ theSourceUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ),
+ rtl::OUStringToOString(
+ theDestinationUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inSourceURL, rEnv );
+}
+
+// -------------------------------------------------------------------
+// MOVE
+// -------------------------------------------------------------------
+void NeonSession::MOVE( const rtl::OUString & inSourceURL,
+ const rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ NeonUri theSourceUri( inSourceURL );
+ NeonUri theDestinationUri( inDestinationURL );
+ int theRetVal = ne_move( m_pHttpSession,
+ inOverWrite ? 1 : 0,
+ rtl::OUStringToOString(
+ theSourceUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ),
+ rtl::OUStringToOString(
+ theDestinationUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inSourceURL, rEnv );
+}
+
+// -------------------------------------------------------------------
+// DESTROY
+// -------------------------------------------------------------------
+void NeonSession::DESTROY( const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ int theRetVal = ne_delete( m_pHttpSession,
+ rtl::OUStringToOString(
+ inPath, RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+namespace
+{
+ sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
+ int timeout )
+ {
+ TimeValue aEnd;
+ osl_getSystemTime( &aEnd );
+
+ // Try to estimate a safe absolute time for sending the
+ // lock refresh request.
+ sal_Int32 lastChanceToSendRefreshRequest = -1;
+ if ( timeout != NE_TIMEOUT_INFINITE )
+ {
+ sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
+ if ( calltime <= timeout )
+ {
+ lastChanceToSendRefreshRequest
+ = aEnd.Seconds + timeout - calltime;
+ }
+ else
+ {
+ OSL_TRACE( "No chance to refresh lock before timeout!" );
+ }
+ }
+ return lastChanceToSendRefreshRequest;
+ }
+
+} // namespace
+
+// -------------------------------------------------------------------
+// LOCK (set new lock)
+// -------------------------------------------------------------------
+void NeonSession::LOCK( const ::rtl::OUString & inPath,
+ ucb::Lock & rLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ Init( rEnv );
+
+ /* Create a depth zero, exclusive write lock, with default timeout
+ * (allowing a server to pick a default). token, owner and uri are
+ * unset. */
+ NeonLock * theLock = ne_lock_create();
+
+ // Set the lock uri
+ ne_uri aUri;
+ ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ &aUri );
+ theLock->uri = aUri;
+
+ // Set the lock depth
+ switch( rLock.Depth )
+ {
+ case ucb::LockDepth_ZERO:
+ theLock->depth = NE_DEPTH_ZERO;
+ break;
+ case ucb::LockDepth_ONE:
+ theLock->depth = NE_DEPTH_ONE;
+ break;
+ case ucb::LockDepth_INFINITY:
+ theLock->depth = NE_DEPTH_INFINITE;
+ break;
+ default:
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ }
+
+ // Set the lock scope
+ switch ( rLock.Scope )
+ {
+ case ucb::LockScope_EXCLUSIVE:
+ theLock->scope = ne_lockscope_exclusive;
+ break;
+ case ucb::LockScope_SHARED:
+ theLock->scope = ne_lockscope_shared;
+ break;
+ default:
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ }
+
+ // Set the lock timeout
+ theLock->timeout = (long)rLock.Timeout;
+
+ // Set the lock owner
+ rtl::OUString aValue;
+ rLock.Owner >>= aValue;
+ theLock->owner =
+ ne_strdup( rtl::OUStringToOString( aValue,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ int theRetVal = ne_lock( m_pHttpSession, theLock );
+
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.addLock( theLock,
+ this,
+ lastChanceToSendRefreshRequest(
+ startCall, theLock->timeout ) );
+
+ uno::Sequence< rtl::OUString > aTokens( 1 );
+ aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token );
+ rLock.LockTokens = aTokens;
+
+ OSL_TRACE( "NeonSession::LOCK: created lock for %s. token: %s",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ theLock->token );
+ }
+ else
+ {
+ ne_lock_destroy( theLock );
+
+ OSL_TRACE( "NeonSession::LOCK: obtaining lock for %s failed!",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// LOCK (refresh existing lock)
+// -------------------------------------------------------------------
+sal_Int64 NeonSession::LOCK( const ::rtl::OUString & inPath,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ // Try to get the neon lock from lock store
+ NeonLock * theLock
+ = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
+ if ( !theLock )
+ throw DAVException( DAVException::DAV_NOT_LOCKED );
+
+ Init( rEnv );
+
+ // refresh existing lock.
+ theLock->timeout = static_cast< long >( nTimeout );
+
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
+
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.updateLock( theLock,
+ lastChanceToSendRefreshRequest(
+ startCall, theLock->timeout ) );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ return theLock->timeout;
+}
+
+// -------------------------------------------------------------------
+// LOCK (refresh existing lock)
+// -------------------------------------------------------------------
+bool NeonSession::LOCK( NeonLock * pLock,
+ sal_Int32 & rlastChanceToSendRefreshRequest )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+#if OSL_DEBUG_LEVEL > 0
+ char * p = ne_uri_unparse( &(pLock->uri) );
+ OSL_TRACE( "NeonSession::LOCK: Refreshing lock for %s.", p );
+ ne_free( p );
+#endif
+
+ // refresh existing lock.
+
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK )
+ {
+ rlastChanceToSendRefreshRequest
+ = lastChanceToSendRefreshRequest( startCall, pLock->timeout );
+
+ OSL_TRACE( "Lock successfully refreshed." );
+ return true;
+ }
+ else
+ {
+ OSL_TRACE( "Lock not refreshed!" );
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+// UNLOCK
+// -------------------------------------------------------------------
+void NeonSession::UNLOCK( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ // get the neon lock from lock store
+ NeonLock * theLock
+ = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
+ if ( !theLock )
+ throw DAVException( DAVException::DAV_NOT_LOCKED );
+
+ Init( rEnv );
+
+ int theRetVal = ne_unlock( m_pHttpSession, theLock );
+
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.removeLock( theLock );
+ ne_lock_destroy( theLock );
+ }
+ else
+ {
+ OSL_TRACE( "NeonSession::UNLOCK: unlocking of %s failed.",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// UNLOCK
+// -------------------------------------------------------------------
+bool NeonSession::UNLOCK( NeonLock * pLock )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+#if OSL_DEBUG_LEVEL > 0
+ char * p = ne_uri_unparse( &(pLock->uri) );
+ OSL_TRACE( "NeonSession::UNLOCK: Unlocking %s.", p );
+ ne_free( p );
+#endif
+
+ if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK )
+ {
+ OSL_TRACE( "UNLOCK succeeded." );
+ return true;
+ }
+ else
+ {
+ OSL_TRACE( "UNLOCK failed!" );
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonSession::abort()
+ throw ( DAVException )
+{
+ // 11.11.09 (tkr): The following code lines causing crashes if
+ // closing a ongoing connection. It turned out that this existing
+ // solution doesn't work in multi-threading environments.
+ // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
+ //if ( m_pHttpSession )
+ // ne_close_connection( m_pHttpSession );
+}
+
+// -------------------------------------------------------------------
+const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
+{
+ if ( m_aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) ||
+ m_aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) )
+ {
+ return m_rProxyDecider.getProxy( m_aScheme,
+ m_aHostName,
+ m_nPort );
+ }
+ else
+ {
+ return m_rProxyDecider.getProxy( m_aScheme,
+ rtl::OUString() /* not used */,
+ -1 /* not used */ );
+ }
+}
+
+// -------------------------------------------------------------------
+namespace {
+
+bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
+ const char * token )
+{
+ for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
+ {
+ const uno::Sequence< rtl::OUString > & rTokens
+ = rLocks[ n ].LockTokens;
+ for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
+ {
+ if ( rTokens[ m ].equalsAscii( token ) )
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+// -------------------------------------------------------------------
+bool NeonSession::removeExpiredLocktoken( const rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv )
+{
+ NeonLock * theLock = m_aNeonLockStore.findByUri( inURL );
+ if ( !theLock )
+ return false;
+
+ // do a lockdiscovery to check whether this lock is still valid.
+ try
+ {
+ // @@@ Alternative: use ne_lock_discover() => less overhead
+
+ std::vector< DAVResource > aResources;
+ std::vector< rtl::OUString > aPropNames;
+ aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
+
+ PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
+
+ if ( aResources.size() == 0 )
+ return false;
+
+ std::vector< DAVPropertyValue >::const_iterator it
+ = aResources[ 0 ].properties.begin();
+ std::vector< DAVPropertyValue >::const_iterator end
+ = aResources[ 0 ].properties.end();
+
+ while ( it != end )
+ {
+ if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
+ {
+ uno::Sequence< ucb::Lock > aLocks;
+ if ( !( (*it).Value >>= aLocks ) )
+ return false;
+
+ if ( !containsLocktoken( aLocks, theLock->token ) )
+ {
+ // expired!
+ break;
+ }
+
+ // still valid.
+ return false;
+ }
+ ++it;
+ }
+
+ // No lockdiscovery prop in propfind result / locktoken not found
+ // in propfind result -> not locked
+ OSL_TRACE( "NeonSession::removeExpiredLocktoken: Removing "
+ " expired lock token for %s. token: %s",
+ rtl::OUStringToOString( inURL,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ theLock->token );
+
+ m_aNeonLockStore.removeLock( theLock );
+ ne_lock_destroy( theLock );
+ return true;
+ }
+ catch ( DAVException const & )
+ {
+ }
+ return false;
+}
+
+// -------------------------------------------------------------------
+// HandleError
+// Common Error Handler
+// -------------------------------------------------------------------
+void NeonSession::HandleError( int nError,
+ const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ m_aEnv = DAVRequestEnvironment();
+
+ // Map error code to DAVException.
+ switch ( nError )
+ {
+ case NE_OK:
+ return;
+
+ case NE_ERROR: // Generic error
+ {
+ rtl::OUString aText = rtl::OUString::createFromAscii(
+ ne_get_error( m_pHttpSession ) );
+
+ sal_uInt16 code = makeStatusCode( aText );
+
+ if ( code == SC_LOCKED )
+ {
+ if ( m_aNeonLockStore.findByUri(
+ makeAbsoluteURL( inPath ) ) == 0 )
+ {
+ // locked by 3rd party
+ throw DAVException( DAVException::DAV_LOCKED );
+ }
+ else
+ {
+ // locked by ourself
+ throw DAVException( DAVException::DAV_LOCKED_SELF );
+ }
+ }
+
+ // Special handling for 400 and 412 status codes, which may indicate
+ // that a lock previously obtained by us has been released meanwhile
+ // by the server. Unfortunately, RFC is not clear at this point,
+ // thus server implementations behave different...
+ else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
+ {
+ if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
+ throw DAVException( DAVException::DAV_LOCK_EXPIRED );
+ }
+
+ throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
+ }
+ case NE_LOOKUP: // Name lookup failed.
+ throw DAVException( DAVException::DAV_HTTP_LOOKUP,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_AUTH: // User authentication failed on server
+ throw DAVException( DAVException::DAV_HTTP_AUTH,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_PROXYAUTH: // User authentication failed on proxy
+ throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
+ NeonUri::makeConnectionEndPointString(
+ m_aProxyName, m_nProxyPort ) );
+
+ case NE_CONNECT: // Could not connect to server
+ throw DAVException( DAVException::DAV_HTTP_CONNECT,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_TIMEOUT: // Connection timed out
+ throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_FAILED: // The precondition failed
+ throw DAVException( DAVException::DAV_HTTP_FAILED,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_RETRY: // Retry request (ne_end_request ONLY)
+ throw DAVException( DAVException::DAV_HTTP_RETRY,
+ NeonUri::makeConnectionEndPointString(
+ m_aHostName, m_nPort ) );
+
+ case NE_REDIRECT:
+ {
+ NeonUri aUri( ne_redirect_location( m_pHttpSession ) );
+ throw DAVException(
+ DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
+ }
+ default:
+ {
+ OSL_TRACE( "NeonSession::HandleError : Unknown Neon error code!" );
+ throw DAVException( DAVException::DAV_HTTP_ERROR,
+ rtl::OUString::createFromAscii(
+ ne_get_error( m_pHttpSession ) ) );
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+namespace {
+
+void runResponseHeaderHandler( void * userdata,
+ const char * value )
+{
+ rtl::OUString aHeader( rtl::OUString::createFromAscii( value ) );
+ sal_Int32 nPos = aHeader.indexOf( ':' );
+
+ if ( nPos != -1 )
+ {
+ rtl::OUString aHeaderName( aHeader.copy( 0, nPos ) );
+
+ NeonRequestContext * pCtx
+ = static_cast< NeonRequestContext * >( userdata );
+
+ // Note: Empty vector means that all headers are requested.
+ bool bIncludeIt = ( pCtx->pHeaderNames->size() == 0 );
+
+ if ( !bIncludeIt )
+ {
+ // Check whether this header was requested.
+ std::vector< ::rtl::OUString >::const_iterator it(
+ pCtx->pHeaderNames->begin() );
+ const std::vector< ::rtl::OUString >::const_iterator end(
+ pCtx->pHeaderNames->end() );
+
+ while ( it != end )
+ {
+ // header names are case insensitive
+ if ( (*it).equalsIgnoreAsciiCase( aHeaderName ) )
+ {
+ aHeaderName = (*it);
+ break;
+ }
+ ++it;
+ }
+
+ if ( it != end )
+ bIncludeIt = true;
+ }
+
+ if ( bIncludeIt )
+ {
+ // Create & set the PropertyValue
+ DAVPropertyValue thePropertyValue;
+ thePropertyValue.IsCaseSensitive = false;
+ thePropertyValue.Name = aHeaderName;
+
+ if ( nPos < aHeader.getLength() )
+ thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim();
+
+ // Add the newly created PropertyValue
+ pCtx->pResource->properties.push_back( thePropertyValue );
+ }
+ }
+}
+
+} // namespace
+
+// -------------------------------------------------------------------
+// static
+int NeonSession::GET( ne_session * sess,
+ const char * uri,
+ ne_block_reader reader,
+ bool getheaders,
+ void * userdata )
+{
+ //struct get_context ctx;
+ ne_request * req = ne_request_create( sess, "GET", uri );
+ int ret;
+ void *cursor = NULL;
+ const char *name, *value;
+
+#if NEON_VERSION < 0x0250
+ if ( getheaders )
+ ne_add_response_header_catcher(
+ req, runResponseHeaderHandler, userdata );
+#endif
+ ne_decompress * dc
+ = ne_decompress_reader( req, ne_accept_2xx, reader, userdata );
+
+ ret = ne_request_dispatch( req );
+
+#if NEON_VERSION >= 0x0250
+ if ( getheaders )
+ {
+ while ( ( cursor = ne_response_header_iterate(
+ req, cursor, &name, &value ) ) != NULL )
+ {
+ char buffer[8192];
+
+ ne_snprintf(buffer, sizeof buffer, "%s: %s", name, value);
+ runResponseHeaderHandler(userdata, buffer);
+ }
+ }
+#endif
+ if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
+ ret = NE_ERROR;
+
+ if ( dc != 0 )
+ ne_decompress_destroy(dc);
+
+ ne_request_destroy( req );
+ return ret;
+}
+
+// -------------------------------------------------------------------
+// static
+int NeonSession::PUT( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ size_t size)
+{
+ ne_request * req = ne_request_create( sess, "PUT", uri );
+ int ret;
+
+ ne_lock_using_resource( req, uri, 0 );
+ ne_lock_using_parent( req, uri );
+
+ ne_set_request_body_buffer( req, buffer, size );
+
+ ret = ne_request_dispatch( req );
+
+ if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
+ ret = NE_ERROR;
+
+ ne_request_destroy( req );
+ return ret;
+}
+
+// -------------------------------------------------------------------
+int NeonSession::POST( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ ne_block_reader reader,
+ void * userdata,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer )
+{
+ ne_request * req = ne_request_create( sess, "POST", uri );
+ //struct get_context ctx;
+ int ret;
+
+ RequestDataMap * pData = 0;
+
+ if ( rContentType.getLength() || rReferer.getLength() )
+ {
+ // Remember contenttype and referer. Data will be added to HTTP request
+ // header in in 'PreSendRequest' callback.
+ pData = static_cast< RequestDataMap* >( m_pRequestData );
+ (*pData)[ req ] = RequestData( rContentType, rReferer );
+ }
+
+ //ctx.total = -1;
+ //ctx.fd = fd;
+ //ctx.error = 0;
+ //ctx.session = sess;
+
+ ///* Read the value of the Content-Length header into ctx.total */
+ //ne_add_response_header_handler( req, "Content-Length",
+ // ne_handle_numeric_header, &ctx.total );
+
+ ne_add_response_body_reader( req, ne_accept_2xx, reader, userdata );
+
+ ne_set_request_body_buffer( req, buffer, strlen( buffer ) );
+
+ ret = ne_request_dispatch( req );
+
+ //if ( ctx.error )
+ // ret = NE_ERROR;
+ //else
+ if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
+ ret = NE_ERROR;
+
+ ne_request_destroy( req );
+
+ if ( pData )
+ {
+ // Remove request data from session's list.
+ RequestDataMap::iterator it = pData->find( req );
+ if ( it != pData->end() )
+ pData->erase( it );
+ }
+
+ return ret;
+}
+
+// -------------------------------------------------------------------
+// static
+bool
+NeonSession::getDataFromInputStream(
+ const uno::Reference< io::XInputStream > & xStream,
+ uno::Sequence< sal_Int8 > & rData,
+ bool bAppendTrailingZeroByte )
+{
+ if ( xStream.is() )
+ {
+ uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
+ if ( xSeekable.is() )
+ {
+ try
+ {
+ sal_Int32 nSize
+ = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
+ sal_Int32 nRead
+ = xStream->readBytes( rData, nSize );
+
+ if ( nRead == nSize )
+ {
+ if ( bAppendTrailingZeroByte )
+ {
+ rData.realloc( nSize + 1 );
+ rData[ nSize ] = sal_Int8( 0 );
+ }
+ return true;
+ }
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // readBytes
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // readBytes
+ }
+ catch ( io::IOException const & )
+ {
+ // getLength, readBytes
+ }
+ }
+ else
+ {
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nPos = 0;
+
+ sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
+ while ( nRead > 0 )
+ {
+ if ( rData.getLength() < ( nPos + nRead ) )
+ rData.realloc( nPos + nRead );
+
+ aBuffer.realloc( nRead );
+ rtl_copyMemory( (void*)( rData.getArray() + nPos ),
+ (const void*)aBuffer.getConstArray(),
+ nRead );
+ nPos += nRead;
+
+ aBuffer.realloc( 0 );
+ nRead = xStream->readSomeBytes( aBuffer, 65536 );
+ }
+
+ if ( bAppendTrailingZeroByte )
+ {
+ rData.realloc( nPos + 1 );
+ rData[ nPos ] = sal_Int8( 0 );
+ }
+ return true;
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // readBytes
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // readBytes
+ }
+ catch ( io::IOException const & )
+ {
+ // readBytes
+ }
+ }
+ }
+ return false;
+}
+
+// ---------------------------------------------------------------------
+sal_Bool
+NeonSession::isDomainMatch( rtl::OUString certHostName )
+{
+ rtl::OUString hostName = getHostName();
+
+ if (hostName.equalsIgnoreAsciiCase( certHostName ) )
+ return sal_True;
+
+ if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
+ hostName.getLength() >= certHostName.getLength() )
+ {
+ rtl::OUString cmpStr = certHostName.copy( 1 );
+
+ if ( hostName.matchIgnoreAsciiCase(
+ cmpStr, hostName.getLength() - cmpStr.getLength() ) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+// ---------------------------------------------------------------------
+rtl::OUString NeonSession::makeAbsoluteURL( rtl::OUString const & rURL ) const
+{
+ try
+ {
+ // Is URL relative or already absolute?
+ if ( rURL[ 0 ] != sal_Unicode( '/' ) )
+ {
+ // absolute.
+ return rtl::OUString( rURL );
+ }
+ else
+ {
+ ne_uri aUri;
+ memset( &aUri, 0, sizeof( aUri ) );
+
+ ne_fill_server_uri( m_pHttpSession, &aUri );
+ aUri.path
+ = ne_strdup( rtl::OUStringToOString(
+ rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+ NeonUri aNeonUri( &aUri );
+ ne_uri_free( &aUri );
+ return aNeonUri.GetURI();
+ }
+ }
+ catch ( DAVException const & )
+ {
+ }
+ // error.
+ return rtl::OUString();
+}
diff --git a/ucb/source/ucp/webdav/NeonSession.hxx b/ucb/source/ucp/webdav/NeonSession.hxx
new file mode 100644
index 000000000000..65c2c25e4ec9
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonSession.hxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NEONSESSION_HXX_
+#define _NEONSESSION_HXX_
+
+#include <vector>
+#include <osl/mutex.hxx>
+#include "DAVSession.hxx"
+#include "NeonTypes.hxx"
+#include "NeonLockStore.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace ucbhelper { class ProxyDecider; }
+
+namespace webdav_ucp
+{
+
+// -------------------------------------------------------------------
+// NeonSession
+// A DAVSession implementation using the neon/expat library
+// -------------------------------------------------------------------
+
+class NeonSession : public DAVSession
+{
+private:
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aScheme;
+ rtl::OUString m_aHostName;
+ rtl::OUString m_aProxyName;
+ sal_Int32 m_nPort;
+ sal_Int32 m_nProxyPort;
+ HttpSession * m_pHttpSession;
+ void * m_pRequestData;
+ const ucbhelper::InternetProxyDecider & m_rProxyDecider;
+
+ // @@@ This should really be per-request data. But Neon currently
+ // (0.23.5) has no interface for passing per-request user data.
+ // Theoretically, a NeonSession instance could handle multiple requests
+ // at a time --currently it doesn't. Thus this is not an issue at the
+ // moment.
+ DAVRequestEnvironment m_aEnv;
+
+ static bool m_bGlobalsInited;
+ static osl::Mutex m_aGlobalMutex;
+ static NeonLockStore m_aNeonLockStore;
+
+protected:
+ virtual ~NeonSession();
+
+public:
+ NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
+ const rtl::OUString& inUri,
+ const ucbhelper::InternetProxyDecider & rProxyDecider )
+ throw ( DAVException );
+
+ // DAVSession methods
+ virtual sal_Bool CanUse( const ::rtl::OUString & inUri );
+
+ virtual sal_Bool UsesProxy();
+
+ const DAVRequestEnvironment & getRequestEnvironment() const
+ { return m_aEnv; }
+
+ virtual void
+ OPTIONS( const ::rtl::OUString & inPath,
+ DAVCapabilities & outCapabilities,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // allprop & named
+ virtual void
+ PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ const std::vector< ::rtl::OUString > & inPropNames,
+ std::vector< DAVResource > & ioResources,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // propnames
+ virtual void
+ PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo >& ioResInfo,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ PROPPATCH( const ::rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ HEAD( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & ioOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & ioOutputStream,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ PUT( const ::rtl::OUString & inPath,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & oOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ MKCOL( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ COPY( const ::rtl::OUString & inSourceURL,
+ const ::rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException );
+
+ virtual void
+ MOVE( const ::rtl::OUString & inSourceURL,
+ const ::rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException );
+
+ virtual void DESTROY( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // set new lock.
+ virtual void LOCK( const ::rtl::OUString & inURL,
+ com::sun::star::ucb::Lock & inLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // refresh existing lock.
+ virtual sal_Int64 LOCK( const ::rtl::OUString & inURL,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void UNLOCK( const ::rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // helpers
+ virtual void abort()
+ throw ( DAVException );
+
+ const rtl::OUString & getHostName() const { return m_aHostName; }
+
+ const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF()
+ { return m_xFactory->getServiceFactory(); }
+
+ const void * getRequestData() const { return m_pRequestData; }
+
+ sal_Bool isDomainMatch( rtl::OUString certHostName );
+
+private:
+ friend class NeonLockStore;
+
+ void Init( void )
+ throw ( DAVException );
+
+ void Init( const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // ret: true => retry request.
+ void HandleError( int nError,
+ const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ const ucbhelper::InternetProxyServer & getProxySettings() const;
+
+ bool removeExpiredLocktoken( const rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv );
+
+ // refresh lock, called by NeonLockStore::refreshLocks
+ bool LOCK( NeonLock * pLock,
+ sal_Int32 & rlastChanceToSendRefreshRequest );
+
+ // unlock, called by NeonLockStore::~NeonLockStore
+ bool UNLOCK( NeonLock * pLock );
+
+ // low level GET implementation, used by public GET implementations
+ static int GET( ne_session * sess,
+ const char * uri,
+ ne_block_reader reader,
+ bool getheaders,
+ void * userdata );
+
+ // Buffer-based PUT implementation. Neon only has file descriptor-
+ // based API.
+ static int PUT( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ size_t size );
+
+ // Buffer-based POST implementation. Neon only has file descriptor-
+ // based API.
+ int POST( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ ne_block_reader reader,
+ void * userdata,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer );
+
+ // Helper: XInputStream -> Sequence< sal_Int8 >
+ static bool getDataFromInputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & xStream,
+ com::sun::star::uno::Sequence< sal_Int8 > & rData,
+ bool bAppendTrailingZeroByte );
+
+ rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const;
+};
+
+} // namespace webdav_ucp
+
+#endif // _NEONSESSION_HXX_
diff --git a/ucb/source/ucp/webdav/NeonTypes.hxx b/ucb/source/ucp/webdav/NeonTypes.hxx
new file mode 100644
index 000000000000..21902f352691
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonTypes.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NEONTYPES_HXX_
+#define _NEONTYPES_HXX_
+
+#include <ne_session.h>
+#include <ne_utils.h>
+#include <ne_basic.h>
+#include <ne_props.h>
+#include <ne_locks.h>
+
+typedef ne_session HttpSession;
+typedef ne_status HttpStatus;
+typedef ne_server_capabilities HttpServerCapabilities;
+
+typedef ne_propname NeonPropName;
+typedef ne_prop_result_set NeonPropFindResultSet;
+
+typedef struct ne_lock NeonLock;
+
+#endif // _NEONTYPES_HXX_
diff --git a/ucb/source/ucp/webdav/NeonUri.cxx b/ucb/source/ucp/webdav/NeonUri.cxx
new file mode 100644
index 000000000000..774faa06b9dd
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonUri.cxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include <rtl/uri.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "ne_alloc.h"
+#include "NeonUri.hxx"
+#include "DAVException.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace webdav_ucp;
+
+# if defined __SUNPRO_CC
+// FIXME: not sure whether initializing a ne_uri statically is supposed to work
+// the string fields of ne_uri are char*, not const char*
+# pragma disable_warn
+# endif
+
+#if defined __GNUC__
+#define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+/* Diagnostics pragma was introduced with gcc-4.2.1 */
+#if GCC_VERSION > 40201
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+#endif
+#endif
+
+namespace {
+
+const ne_uri g_sUriDefaultsHTTP = { "http",
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ DEFAULT_HTTP_PORT,
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ NULL };
+const ne_uri g_sUriDefaultsHTTPS = { "https",
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ DEFAULT_HTTPS_PORT,
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ NULL };
+const ne_uri g_sUriDefaultsFTP = { "ftp",
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ DEFAULT_FTP_PORT,
+#if NEON_VERSION >= 0x0260
+ NULL,
+#endif
+ NULL,
+ NULL };
+} // namespace
+
+# if defined __SUNPRO_CC
+# pragma enable_warn
+#endif
+
+// -------------------------------------------------------------------
+// Constructor
+// -------------------------------------------------------------------
+
+namespace {
+
+//TODO! rtl::OString::matchIgnoreAsciiCaseAsciiL() missing
+inline bool matchIgnoreAsciiCase(rtl::OString const & rStr1,
+ sal_Char const * pStr2,
+ sal_Int32 nStr2Len) SAL_THROW(())
+{
+ return
+ rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
+ rStr1.getStr(), rStr1.getLength(), pStr2, nStr2Len, nStr2Len)
+ == 0;
+}
+
+}
+
+NeonUri::NeonUri( const ne_uri * inUri )
+ throw ( DAVException )
+{
+ if ( inUri == 0 )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ char * uri = ne_uri_unparse( inUri );
+
+ if ( uri == 0 )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ init( rtl::OString( uri ), inUri );
+ ne_free( uri );
+
+ calculateURI();
+}
+
+NeonUri::NeonUri( const rtl::OUString & inUri )
+ throw ( DAVException )
+{
+ if ( inUri.getLength() <= 0 )
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+
+ // #i77023#
+ rtl::OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
+
+ rtl::OString theInputUri(
+ aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
+
+ ne_uri theUri;
+ if ( ne_uri_parse( theInputUri.getStr(), &theUri ) != 0 )
+ {
+ ne_uri_free( &theUri );
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ }
+
+ init( theInputUri, &theUri );
+ ne_uri_free( &theUri );
+
+ calculateURI();
+}
+
+void NeonUri::init( const rtl::OString & rUri, const ne_uri * pUri )
+{
+ // Complete URI.
+ const ne_uri * pUriDefs
+ = matchIgnoreAsciiCase( rUri,
+ RTL_CONSTASCII_STRINGPARAM( "ftp:" ) ) ?
+ &g_sUriDefaultsFTP :
+ matchIgnoreAsciiCase( rUri,
+ RTL_CONSTASCII_STRINGPARAM( "https:" ) ) ?
+ &g_sUriDefaultsHTTPS :
+ &g_sUriDefaultsHTTP;
+
+ mScheme = rtl::OStringToOUString(
+ pUri->scheme ? pUri->scheme : pUriDefs->scheme,
+ RTL_TEXTENCODING_UTF8 );
+ mUserInfo = rtl::OStringToOUString(
+#if NEON_VERSION >= 0x0260
+ pUri->userinfo ? pUri->userinfo : pUriDefs->userinfo,
+#else
+ pUri->authinfo ? pUri->authinfo : pUriDefs->authinfo,
+#endif
+ RTL_TEXTENCODING_UTF8 );
+ mHostName = rtl::OStringToOUString(
+ pUri->host ? pUri->host : pUriDefs->host,
+ RTL_TEXTENCODING_UTF8 );
+ mPort = pUri->port > 0 ? pUri->port : pUriDefs->port;
+ mPath = rtl::OStringToOUString(
+ pUri->path ? pUri->path : pUriDefs->path,
+ RTL_TEXTENCODING_UTF8 );
+
+#if NEON_VERSION >= 0x0260
+ if ( pUri->query )
+ {
+ mPath += rtl::OUString::createFromAscii( "?" );
+ mPath += rtl::OStringToOUString(
+ pUri->query, RTL_TEXTENCODING_UTF8 );
+ }
+
+ if ( pUri->fragment )
+ {
+ mPath += rtl::OUString::createFromAscii( "#" );
+ mPath += rtl::OStringToOUString(
+ pUri->fragment, RTL_TEXTENCODING_UTF8 );
+ }
+#endif
+}
+
+// -------------------------------------------------------------------
+// Destructor
+// -------------------------------------------------------------------
+NeonUri::~NeonUri( )
+{
+}
+
+void NeonUri::calculateURI ()
+{
+ rtl::OUStringBuffer aBuf( mScheme );
+ aBuf.appendAscii( "://" );
+ if ( mUserInfo.getLength() > 0 )
+ {
+ //TODO! differentiate between empty and missing userinfo
+ aBuf.append( mUserInfo );
+ aBuf.appendAscii( "@" );
+ }
+ // Is host a numeric IPv6 address?
+ if ( ( mHostName.indexOf( ':' ) != -1 ) &&
+ ( mHostName[ 0 ] != sal_Unicode( '[' ) ) )
+ {
+ aBuf.appendAscii( "[" );
+ aBuf.append( mHostName );
+ aBuf.appendAscii( "]" );
+ }
+ else
+ {
+ aBuf.append( mHostName );
+ }
+
+ // append port, but only, if not default port.
+ bool bAppendPort = true;
+ switch ( mPort )
+ {
+ case DEFAULT_HTTP_PORT:
+ bAppendPort
+ = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
+ break;
+
+ case DEFAULT_HTTPS_PORT:
+ bAppendPort
+ = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
+ break;
+
+ case DEFAULT_FTP_PORT:
+ bAppendPort
+ = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ftp" ) );
+ break;
+ }
+ if ( bAppendPort )
+ {
+ aBuf.appendAscii( ":" );
+ aBuf.append( rtl::OUString::valueOf( mPort ) );
+ }
+ aBuf.append( mPath );
+
+ mURI = aBuf.makeStringAndClear();
+}
+
+::rtl::OUString NeonUri::GetPathBaseName () const
+{
+ sal_Int32 nPos = mPath.lastIndexOf ('/');
+ sal_Int32 nTrail = 0;
+ if (nPos == mPath.getLength () - 1)
+ {
+ // Trailing slash found. Skip.
+ nTrail = 1;
+ nPos = mPath.lastIndexOf ('/', nPos);
+ }
+ if (nPos != -1)
+ {
+ rtl::OUString aTemp(
+ mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) );
+
+ // query, fragment present?
+ nPos = aTemp.indexOf( '?' );
+ if ( nPos == -1 )
+ nPos = aTemp.indexOf( '#' );
+
+ if ( nPos != -1 )
+ aTemp = aTemp.copy( 0, nPos );
+
+ return aTemp;
+ }
+ else
+ return rtl::OUString::createFromAscii ("/");
+}
+
+bool NeonUri::operator== ( const NeonUri & rOther ) const
+{
+ return ( mURI == rOther.mURI );
+}
+
+::rtl::OUString NeonUri::GetPathBaseNameUnescaped () const
+{
+ return unescape( GetPathBaseName() );
+}
+
+void NeonUri::AppendPath (const rtl::OUString& rPath)
+{
+ if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
+ mPath += rtl::OUString::createFromAscii ("/");
+
+ mPath += rPath;
+ calculateURI ();
+};
+
+// static
+rtl::OUString NeonUri::escapeSegment( const rtl::OUString& segment )
+{
+ return rtl::Uri::encode( segment,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+}
+
+// static
+rtl::OUString NeonUri::unescape( const rtl::OUString& segment )
+{
+ return rtl::Uri::decode( segment,
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 );
+}
+
+// static
+rtl::OUString NeonUri::makeConnectionEndPointString(
+ const rtl::OUString & rHostName, int nPort )
+{
+ rtl::OUStringBuffer aBuf;
+
+ // Is host a numeric IPv6 address?
+ if ( ( rHostName.indexOf( ':' ) != -1 ) &&
+ ( rHostName[ 0 ] != sal_Unicode( '[' ) ) )
+ {
+ aBuf.appendAscii( "[" );
+ aBuf.append( rHostName );
+ aBuf.appendAscii( "]" );
+ }
+ else
+ {
+ aBuf.append( rHostName );
+ }
+
+ if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
+ {
+ aBuf.appendAscii( ":" );
+ aBuf.append( rtl::OUString::valueOf( sal_Int32( nPort ) ) );
+ }
+ return aBuf.makeStringAndClear();
+}
+
diff --git a/ucb/source/ucp/webdav/NeonUri.hxx b/ucb/source/ucp/webdav/NeonUri.hxx
new file mode 100644
index 000000000000..c83ca47d5a1c
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonUri.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _NEONURI_HXX_
+#define _NEONURI_HXX_
+
+#include <ne_uri.h>
+#include <rtl/ustring.hxx>
+#include <DAVException.hxx>
+
+namespace webdav_ucp
+{
+
+#define DEFAULT_HTTP_PORT 80
+#define DEFAULT_HTTPS_PORT 443
+#define DEFAULT_FTP_PORT 21
+
+// -------------------------------------------------------------------
+// NeonUri
+// A URI implementation for use with the neon/expat library
+// -------------------------------------------------------------------
+class NeonUri
+{
+ private:
+ ::rtl::OUString mURI;
+ ::rtl::OUString mScheme;
+ ::rtl::OUString mUserInfo;
+ ::rtl::OUString mHostName;
+ sal_Int32 mPort;
+ ::rtl::OUString mPath;
+
+ void init( const rtl::OString & rUri, const ne_uri * pUri );
+ void calculateURI ();
+
+ public:
+ NeonUri( const ::rtl::OUString & inUri ) throw ( DAVException );
+ NeonUri( const ne_uri * inUri ) throw ( DAVException );
+ ~NeonUri( );
+
+ bool operator== ( const NeonUri & rOther ) const;
+ bool operator!= ( const NeonUri & rOther ) const
+ { return !operator==( rOther ); }
+
+ const ::rtl::OUString & GetURI( void ) const
+ { return mURI; };
+ const ::rtl::OUString & GetScheme( void ) const
+ { return mScheme; };
+ const ::rtl::OUString & GetUserInfo( void ) const
+ { return mUserInfo; };
+ const ::rtl::OUString & GetHost( void ) const
+ { return mHostName; };
+ sal_Int32 GetPort( void ) const
+ { return mPort; };
+ const ::rtl::OUString & GetPath( void ) const
+ { return mPath; };
+
+ ::rtl::OUString GetPathBaseName ( void ) const;
+
+ ::rtl::OUString GetPathBaseNameUnescaped ( void ) const;
+
+ void SetScheme (const ::rtl::OUString& scheme)
+ { mScheme = scheme; calculateURI (); };
+
+ void AppendPath (const ::rtl::OUString& rPath);
+
+ static ::rtl::OUString escapeSegment( const ::rtl::OUString& segment );
+ static ::rtl::OUString unescape( const ::rtl::OUString& string );
+
+ // "host:port", omit ":port" for port 80 and 443
+ static rtl::OUString makeConnectionEndPointString(
+ const rtl::OUString & rHostName,
+ int nPort );
+ rtl::OUString makeConnectionEndPointString() const
+ { return makeConnectionEndPointString( GetHost(), GetPort() ); }
+};
+
+} // namespace webdav_ucp
+
+#endif // _NEONURI_HXX_
diff --git a/ucb/source/ucp/webdav/PropertyMap.hxx b/ucb/source/ucp/webdav/PropertyMap.hxx
new file mode 100644
index 000000000000..624187b1746e
--- /dev/null
+++ b/ucb/source/ucp/webdav/PropertyMap.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_PROPERTYMAP_HXX
+#define _WEBDAV_UCP_PROPERTYMAP_HXX
+
+#include <hash_set>
+#include <com/sun/star/beans/Property.hpp>
+
+namespace webdav_ucp {
+
+//=========================================================================
+
+struct equalPropertyName
+{
+ bool operator()( const ::com::sun::star::beans::Property & p1,
+ const ::com::sun::star::beans::Property & p2 ) const
+ {
+ return !!( p1.Name == p2.Name );
+ }
+};
+
+struct hashPropertyName
+{
+ size_t operator()( const ::com::sun::star::beans::Property & p ) const
+ {
+ return p.Name.hashCode();
+ }
+};
+
+typedef std::hash_set
+<
+ ::com::sun::star::beans::Property,
+ hashPropertyName,
+ equalPropertyName
+>
+PropertyMap;
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/UCBDeadPropertyValue.cxx b/ucb/source/ucp/webdav/UCBDeadPropertyValue.cxx
new file mode 100644
index 000000000000..1ce4c70e6b21
--- /dev/null
+++ b/ucb/source/ucp/webdav/UCBDeadPropertyValue.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <string.h>
+#include <ne_xml.h>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "UCBDeadPropertyValue.hxx"
+
+using namespace webdav_ucp;
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////
+
+struct UCBDeadPropertyValueParseContext
+{
+ rtl::OUString * pType;
+ rtl::OUString * pValue;
+
+ UCBDeadPropertyValueParseContext() : pType( 0 ), pValue( 0 ) {}
+ ~UCBDeadPropertyValueParseContext() { delete pType; delete pValue; }
+};
+
+// static
+const rtl::OUString UCBDeadPropertyValue::aTypeString
+ = rtl::OUString::createFromAscii( "string" );
+const rtl::OUString UCBDeadPropertyValue::aTypeLong
+ = rtl::OUString::createFromAscii( "long" );
+const rtl::OUString UCBDeadPropertyValue::aTypeShort
+ = rtl::OUString::createFromAscii( "short" );
+const rtl::OUString UCBDeadPropertyValue::aTypeBoolean
+ = rtl::OUString::createFromAscii( "boolean" );
+const rtl::OUString UCBDeadPropertyValue::aTypeChar
+ = rtl::OUString::createFromAscii( "char" );
+const rtl::OUString UCBDeadPropertyValue::aTypeByte
+ = rtl::OUString::createFromAscii( "byte" );
+const rtl::OUString UCBDeadPropertyValue::aTypeHyper
+ = rtl::OUString::createFromAscii( "hyper" );
+const rtl::OUString UCBDeadPropertyValue::aTypeFloat
+ = rtl::OUString::createFromAscii( "float" );
+const rtl::OUString UCBDeadPropertyValue::aTypeDouble
+ = rtl::OUString::createFromAscii( "double" );
+
+// static
+const rtl::OUString UCBDeadPropertyValue::aXMLPre
+ = rtl::OUString::createFromAscii( "<ucbprop><type>" );
+const rtl::OUString UCBDeadPropertyValue::aXMLMid
+ = rtl::OUString::createFromAscii( "</type><value>" );
+const rtl::OUString UCBDeadPropertyValue::aXMLEnd
+ = rtl::OUString::createFromAscii( "</value></ucbprop>" );
+
+#define STATE_TOP (1)
+
+#define STATE_UCBPROP (STATE_TOP)
+#define STATE_TYPE (STATE_TOP + 1)
+#define STATE_VALUE (STATE_TOP + 2)
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int UCBDeadPropertyValue_startelement_callback(
+ void *,
+ int parent,
+ const char * /*nspace*/,
+ const char *name,
+ const char ** )
+{
+ if ( name != 0 )
+ {
+ switch ( parent )
+ {
+ case NE_XML_STATEROOT:
+ if ( strcmp( name, "ucbprop" ) == 0 )
+ return STATE_UCBPROP;
+ break;
+
+ case STATE_UCBPROP:
+ if ( strcmp( name, "type" ) == 0 )
+ return STATE_TYPE;
+ else if ( strcmp( name, "value" ) == 0 )
+ return STATE_VALUE;
+ break;
+ }
+ }
+ return NE_XML_DECLINE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int UCBDeadPropertyValue_chardata_callback(
+ void *userdata,
+ int state,
+ const char *buf,
+ size_t len )
+{
+ UCBDeadPropertyValueParseContext * pCtx
+ = static_cast< UCBDeadPropertyValueParseContext * >( userdata );
+
+ switch ( state )
+ {
+ case STATE_TYPE:
+ OSL_ENSURE( !pCtx->pType,
+ "UCBDeadPropertyValue_endelement_callback - "
+ "Type already set!" );
+ pCtx->pType
+ = new rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ break;
+
+ case STATE_VALUE:
+ OSL_ENSURE( !pCtx->pValue,
+ "UCBDeadPropertyValue_endelement_callback - "
+ "Value already set!" );
+ pCtx->pValue
+ = new rtl::OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+extern "C" int UCBDeadPropertyValue_endelement_callback(
+ void *userdata,
+ int state,
+ const char *,
+ const char * )
+{
+ UCBDeadPropertyValueParseContext * pCtx
+ = static_cast< UCBDeadPropertyValueParseContext * >( userdata );
+
+ switch ( state )
+ {
+ case STATE_TYPE:
+ if ( !pCtx->pType )
+ return 1; // abort
+ break;
+
+ case STATE_VALUE:
+ if ( !pCtx->pValue )
+ return 1; // abort
+ break;
+
+ case STATE_UCBPROP:
+ if ( !pCtx->pType || ! pCtx->pValue )
+ return 1; // abort
+ break;
+ }
+ return 0; // zero to continue, non-zero to abort parsing
+}
+
+//////////////////////////////////////////////////////////////////////////
+static rtl::OUString encodeValue( const rtl::OUString & rValue )
+{
+ // Note: I do not use the usual &amp; + &lt; + &gt; encoding, because
+ // I want to prevent any XML parser from trying to 'understand'
+ // the value. This caused problems:
+ //
+ // Example:
+ // - Unencoded property value: x<z
+ // PROPPATCH:
+ // - Encoded property value: x&lt;z
+ // - UCBDeadPropertyValue::toXML result:
+ // <ucbprop><type>string</type><value>x&lt;z</value></ucbprop>
+ // PROPFIND:
+ // - parser replaces &lt; by > ==> error (not well formed)
+
+ rtl::OUStringBuffer aResult;
+ const sal_Unicode * pValue = rValue.getStr();
+
+ sal_Int32 nCount = rValue.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = pValue[ n ];
+
+ if ( '%' == c )
+ aResult.appendAscii( "%per;" );
+ else if ( '<' == c )
+ aResult.appendAscii( "%lt;" );
+ else if ( '>' == c )
+ aResult.appendAscii( "%gt;" );
+ else
+ aResult.append( c );
+ }
+ return rtl::OUString( aResult );
+}
+
+//////////////////////////////////////////////////////////////////////////
+static rtl::OUString decodeValue( const rtl::OUString & rValue )
+{
+ rtl::OUStringBuffer aResult;
+ const sal_Unicode * pValue = rValue.getStr();
+
+ sal_Int32 nPos = 0;
+ sal_Int32 nEnd = rValue.getLength();
+
+ while ( nPos < nEnd )
+ {
+ sal_Unicode c = pValue[ nPos ];
+
+ if ( '%' == c )
+ {
+ nPos++;
+
+ if ( nPos == nEnd )
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+
+ c = pValue[ nPos ];
+
+ if ( 'p' == c )
+ {
+ // %per;
+
+ if ( nPos > nEnd - 4 )
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+
+ if ( ( 'e' == pValue[ nPos + 1 ] )
+ &&
+ ( 'r' == pValue[ nPos + 2 ] )
+ &&
+ ( ';' == pValue[ nPos + 3 ] ) )
+ {
+ aResult.append( sal_Unicode( '%' ) );
+ nPos += 3;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+ }
+ else if ( 'l' == c )
+ {
+ // %lt;
+
+ if ( nPos > nEnd - 3 )
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+
+ if ( ( 't' == pValue[ nPos + 1 ] )
+ &&
+ ( ';' == pValue[ nPos + 2 ] ) )
+ {
+ aResult.append( sal_Unicode( '<' ) );
+ nPos += 2;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+ }
+ else if ( 'g' == c )
+ {
+ // %gt;
+
+ if ( nPos > nEnd - 3 )
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+
+ if ( ( 't' == pValue[ nPos + 1 ] )
+ &&
+ ( ';' == pValue[ nPos + 2 ] ) )
+ {
+ aResult.append( sal_Unicode( '>' ) );
+ nPos += 2;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::decodeValue - syntax error!" );
+ return rtl::OUString();
+ }
+ }
+ else
+ aResult.append( c );
+
+ nPos++;
+ }
+
+ return rtl::OUString( aResult );
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool UCBDeadPropertyValue::supportsType( const uno::Type & rType )
+{
+ if ( ( rType != getCppuType( static_cast< const rtl::OUString * >( 0 ) ) )
+ &&
+ ( rType != getCppuType( static_cast< const sal_Int32 * >( 0 ) ) )
+ &&
+ ( rType != getCppuType( static_cast< const sal_Int16 * >( 0 ) ) )
+ &&
+ ( rType != getCppuBooleanType() )
+ &&
+ ( rType != getCppuCharType() )
+ &&
+ ( rType != getCppuType( static_cast< const sal_Int8 * >( 0 ) ) )
+ &&
+ ( rType != getCppuType( static_cast< const sal_Int64 * >( 0 ) ) )
+ &&
+ ( rType != getCppuType( static_cast< const float * >( 0 ) ) )
+ &&
+ ( rType != getCppuType( static_cast< const double * >( 0 ) ) ) )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool UCBDeadPropertyValue::createFromXML( const rtl::OString & rInData,
+ uno::Any & rOutData )
+{
+ bool success = false;
+
+ ne_xml_parser * parser = ne_xml_create();
+ if ( parser )
+ {
+ UCBDeadPropertyValueParseContext aCtx;
+ ne_xml_push_handler( parser,
+ UCBDeadPropertyValue_startelement_callback,
+ UCBDeadPropertyValue_chardata_callback,
+ UCBDeadPropertyValue_endelement_callback,
+ &aCtx );
+
+ ne_xml_parse( parser, rInData.getStr(), rInData.getLength() );
+
+#if NEON_VERSION >= 0x0250
+ success = !ne_xml_failed( parser );
+#else
+ success = !!ne_xml_valid( parser );
+#endif
+
+ ne_xml_destroy( parser );
+
+ if ( success )
+ {
+ if ( aCtx.pType && aCtx.pValue )
+ {
+ // Decode aCtx.pValue! It may contain XML reserved chars.
+ rtl::OUString aStringValue = decodeValue( *aCtx.pValue );
+ if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeString ) )
+ {
+ rOutData <<= aStringValue;
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeLong ) )
+ {
+ rOutData <<= aStringValue.toInt32();
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeShort ) )
+ {
+ rOutData <<= sal_Int16( aStringValue.toInt32() );
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeBoolean ) )
+ {
+ if ( aStringValue.equalsIgnoreAsciiCase(
+ rtl::OUString::createFromAscii( "true" ) ) )
+ rOutData <<= sal_Bool( sal_True );
+ else
+ rOutData <<= sal_Bool( sal_False );
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeChar ) )
+ {
+ rOutData <<= aStringValue.toChar();
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeByte ) )
+ {
+ rOutData <<= sal_Int8( aStringValue.toChar() );
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeHyper ) )
+ {
+ rOutData <<= aStringValue.toInt64();
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeFloat ) )
+ {
+ rOutData <<= aStringValue.toFloat();
+ }
+ else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeDouble ) )
+ {
+ rOutData <<= aStringValue.toDouble();
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::createFromXML - "
+ "Unsupported property type!" );
+ success = false;
+ }
+ }
+ else
+ success = false;
+ }
+ }
+
+ return success;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// static
+bool UCBDeadPropertyValue::toXML( const uno::Any & rInData,
+ rtl::OUString & rOutData )
+{
+ // <ucbprop><type>the_type</type><value>the_value</value></ucbprop>
+
+ // Check property type. Extract type and value as string.
+
+ const uno::Type& rType = rInData.getValueType();
+ rtl::OUString aStringValue;
+ rtl::OUString aStringType;
+
+ if ( rType == getCppuType( static_cast< const rtl::OUString * >( 0 ) ) )
+ {
+ // string
+ rInData >>= aStringValue;
+ aStringType = aTypeString;
+ }
+ else if ( rType == getCppuType( static_cast< const sal_Int32 * >( 0 ) ) )
+ {
+ // long
+ sal_Int32 nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( nValue );
+ aStringType = aTypeLong;
+ }
+ else if ( rType == getCppuType( static_cast< const sal_Int16 * >( 0 ) ) )
+ {
+ // short
+ sal_Int32 nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( nValue );
+ aStringType = aTypeShort;
+ }
+ else if ( rType == getCppuBooleanType() )
+ {
+ // boolean
+ sal_Bool bValue = false;
+ rInData >>= bValue;
+ aStringValue = rtl::OUString::valueOf( bValue );
+ aStringType = aTypeBoolean;
+ }
+ else if ( rType == getCppuCharType() )
+ {
+ // char
+ sal_Unicode cValue = 0;
+ rInData >>= cValue;
+ aStringValue = rtl::OUString::valueOf( cValue );
+ aStringType = aTypeChar;
+ }
+ else if ( rType == getCppuType( static_cast< const sal_Int8 * >( 0 ) ) )
+ {
+ // byte
+ sal_Int8 nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( sal_Unicode( nValue ) );
+ aStringType = aTypeByte;
+ }
+ else if ( rType == getCppuType( static_cast< const sal_Int64 * >( 0 ) ) )
+ {
+ // hyper
+ sal_Int64 nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( nValue );
+ aStringType = aTypeHyper;
+ }
+ else if ( rType == getCppuType( static_cast< const float * >( 0 ) ) )
+ {
+ // float
+ float nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( nValue );
+ aStringType = aTypeFloat;
+ }
+ else if ( rType == getCppuType( static_cast< const double * >( 0 ) ) )
+ {
+ // double
+ double nValue = 0;
+ rInData >>= nValue;
+ aStringValue = rtl::OUString::valueOf( nValue );
+ aStringType = aTypeDouble;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "UCBDeadPropertyValue::toXML - "
+ "Unsupported property type!" );
+ return false;
+ }
+
+ // Encode value! It must not contain XML reserved chars!
+ aStringValue = encodeValue( aStringValue );
+
+ rOutData = aXMLPre;
+ rOutData += aStringType;
+ rOutData += aXMLMid;
+ rOutData += aStringValue;
+ rOutData += aXMLEnd;
+
+ return true;
+}
diff --git a/ucb/source/ucp/webdav/UCBDeadPropertyValue.hxx b/ucb/source/ucp/webdav/UCBDeadPropertyValue.hxx
new file mode 100644
index 000000000000..69dc5d3c80bf
--- /dev/null
+++ b/ucb/source/ucp/webdav/UCBDeadPropertyValue.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UCBDEADPROPERTYVALUE_HXX_
+#define _UCBDEADPROPERTYVALUE_HXX_
+
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+namespace webdav_ucp
+{
+
+class UCBDeadPropertyValue
+{
+private:
+ static const rtl::OUString aTypeString;
+ static const rtl::OUString aTypeLong;
+ static const rtl::OUString aTypeShort;
+ static const rtl::OUString aTypeBoolean;
+ static const rtl::OUString aTypeChar;
+ static const rtl::OUString aTypeByte;
+ static const rtl::OUString aTypeHyper;
+ static const rtl::OUString aTypeFloat;
+ static const rtl::OUString aTypeDouble;
+
+ static const rtl::OUString aXMLPre;
+ static const rtl::OUString aXMLMid;
+ static const rtl::OUString aXMLEnd;
+
+public:
+ static bool supportsType( const com::sun::star::uno::Type & rType );
+
+ static bool createFromXML( const rtl::OString & rInData,
+ com::sun::star::uno::Any & rOutData );
+ static bool toXML( const com::sun::star::uno::Any & rInData,
+ rtl::OUString & rOutData );
+};
+
+}
+
+#endif /* _UCBDEADPROPERTYVALUE_HXX_ */
diff --git a/ucb/source/ucp/webdav/makefile.mk b/ucb/source/ucp/webdav/makefile.mk
new file mode 100644
index 000000000000..73ee298697e8
--- /dev/null
+++ b/ucb/source/ucp/webdav/makefile.mk
@@ -0,0 +1,160 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# UCP Version - Increase, if UCP libraray becomes incompatible.
+UCP_VERSION=1
+
+# Name for the UCP. Will become part of the library name (See below).
+UCP_NAME=dav
+
+# Relative path to project root.
+PRJ = ..$/..$/..
+
+# Project Name.
+PRJNAME=ucb
+
+TARGET=ucp$(UCP_NAME)
+
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+.IF "$(DISABLE_NEON)" == "TRUE"
+
+@all:
+ @echo "neon disabled...."
+
+.ELSE
+
+NEONINCDIR=external$/neon
+
+.IF "$(SYSTEM_NEON)" != "YES"
+.INCLUDE: $(SOLARINCDIR)$/$(NEONINCDIR)$/version.mk
+.ENDIF
+
+CFLAGS+= -DNEON_VERSION=0x$(NEON_VERSION)
+
+.IF "$(SYSTEM_NEON)" == "YES"
+CFLAGS+= $(NEON_CFLAGS)
+.ELSE
+CFLAGS+= -I$(SOLARINCDIR)$/$(NEONINCDIR)
+.ENDIF
+
+.IF "$(SYSTEM_LIBXML)" == "YES"
+CFLAGS+= $(LIBXML_CFLAGS)
+.ELSE
+LIBXMLINCDIR=external$/libxml
+CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXMLINCDIR)
+.ENDIF
+
+.IF "$(SYSTEM_OPENSSL)" == "YES"
+CFLAGS+= $(OPENSSL_CFLAGS)
+.ENDIF
+
+# --- General -----------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/webdavservices.obj \
+ $(SLO)$/webdavprovider.obj \
+ $(SLO)$/webdavcontent.obj \
+ $(SLO)$/webdavcontentcaps.obj \
+ $(SLO)$/webdavresultset.obj \
+ $(SLO)$/webdavdatasupplier.obj \
+ $(SLO)$/ContentProperties.obj \
+ $(SLO)$/DAVProperties.obj \
+ $(SLO)$/DAVSessionFactory.obj \
+ $(SLO)$/DAVResourceAccess.obj \
+ $(SLO)$/NeonUri.obj \
+ $(SLO)$/NeonInputStream.obj \
+ $(SLO)$/NeonPropFindRequest.obj \
+ $(SLO)$/NeonHeadRequest.obj \
+ $(SLO)$/NeonSession.obj \
+ $(SLO)$/NeonLockStore.obj \
+ $(SLO)$/DateTimeHelper.obj \
+ $(SLO)$/LinkSequence.obj \
+ $(SLO)$/LockSequence.obj \
+ $(SLO)$/LockEntrySequence.obj \
+ $(SLO)$/UCBDeadPropertyValue.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCP_VERSION)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(NEON3RDLIB) \
+ $(LIBXML2LIB)
+
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= $(WSOCK32LIB)
+.IF "$(WINDOWS_VISTA_PSDK)" != ""
+SHL1STDLIBS+= $(WS2_32LIB)
+.ENDIF
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE # WNT
+.IF "$(OS)"=="SOLARIS"
+SHL1STDLIBS+= -lnsl -lsocket -ldl
+.ENDIF # SOLARIS
+.IF "$(OS)"=="OS2"
+SHL1STDLIBS+= pthread.lib libz.lib
+.ENDIF # OS2
+.IF "$(SYSTEM_OPENSSL)"=="YES"
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE
+SHL1STDLIBS+= $(OPENSSLLIBST)
+.ENDIF
+.ENDIF # WNT
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF #"$(DISABLE_NEON)" == "TRUE"
+
+.ENDIF # L10N_framework
+# --- Targets ----------------------------------------------------------
+
+.INCLUDE: target.mk
diff --git a/ucb/source/ucp/webdav/ucpdav.xml b/ucb/source/ucp/webdav/ucpdav.xml
new file mode 100644
index 000000000000..ccb993b3138c
--- /dev/null
+++ b/ucb/source/ucp/webdav/ucpdav.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucpdav
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.WebDAVContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to contents stored on an HTTP/WebDAV
+ server.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.WebDAVContentProvider
+ </supported-service>
+ </component-description>
+
+ <project-build-dependency> external </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XInputStream </type>
+ <type> com.sun.star.io.XOutputStream </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.task.InteractionClassification </type>
+ <type> com.sun.star.task.XInteractionAbort </type>
+ <type> com.sun.star.task.XInteractionReply </type>
+ <type> com.sun.star.ucb.AuthenticationRequest </type>
+ <type> com.sun.star.ucb.CommandFailedException </type>
+ <type> com.sun.star.ucb.ContentCreationException </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveAugmentedIOException </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkConnectException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkGeneralException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkReadException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkResolveNameException </type>
+ <type> com.sun.star.ucb.InteractiveNetworkWriteException </type>
+ <type> com.sun.star.ucb.Link </type>
+ <type> com.sun.star.ucb.Lock </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.PostCommandArgument2 </type>
+ <type> com.sun.star.ucb.RememberAuthentication </type>
+ <type> com.sun.star.ucb.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.XCommandEnvironment </type>
+ <type> com.sun.star.ucb.UnsupportedCommandException </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandInfoChangeNotifier </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XInteractionSupplyAuthentication </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.util.DateTime </type>
+</module-description>
diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx
new file mode 100644
index 000000000000..26b2a044e7b6
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavcontent.cxx
@@ -0,0 +1,3247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <osl/diagnose.h>
+#include "osl/doublecheckedlocking.h"
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/simpleinteractionrequest.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertySetInfoChange.hpp>
+#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
+#include <com/sun/star/ucb/CommandEnvironment.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include "com/sun/star/ucb/InteractiveLockingLockedException.hpp"
+#include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp"
+#include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp"
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/MissingPropertiesException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include "webdavcontent.hxx"
+#include "webdavprovider.hxx"
+#include "webdavresultset.hxx"
+#include "ContentProperties.hxx"
+#include "NeonUri.hxx"
+#include "UCBDeadPropertyValue.hxx"
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+//=========================================================================
+// ctr for content on an existing webdav resource
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ rtl::Reference< DAVSessionFactory > const & rSessionFactory )
+ throw ( ucb::ContentCreationException )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_eResourceType( UNKNOWN ),
+ m_pProvider( pProvider ),
+ m_bTransient( false ),
+ m_bCollection( false ),
+ m_bDidGetOrHead( false )
+{
+ try
+ {
+ m_xResAccess.reset( new DAVResourceAccess(
+ rxSMgr,
+ rSessionFactory,
+ Identifier->getContentIdentifier() ) );
+
+ NeonUri aURI( Identifier->getContentIdentifier() );
+ m_aEscapedTitle = aURI.GetPathBaseName();
+ }
+ catch ( DAVException const & )
+ {
+ throw ucb::ContentCreationException();
+ }
+}
+
+//=========================================================================
+// ctr for content on an non-existing webdav resource
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ rtl::Reference< DAVSessionFactory > const & rSessionFactory,
+ sal_Bool isCollection )
+ throw ( ucb::ContentCreationException )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_eResourceType( UNKNOWN ),
+ m_pProvider( pProvider ),
+ m_bTransient( true ),
+ m_bCollection( isCollection ),
+ m_bDidGetOrHead( false )
+{
+ try
+ {
+ m_xResAccess.reset( new DAVResourceAccess(
+ rxSMgr, rSessionFactory, Identifier->getContentIdentifier() ) );
+ }
+ catch ( DAVException const & )
+ {
+ throw ucb::ContentCreationException();
+ }
+
+ // Do not set m_aEscapedTitle here! Content::insert relays on this!!!
+}
+
+//=========================================================================
+// virtual
+Content::~Content()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Content::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ // Note: isFolder may require network activities! So call it only
+ // if it is really necessary!!!
+ uno::Any aRet = cppu::queryInterface(
+ rType,
+ static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > const xProps(
+ m_xSMgr, uno::UNO_QUERY_THROW );
+ uno::Reference< uno::XComponentContext > xCtx;
+ xCtx.set( xProps->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
+ uno::UNO_QUERY_THROW );
+
+ uno::Reference< task::XInteractionHandler > xIH(
+ task::PasswordContainerInteractionHandler::create( xCtx ) );
+
+ // Supply a command env to isFolder() that contains an interaction
+ // handler that uses the password container service to obtain
+ // credentials without displaying a password gui.
+
+ uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
+ ucb::CommandEnvironment::create(
+ xCtx,
+ xIH,
+ uno::Reference< ucb::XProgressHandler >() ) );
+
+ return isFolder( xCmdEnv ) ? aRet : uno::Any();
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ return uno::Any();
+ }
+ }
+ return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ sal_Bool bFolder = sal_False;
+ try
+ {
+ bFolder
+ = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( bFolder )
+ {
+ static cppu::OTypeCollection* pFolderTypes = 0;
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pFolderTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pDocumentTypes = 0;
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( ucb::XContent ),
+ CPPU_TYPE_REF( ucb::XCommandProcessor ),
+ CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
+ CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
+ CPPU_TYPE_REF( beans::XPropertyContainer ),
+ CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
+ CPPU_TYPE_REF( container::XChild ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pDocumentTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.WebDAVContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString::createFromAscii( WEBDAV_CONTENT_SERVICE_NAME );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ sal_Bool bFolder = sal_False;
+ try
+ {
+ bFolder
+ = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ }
+
+ if ( bFolder )
+ return rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE );
+
+ return rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE );
+}
+
+//=========================================================================
+//
+// XCommandProcessor methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Content::execute(
+ const ucb::Command& aCommand,
+ sal_Int32 /*CommandId*/,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception,
+ ucb::CommandAbortedException,
+ uno::RuntimeException )
+{
+ OSL_TRACE( ">>>>> Content::execute: start: command: %s, env: %s",
+ rtl::OUStringToOString( aCommand.Name,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ Environment.is() ? "present" : "missing" );
+
+ uno::Any aRet;
+
+ if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > Properties;
+ if ( !( aCommand.Argument >>= Properties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "No properties!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getPropertySetInfo( Environment,
+ sal_False /* don't cache data */ );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ // Note: Implemented by base class.
+ aRet <<= getCommandInfo( Environment, sal_False );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open
+ //////////////////////////////////////////////////////////////////
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet = open( aOpenCommand, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ //////////////////////////////////////////////////////////////////
+
+ ucb::InsertCommandArgument arg;
+ if ( !( aCommand.Argument >>= arg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ insert( arg.Data, arg.ReplaceExisting, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ //////////////////////////////////////////////////////////////////
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+
+// KSO: Ignore parameter and destroy the content, if you don't support
+// putting objects into trashcan. ( Since we do not have a trash can
+// service yet (src603), you actually have no other choice. )
+// if ( bDeletePhysical )
+// {
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+ xResAccess->DESTROY( Environment );
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, Environment, sal_True );
+ // Unreachable
+ }
+// }
+
+ // Propagate destruction.
+ destroy( bDeletePhysical );
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "transfer" ) )
+ && isFolder( Environment ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer
+ // ( Not available at documents )
+ //////////////////////////////////////////////////////////////////
+
+ ucb::TransferInfo transferArgs;
+ if ( !( aCommand.Argument >>= transferArgs ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ transfer( transferArgs, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "post" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // post
+ //////////////////////////////////////////////////////////////////
+
+ ucb::PostCommandArgument2 aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ post( aArg, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "lock" ) ) &&
+ supportsExclusiveWriteLock( Environment ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // lock
+ //////////////////////////////////////////////////////////////////
+
+ lock( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) &&
+ supportsExclusiveWriteLock( Environment ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // unlock
+ //////////////////////////////////////////////////////////////////
+
+ unlock( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) &&
+ isFolder( Environment ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent
+ //////////////////////////////////////////////////////////////////
+
+ ucb::ContentInfo aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet = uno::makeAny( createNewContent( aArg ) );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // Unsupported command
+ //////////////////////////////////////////////////////////////////
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ aCommand.Name,
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ OSL_TRACE( "<<<<< Content::execute: end: command: %s",
+ rtl::OUStringToOString( aCommand.Name,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ return aRet;
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+ xResAccess->abort();
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & )
+ {
+ // abort failed!
+ }
+}
+
+//=========================================================================
+//
+// XPropertyContainer methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Content::addProperty( const rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const uno::Any& DefaultValue )
+ throw( beans::PropertyExistException,
+ beans::IllegalTypeException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException )
+{
+// if ( m_bTransient )
+// @@@ ???
+
+ if ( !Name.getLength() )
+ throw lang::IllegalArgumentException();
+
+ // Check property type.
+ if ( !UCBDeadPropertyValue::supportsType( DefaultValue.getValueType() ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::addProperty - Unsupported property type!" );
+ throw beans::IllegalTypeException();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Make sure a property with the requested name does not already
+ // exist in dynamic and static(!) properties.
+ //////////////////////////////////////////////////////////////////////
+
+ // @@@ Need real command environment here, but where to get it from?
+ // XPropertyContainer interface should be replaced by
+ // XCommandProcessor commands!
+ uno::Reference< ucb::XCommandEnvironment > xEnv;
+
+ // Note: This requires network access!
+ if ( getPropertySetInfo( xEnv, sal_False /* don't cache data */ )
+ ->hasPropertyByName( Name ) )
+ {
+ // Property does already exist.
+ throw beans::PropertyExistException();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Add a new dynamic property.
+ //////////////////////////////////////////////////////////////////////
+
+ ProppatchValue aValue( PROPSET, Name, DefaultValue );
+
+ std::vector< ProppatchValue > aProppatchValues;
+ aProppatchValues.push_back( aValue );
+
+ try
+ {
+ // Set property value at server.
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+ xResAccess->PROPPATCH( aProppatchValues, xEnv );
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ // Notify propertyset info change listeners.
+ beans::PropertySetInfoChangeEvent evt(
+ static_cast< cppu::OWeakObject * >( this ),
+ Name,
+ -1, // No handle available
+ beans::PropertySetInfoChange::PROPERTY_INSERTED );
+ notifyPropertySetInfoChange( evt );
+ }
+ catch ( DAVException const & e )
+ {
+ if ( e.getStatus() == SC_FORBIDDEN )
+ {
+ // Support for setting arbitrary dead properties is optional!
+
+ // Store property locally.
+ ContentImplHelper::addProperty(
+ Name, Attributes, DefaultValue );
+ }
+ else
+ {
+ if ( shouldAccessNetworkAfterException( e ) )
+ {
+ try
+ {
+ const ResourceType & rType = getResourceType( xEnv );
+ switch ( rType )
+ {
+ case UNKNOWN:
+ case DAV:
+ throw lang::IllegalArgumentException();
+
+ case FTP:
+ case NON_DAV:
+ // Store property locally.
+ ContentImplHelper::addProperty( Name,
+ Attributes,
+ DefaultValue );
+ break;
+
+ default:
+ OSL_ENSURE( sal_False,
+ "Content::addProperty - "
+ "Unsupported resource type!" );
+ break;
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::addProperty - "
+ "Unable to determine resource type!" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "Content::addProperty - "
+ "Unable to determine resource type!" );
+ }
+ }
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Content::removeProperty( const rtl::OUString& Name )
+ throw( beans::UnknownPropertyException,
+ beans::NotRemoveableException,
+ uno::RuntimeException )
+{
+ // @@@ Need real command environment here, but where to get it from?
+ // XPropertyContainer interface should be replaced by
+ // XCommandProcessor commands!
+ uno::Reference< ucb::XCommandEnvironment > xEnv;
+
+#if 0
+ // @@@ REMOVEABLE z.Z. nicht richtig an der PropSetInfo gesetzt!!!
+ try
+ {
+ beans::Property aProp
+ = getPropertySetInfo( xEnv, sal_False /* don't cache data */ )
+ ->getPropertyByName( Name );
+
+ if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) )
+ {
+ // Not removeable!
+ throw beans::NotRemoveableException();
+ }
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ //OSL_ENSURE( sal_False, "removeProperty - Unknown property!" );
+ throw;
+ }
+#endif
+
+ //////////////////////////////////////////////////////////////////////
+ // Try to remove property from server.
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ std::vector< ProppatchValue > aProppatchValues;
+ ProppatchValue aValue( PROPREMOVE, Name, uno::Any() );
+ aProppatchValues.push_back( aValue );
+
+ // Remove property value from server.
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+ xResAccess->PROPPATCH( aProppatchValues, xEnv );
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ // Notify propertyset info change listeners.
+ beans::PropertySetInfoChangeEvent evt(
+ static_cast< cppu::OWeakObject * >( this ),
+ Name,
+ -1, // No handle available
+ beans::PropertySetInfoChange::PROPERTY_REMOVED );
+ notifyPropertySetInfoChange( evt );
+ }
+ catch ( DAVException const & e )
+ {
+ if ( e.getStatus() == SC_FORBIDDEN )
+ {
+ // Support for setting arbitrary dead properties is optional!
+
+ // Try to remove property from local store.
+ ContentImplHelper::removeProperty( Name );
+ }
+ else
+ {
+ if ( shouldAccessNetworkAfterException( e ) )
+ {
+ try
+ {
+ const ResourceType & rType = getResourceType( xEnv );
+ switch ( rType )
+ {
+ case UNKNOWN:
+ case DAV:
+ throw beans::UnknownPropertyException();
+
+ case FTP:
+ case NON_DAV:
+ // Try to remove property from local store.
+ ContentImplHelper::removeProperty( Name );
+ break;
+
+ default:
+ OSL_ENSURE( sal_False,
+ "Content::removeProperty - "
+ "Unsupported resource type!" );
+ break;
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::removeProperty - "
+ "Unable to determine resource type!" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "Content::removeProperty - "
+ "Unable to determine resource type!" );
+// throw beans::UnknownPropertyException();
+ }
+ }
+ }
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // document.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+
+ beans::Property aProp;
+ m_pProvider->getProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), aProp );
+
+ uno::Sequence< beans::Property > aDocProps( 1 );
+ aDocProps.getArray()[ 0 ] = aProp;
+ aSeq.getArray()[ 0 ].Properties = aDocProps;
+
+ // folder.
+ aSeq.getArray()[ 1 ].Type
+ = rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+
+ uno::Sequence< beans::Property > aFolderProps( 1 );
+ aFolderProps.getArray()[ 0 ] = aProp;
+ aSeq.getArray()[ 1 ].Properties = aFolderProps;
+ return aSeq;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !Info.Type.getLength() )
+ return uno::Reference< ucb::XContent >();
+
+ if ( ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) )
+ &&
+ ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_CONTENT_TYPE ) ) ) )
+ return uno::Reference< ucb::XContent >();
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.getLength() > 0,
+ "WebdavContent::createNewContent - empty identifier!" );
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ sal_Bool isCollection;
+ if ( Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) )
+ {
+ aURL += rtl::OUString::createFromAscii( "New_Collection" );
+ isCollection = sal_True;
+ }
+ else
+ {
+ aURL += rtl::OUString::createFromAscii( "New_Content" );
+ isCollection = sal_False;
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId(
+ new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) );
+
+ // create the local content
+ try
+ {
+ return new ::webdav_ucp::Content( m_xSMgr,
+ m_pProvider,
+ xId,
+ m_xResAccess->getSessionFactory(),
+ isCollection );
+ }
+ catch ( ucb::ContentCreationException & )
+ {
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+// virtual
+rtl::OUString Content::getParentURL()
+{
+ // <scheme>:// -> ""
+ // <scheme>://foo -> ""
+ // <scheme>://foo/ -> ""
+ // <scheme>://foo/bar -> <scheme>://foo/
+ // <scheme>://foo/bar/ -> <scheme>://foo/
+ // <scheme>://foo/bar/abc -> <scheme>://foo/bar/
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
+ if ( nPos == ( aURL.getLength() - 1 ) )
+ {
+ // Trailing slash found. Skip.
+ nPos = aURL.lastIndexOf( '/', nPos );
+ }
+
+ sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
+ if ( nPos1 != -1 )
+ nPos1 = aURL.lastIndexOf( '/', nPos1 );
+
+ if ( nPos1 == -1 )
+ return rtl::OUString();
+
+ return rtl::OUString( aURL.copy( 0, nPos + 1 ) );
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const ContentProperties& rData,
+ const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
+ const rtl::OUString& rContentId )
+{
+ // Note: Empty sequence means "get values of all supported properties".
+
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ uno::Reference< beans::XPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+
+ // Process standard UCB, DAV and HTTP properties.
+ const uno::Any & rValue = rData.getValue( rProp.Name );
+ if ( rValue.hasValue() )
+ {
+ xRow->appendObject( rProp, rValue );
+ }
+ else
+ {
+ // Process local Additional Properties.
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ rProvider->getAdditionalPropertySet( rContentId,
+ sal_False ),
+ uno::UNO_QUERY );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( !xAdditionalPropSet.is() ||
+ !xRow->appendPropertySetValue(
+ xAdditionalPropSet, rProp ) )
+ {
+ // Append empty entry.
+ xRow->appendVoid( rProp );
+ }
+ }
+ }
+ }
+ else
+ {
+ // Append all standard UCB, DAV and HTTP properties.
+
+ const std::auto_ptr< PropertyValueMap > & xProps = rData.getProperties();
+
+ PropertyValueMap::const_iterator it = xProps->begin();
+ PropertyValueMap::const_iterator end = xProps->end();
+
+ ContentProvider * pProvider
+ = static_cast< ContentProvider * >( rProvider.get() );
+ beans::Property aProp;
+
+ while ( it != end )
+ {
+ if ( pProvider->getProperty( (*it).first, aProp ) )
+ xRow->appendObject( aProp, (*it).second.value() );
+
+ ++it;
+ }
+
+ // Append all local Additional Properties.
+ uno::Reference< beans::XPropertySet > xSet(
+ rProvider->getAdditionalPropertySet( rContentId, sal_False ),
+ uno::UNO_QUERY );
+ xRow->appendPropertySet( xSet );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+}
+
+//=========================================================================
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Sequence< beans::Property >& rProperties,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw ( uno::Exception )
+{
+ std::auto_ptr< ContentProperties > xProps;
+ std::auto_ptr< ContentProperties > xCachedProps;
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ rtl::OUString aEscapedTitle;
+ bool bHasAll = false;
+ uno::Reference< lang::XMultiServiceFactory > xSMgr;
+ uno::Reference< ucb::XContentIdentifier > xIdentifier;
+ rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ aEscapedTitle = NeonUri::unescape( m_aEscapedTitle );
+ xSMgr.set( m_xSMgr );
+ xIdentifier.set( m_xIdentifier );
+ xProvider.set( m_xProvider.get() );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+
+ // First, ask cache...
+ if ( m_xCachedProps.get() )
+ {
+ xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
+
+ std::vector< rtl::OUString > aMissingProps;
+ if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) )
+ {
+ // All properties are already in cache! No server access needed.
+ bHasAll = true;
+ }
+
+ // use the cached ContentProperties instance
+ xProps.reset( new ContentProperties( *xCachedProps.get() ) );
+ }
+ }
+
+ if ( !m_bTransient && !bHasAll )
+ {
+ /////////////////////////////////////////////////////////////////////
+ // Obtain values from server...
+ /////////////////////////////////////////////////////////////////////
+
+ // First, identify whether resource is DAV or not
+ const ResourceType & rType = getResourceType( xEnv, xResAccess );
+
+ bool bNetworkAccessAllowed = true;
+
+ if ( DAV == rType )
+ {
+ // cache lookup... getResourceType may fill the props cache via
+ // PROPFIND!
+ if ( m_xCachedProps.get() )
+ {
+ xCachedProps.reset(
+ new ContentProperties( *m_xCachedProps.get() ) );
+
+ std::vector< rtl::OUString > aMissingProps;
+ if ( xCachedProps->containsAllNames(
+ rProperties, aMissingProps ) )
+ {
+ // All properties are already in cache! No server access
+ // needed.
+ bHasAll = true;
+ }
+
+ // use the cached ContentProperties instance
+ xProps.reset( new ContentProperties( *xCachedProps.get() ) );
+ }
+
+ if ( !bHasAll )
+ {
+ // Only DAV resources support PROPFIND
+ std::vector< rtl::OUString > aPropNames;
+
+ uno::Sequence< beans::Property > aProperties(
+ rProperties.getLength() );
+
+ if ( m_aFailedPropNames.size() > 0 )
+ {
+ sal_Int32 nProps = 0;
+ sal_Int32 nCount = rProperties.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const rtl::OUString & rName = rProperties[ n ].Name;
+
+ std::vector< rtl::OUString >::const_iterator it
+ = m_aFailedPropNames.begin();
+ std::vector< rtl::OUString >::const_iterator end
+ = m_aFailedPropNames.end();
+
+ while ( it != end )
+ {
+ if ( *it == rName )
+ break;
+
+ ++it;
+ }
+
+ if ( it == end )
+ {
+ aProperties[ nProps ] = rProperties[ n ];
+ nProps++;
+ }
+ }
+
+ aProperties.realloc( nProps );
+ }
+ else
+ {
+ aProperties = rProperties;
+ }
+
+ if ( aProperties.getLength() > 0 )
+ ContentProperties::UCBNamesToDAVNames(
+ aProperties, aPropNames );
+
+ if ( aPropNames.size() > 0 )
+ {
+ std::vector< DAVResource > resources;
+ try
+ {
+ xResAccess->PROPFIND(
+ DAVZERO, aPropNames, resources, xEnv );
+
+ if ( 1 == resources.size() )
+ {
+ if ( xProps.get())
+ xProps->addProperties(
+ aPropNames,
+ ContentProperties( resources[ 0 ] ));
+ else
+ xProps.reset(
+ new ContentProperties( resources[ 0 ] ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ bNetworkAccessAllowed
+ = shouldAccessNetworkAfterException( e );
+
+ if ( !bNetworkAccessAllowed )
+ {
+ cancelCommandExecution( e, xEnv );
+ // unreachable
+ }
+ }
+ }
+ }
+ }
+
+ if ( bNetworkAccessAllowed )
+ {
+ // All properties obtained already?
+ std::vector< rtl::OUString > aMissingProps;
+ if ( !( xProps.get()
+ && xProps->containsAllNames(
+ rProperties, aMissingProps ) )
+ && !m_bDidGetOrHead )
+ {
+ // Possibly the missing props can be obtained using a HEAD
+ // request.
+
+ std::vector< rtl::OUString > aHeaderNames;
+ ContentProperties::UCBNamesToHTTPNames(
+ rProperties,
+ aHeaderNames,
+ true /* bIncludeUnmatched */ );
+
+ if ( aHeaderNames.size() > 0 )
+ {
+ try
+ {
+ DAVResource resource;
+ xResAccess->HEAD( aHeaderNames, resource, xEnv );
+ m_bDidGetOrHead = true;
+
+ if ( xProps.get() )
+ xProps->addProperties(
+ aMissingProps,
+ ContentProperties( resource ) );
+ else
+ xProps.reset ( new ContentProperties( resource ) );
+
+ if ( m_eResourceType == NON_DAV )
+ xProps->addProperties( aMissingProps,
+ ContentProperties(
+ aEscapedTitle,
+ false ) );
+ }
+ catch ( DAVException const & e )
+ {
+ bNetworkAccessAllowed
+ = shouldAccessNetworkAfterException( e );
+
+ if ( !bNetworkAccessAllowed )
+ {
+ cancelCommandExecution( e, xEnv );
+ // unreachable
+ }
+ }
+ }
+ }
+ }
+
+ // might trigger HTTP redirect.
+ // Therefore, title must be updated here.
+ NeonUri aUri( xResAccess->getURL() );
+ aEscapedTitle = aUri.GetPathBaseName();
+
+ if ( UNKNOWN == rType )
+ {
+ xProps.reset( new ContentProperties( aEscapedTitle ) );
+ }
+
+ // For DAV resources we only know the Title, for non-DAV
+ // resources we additionally know that it is a document.
+ if ( DAV == rType )
+ {
+ //xProps.reset(
+ // new ContentProperties( aEscapedTitle ) );
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ uno::makeAny( aEscapedTitle ),
+ true );
+ }
+ else
+ {
+ if ( !xProps.get() )
+ xProps.reset( new ContentProperties( aEscapedTitle, false ) );
+ else
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ uno::makeAny( aEscapedTitle ),
+ true );
+
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ uno::makeAny( false ),
+ true );
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ uno::makeAny( true ),
+ true );
+ }
+ }
+ else
+ {
+ // No server access for just created (not yet committed) objects.
+ // Only a minimal set of properties supported at this stage.
+ if (m_bTransient)
+ xProps.reset( new ContentProperties( aEscapedTitle,
+ m_bCollection ) );
+ }
+
+ sal_Int32 nCount = rProperties.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const rtl::OUString rName = rProperties[ n ].Name;
+ if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "BaseURI" ) ) )
+ {
+ // Add BaseURI property, if requested.
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ),
+ uno::makeAny( getBaseURI( xResAccess ) ),
+ true );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ // Add CreatableContentsInfo property, if requested.
+ sal_Bool bFolder = sal_False;
+ xProps->getValue(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ) )
+ >>= bFolder;
+ xProps->addProperty(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
+ uno::makeAny( bFolder
+ ? queryCreatableContentsInfo()
+ : uno::Sequence< ucb::ContentInfo >() ),
+ true );
+ }
+ }
+
+ uno::Reference< sdbc::XRow > xResultRow
+ = getPropertyValues( xSMgr,
+ rProperties,
+ *xProps,
+ xProvider,
+ xIdentifier->getContentIdentifier() );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_xCachedProps.get() )
+ m_xCachedProps.reset( new ContentProperties( *xProps.get() ) );
+ else
+ m_xCachedProps->addProperties( *xProps.get() );
+
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ m_aEscapedTitle = aEscapedTitle;
+ }
+
+ return xResultRow;
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw ( uno::Exception )
+{
+ uno::Reference< lang::XMultiServiceFactory > xSMgr;
+ uno::Reference< ucb::XContentIdentifier > xIdentifier;
+ rtl::Reference< ContentProvider > xProvider;
+ sal_Bool bTransient;
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ xProvider.set( m_pProvider );
+ xIdentifier.set( m_xIdentifier );
+ bTransient = m_bTransient;
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ xSMgr.set( m_xSMgr );
+ }
+
+ uno::Sequence< uno::Any > aRet( rValues.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
+ sal_Int32 nChanged = 0;
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = static_cast< cppu::OWeakObject * >( this );
+ aEvent.Further = sal_False;
+ // aEvent.PropertyName =
+ aEvent.PropertyHandle = -1;
+ // aEvent.OldValue =
+ // aEvent.NewValue =
+
+ std::vector< ProppatchValue > aProppatchValues;
+ std::vector< sal_Int32 > aProppatchPropsPositions;
+
+ uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
+ sal_Bool bTriedToGetAdditonalPropSet = sal_False;
+
+ sal_Bool bExchange = sal_False;
+ rtl::OUString aNewTitle;
+ rtl::OUString aOldTitle;
+ sal_Int32 nTitlePos = -1;
+
+ uno::Reference< beans::XPropertySetInfo > xInfo;
+
+ const beans::PropertyValue* pValues = rValues.getConstArray();
+ sal_Int32 nCount = rValues.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::PropertyValue& rValue = pValues[ n ];
+ const rtl::OUString & rName = rValue.Name;
+
+ beans::Property aTmpProp;
+ xProvider->getProperty( rName, aTmpProp );
+
+ if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ continue;
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // Mandatory props.
+ //////////////////////////////////////////////////////////////////
+
+ if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty titles!
+ if ( aNewValue.getLength() > 0 )
+ {
+ try
+ {
+ NeonUri aURI( xIdentifier->getContentIdentifier() );
+ aOldTitle = aURI.GetPathBaseNameUnescaped();
+
+ if ( aNewValue != aOldTitle )
+ {
+ // modified title -> modified URL -> exchange !
+ if ( !bTransient )
+ bExchange = sal_True;
+
+ // new value will be set later...
+ aNewTitle = aNewValue;
+
+ // remember position within sequence of values (for
+ // error handling).
+ nTitlePos = n;
+ }
+ }
+ catch ( DAVException const & )
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid content identifier!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////
+ // Optional props.
+ //////////////////////////////////////////////////////////////
+
+ if ( !xInfo.is() )
+ xInfo = getPropertySetInfo( xEnv,
+ sal_False /* don't cache data */ );
+
+ if ( !xInfo->hasPropertyByName( rName ) )
+ {
+ // Check, whether property exists. Skip otherwise.
+ // PROPPATCH::set would add the property automatically, which
+ // is not allowed for "setPropertyValues" command!
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Property is unknown!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ continue;
+ }
+
+ if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ // Read-only property!
+ // (but could be writable, if 'getcontenttype' would be)
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ if ( rName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ // Read-only property!
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ if ( getResourceType( xEnv, xResAccess ) == DAV )
+ {
+ // Property value will be set on server.
+ ProppatchValue aValue( PROPSET, rName, rValue.Value );
+ aProppatchValues.push_back( aValue );
+
+ // remember position within sequence of values (for
+ // error handling).
+ aProppatchPropsPositions.push_back( n );
+ }
+ else
+ {
+ // Property value will be stored in local property store.
+ if ( !bTriedToGetAdditonalPropSet &&
+ !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = getAdditionalPropertySet( sal_False );
+ bTriedToGetAdditonalPropSet = sal_True;
+ }
+
+ if ( xAdditionalPropSet.is() )
+ {
+ try
+ {
+ uno::Any aOldValue
+ = xAdditionalPropSet->getPropertyValue( rName );
+ if ( aOldValue != rValue.Value )
+ {
+ xAdditionalPropSet->setPropertyValue(
+ rName, rValue.Value );
+
+ aEvent.PropertyName = rName;
+ aEvent.OldValue = aOldValue;
+ aEvent.NewValue = rValue.Value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( beans::PropertyVetoException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ catch ( lang::IllegalArgumentException const & e )
+ {
+ aRet[ n ] <<= e;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= uno::Exception(
+ rtl::OUString::createFromAscii(
+ "No property set for storing the value!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ }
+ } // for
+
+ if ( !bTransient && aProppatchValues.size() )
+ {
+ try
+ {
+ // Set property values at server.
+ xResAccess->PROPPATCH( aProppatchValues, xEnv );
+
+ std::vector< ProppatchValue >::const_iterator it
+ = aProppatchValues.begin();
+ std::vector< ProppatchValue >::const_iterator end
+ = aProppatchValues.end();
+
+ while ( it != end )
+ {
+ aEvent.PropertyName = (*it).name;
+ aEvent.OldValue = uno::Any(); // @@@ to expensive to obtain!
+ aEvent.NewValue = (*it).value;
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+
+ ++it;
+ }
+ }
+ catch ( DAVException const & e )
+ {
+// OSL_ENSURE( sal_False,
+// "Content::setPropertyValues - PROPPATCH failed!" );
+
+#if 1
+ cancelCommandExecution( e, xEnv );
+ // unreachable
+#else
+ // Note: PROPPATCH either sets ALL property values OR NOTHING.
+
+ std::vector< sal_Int32 >::const_iterator it
+ = aProppatchPropsPositions.begin();
+ std::vector< sal_Int32 >::const_iterator end
+ = aProppatchPropsPositions.end();
+
+ while ( it != end )
+ {
+ // Set error.
+ aRet[ (*it) ] <<= MapDAVException( e, sal_True );
+ ++it;
+ }
+#endif
+ }
+ }
+
+ if ( bExchange )
+ {
+ // Assemble new content identifier...
+
+ rtl::OUString aNewURL = getParentURL();
+ if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+
+ aNewURL += NeonUri::escapeSegment( aNewTitle );
+
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = new ::ucbhelper::ContentIdentifier( xSMgr, aNewURL );
+ uno::Reference< ucb::XContentIdentifier > xOldId = xIdentifier;
+
+ try
+ {
+ NeonUri sourceURI( xOldId->getContentIdentifier() );
+ NeonUri targetURI( xNewId->getContentIdentifier() );
+ targetURI.SetScheme( sourceURI.GetScheme() );
+
+ xResAccess->MOVE(
+ sourceURI.GetPath(), targetURI.GetURI(), sal_False, xEnv );
+ // @@@ Should check for resources that could not be moved
+ // (due to source access or target overwrite) and send
+ // this information through the interaction handler.
+
+ // @@@ Existing content should be checked to see if it needs
+ // to be deleted at the source
+
+ // @@@ Existing content should be checked to see if it has
+ // been overwritten at the target
+
+ if ( exchangeIdentity( xNewId ) )
+ {
+ xResAccess->setURL( aNewURL );
+
+// DAV resources store all additional props on server!
+// // Adapt Additional Core Properties.
+// renameAdditionalPropertySet( xOldId->getContentIdentifier(),
+// xNewId->getContentIdentifier(),
+// sal_True );
+ }
+ else
+ {
+ // Do not set new title!
+ aNewTitle = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= uno::Exception(
+ rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ // Do not set new title!
+ aNewTitle = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= MapDAVException( e, sal_True );
+ }
+ }
+
+ if ( aNewTitle.getLength() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( aOldTitle );
+ aEvent.NewValue = uno::makeAny( aNewTitle );
+
+ m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+
+ if ( nChanged > 0 )
+ {
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
+ }
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+uno::Any Content::open(
+ const ucb::OpenCommandArgument2 & rArg,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ uno::Any aRet;
+
+ sal_Bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) ||
+ ( rArg.Mode == ucb::OpenMode::FOLDERS ) ||
+ ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) );
+ if ( bOpenFolder )
+ {
+ if ( isFolder( xEnv ) )
+ {
+ // Open collection.
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, rArg, xEnv );
+ aRet <<= xSet;
+ }
+ else
+ {
+ // Error: Not a folder!
+
+ rtl::OUStringBuffer aMsg;
+ if ( getResourceType( xEnv ) == FTP )
+ {
+ // #114653#
+ aMsg.appendAscii( "FTP over HTTP proxy: resource cannot "
+ "be opened as folder! Wrong Open Mode!" );
+ }
+ else
+ {
+ aMsg.appendAscii( "Non-folder resource cannot be "
+ "opened as folder! Wrong Open Mode!" );
+ }
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ lang::IllegalArgumentException(
+ aMsg.makeStringAndClear(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+
+ if ( rArg.Sink.is() )
+ {
+ // Open document.
+
+ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+ {
+ // Currently(?) unsupported.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( rArg.Mode ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ uno::Reference< io::XOutputStream > xOut
+ = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
+ if ( xOut.is() )
+ {
+ // PUSH: write data
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ xResAccess.reset(
+ new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ DAVResource aResource;
+ std::vector< rtl::OUString > aHeaders;
+
+ xResAccess->GET( xOut, aHeaders, aResource, xEnv );
+ m_bDidGetOrHead = true;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // cache headers.
+ if ( !m_xCachedProps.get())
+ m_xCachedProps.reset(
+ new ContentProperties( aResource ) );
+ else
+ m_xCachedProps->addProperties( aResource );
+
+ m_xResAccess.reset(
+ new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, xEnv );
+ // Unreachable
+ }
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataSink > xDataSink
+ = uno::Reference< io::XActiveDataSink >( rArg.Sink,
+ uno::UNO_QUERY );
+ if ( xDataSink.is() )
+ {
+ // PULL: wait for client read
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ xResAccess.reset(
+ new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ // fill inputsream sync; return if all data present
+ DAVResource aResource;
+ std::vector< rtl::OUString > aHeaders;
+
+ uno::Reference< io::XInputStream > xIn
+ = xResAccess->GET( aHeaders, aResource, xEnv );
+ m_bDidGetOrHead = true;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // cache headers.
+ if ( !m_xCachedProps.get())
+ m_xCachedProps.reset(
+ new ContentProperties( aResource ) );
+ else
+ m_xCachedProps->addProperties(
+ aResource.properties );
+
+ m_xResAccess.reset(
+ new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ xDataSink->setInputStream( xIn );
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, xEnv );
+ // Unreachable
+ }
+ }
+ else
+ {
+ // Note: aOpenCommand.Sink may contain an XStream
+ // implementation. Support for this type of
+ // sink is optional...
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArg.Sink ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+void Content::post(
+ const ucb::PostCommandArgument2 & rArg,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
+ if ( xSink.is() )
+ {
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ xResAccess.reset(
+ new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ uno::Reference< io::XInputStream > xResult
+ = xResAccess->POST( rArg.MediaType,
+ rArg.Referer,
+ rArg.Source,
+ xEnv );
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_xResAccess.reset(
+ new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ xSink->setInputStream( xResult );
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, xEnv, sal_True );
+ // Unreachable
+ }
+ }
+ else
+ {
+ uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
+ if ( xResult.is() )
+ {
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ xResAccess.reset(
+ new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ xResAccess->POST( rArg.MediaType,
+ rArg.Referer,
+ rArg.Source,
+ xResult,
+ xEnv );
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ m_xResAccess.reset(
+ new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, xEnv, sal_True );
+ // Unreachable
+ }
+ }
+ else
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArg.Sink ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+}
+
+//=========================================================================
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ // Obtain a list with a snapshot of all currently instanciated contents
+ // from provider and extract the contents which are direct children
+ // of this content.
+
+ ::ucbhelper::ContentRefList aAllContents;
+ m_xProvider->queryExistingContents( aAllContents );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( aURL.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aURL += rtl::OUString::createFromAscii( "/" );
+ }
+
+ sal_Int32 nLen = aURL.getLength();
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ while ( it != end )
+ {
+ ::ucbhelper::ContentImplHelperRef xChild = (*it);
+ rtl::OUString aChildURL
+ = xChild->getIdentifier()->getContentIdentifier();
+
+ // Is aURL a prefix of aChildURL?
+ if ( ( aChildURL.getLength() > nLen ) &&
+ ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ if ( ( nPos == -1 ) ||
+ ( nPos == ( aChildURL.getLength() - 1 ) ) )
+ {
+ // No further slashes / only a final slash. It's a child!
+ rChildren.push_back(
+ ::webdav_ucp::Content::ContentRef(
+ static_cast< ::webdav_ucp::Content * >(
+ xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+void Content::insert(
+ const uno::Reference< io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception )
+{
+ sal_Bool bTransient, bCollection;
+ rtl::OUString aEscapedTitle;
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ bTransient = m_bTransient;
+ bCollection = m_bCollection;
+ aEscapedTitle = m_aEscapedTitle;
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ // Check, if all required properties are present.
+
+ if ( aEscapedTitle.getLength() == 0 )
+ {
+ OSL_ENSURE( sal_False, "Content::insert - Title missing!" );
+
+ uno::Sequence< rtl::OUString > aProps( 1 );
+ aProps[ 0 ] = rtl::OUString::createFromAscii( "Title" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingPropertiesException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aProps ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !bReplaceExisting )
+ {
+ /* [RFC 2616] - HTTP
+
+ The PUT method requests that the enclosed entity be stored under the
+ supplied Request-URI. If the Request-URI refers to an already
+ existing resource, the enclosed entity SHOULD be considered as a
+ modified version of the one residing on the origin server.
+ */
+
+ /* [RFC 2518] - WebDAV
+
+ MKCOL creates a new collection resource at the location specified by
+ the Request-URI. If the resource identified by the Request-URI is
+ non-null then the MKCOL MUST fail.
+ */
+
+ // ==> Complain on PUT, continue on MKCOL.
+ if ( !bTransient || ( bTransient && !bCollection ) )
+ {
+ ucb::UnsupportedNameClashException aEx(
+ rtl::OUString::createFromAscii(
+ "Unable to write without overwrite!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ ucb::NameClash::ERROR );
+
+ uno::Reference< task::XInteractionHandler > xIH;
+
+ if ( Environment.is() )
+ xIH = Environment->getInteractionHandler();
+
+ if ( xIH.is() )
+ {
+ uno::Any aExAsAny( uno::makeAny( aEx ) );
+
+ rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest
+ = new ucbhelper::SimpleInteractionRequest(
+ aExAsAny,
+ ucbhelper::CONTINUATION_APPROVE
+ | ucbhelper::CONTINUATION_DISAPPROVE );
+ xIH->handle( xRequest.get() );
+
+ const sal_Int32 nResp = xRequest->getResponse();
+
+ switch ( nResp )
+ {
+ case ucbhelper::CONTINUATION_UNKNOWN:
+ // Not handled; throw.
+ throw aEx;
+// break;
+
+ case ucbhelper::CONTINUATION_APPROVE:
+ // Continue -> Overwrite.
+ bReplaceExisting = sal_True;
+ break;
+
+ case ucbhelper::CONTINUATION_DISAPPROVE:
+ // Abort.
+ throw ucb::CommandFailedException(
+ rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ aExAsAny );
+// break;
+
+ default:
+ OSL_ENSURE( sal_False,
+ "Content::insert - "
+ "Unknown interaction selection!" );
+ throw ucb::CommandFailedException(
+ rtl::OUString::createFromAscii(
+ "Unknown interaction selection!" ),
+ uno::Reference< uno::XInterface >(),
+ aExAsAny );
+// break;
+ }
+ }
+ else
+ {
+ // No IH; throw.
+ throw aEx;
+ }
+ }
+ }
+
+ if ( bTransient )
+ {
+ // Assemble new content identifier...
+ rtl::OUString aURL = getParentURL();
+ if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ aURL += aEscapedTitle;
+
+ try
+ {
+ xResAccess->setURL( aURL );
+
+ if ( bCollection )
+ xResAccess->MKCOL( Environment );
+ else
+ xResAccess->PUT( xInputStream, Environment );
+ }
+ catch ( DAVException const & except )
+ {
+ if ( bCollection )
+ {
+ if ( except.getStatus() == SC_METHOD_NOT_ALLOWED )
+ {
+ // [RFC 2518] - WebDAV
+ // 405 (Method Not Allowed) - MKCOL can only be
+ // executed on a deleted/non-existent resource.
+
+ if ( bReplaceExisting )
+ {
+ // Destroy old resource.
+ try
+ {
+ xResAccess->DESTROY( Environment );
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, Environment, sal_True );
+ // Unreachable
+ }
+
+ // Insert (recursion!).
+ insert( xInputStream, bReplaceExisting, Environment );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset(
+ new DAVResourceAccess( *xResAccess.get() ) );
+ }
+
+ // Success!
+ return;
+ }
+ else
+ {
+ rtl::OUString aTitle;
+ try
+ {
+ NeonUri aURI( aURL );
+ aTitle = aURI.GetPathBaseNameUnescaped();
+ }
+ catch ( DAVException const & )
+ {
+ }
+
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ aTitle ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+ }
+
+ cancelCommandExecution( except, Environment, sal_True );
+ // Unreachable
+ }
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xIdentifier
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
+ }
+
+ inserted();
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_bTransient = sal_False;
+ }
+ }
+ else
+ {
+ if ( !xInputStream.is() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::MissingInputStreamException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ try
+ {
+ xResAccess->PUT( xInputStream, Environment );
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, Environment, sal_True );
+ // Unreachable
+ }
+ }
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+}
+
+//=========================================================================
+void Content::transfer(
+ const ucb::TransferInfo & rArgs,
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception )
+{
+ uno::Reference< lang::XMultiServiceFactory > xSMgr;
+ uno::Reference< ucb::XContentIdentifier > xIdentifier;
+ uno::Reference< ucb::XContentProvider > xProvider;
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ xSMgr.set( m_xSMgr );
+ xIdentifier.set( m_xIdentifier );
+ xProvider.set( m_xProvider.get() );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ rtl::OUString aTargetURI;
+ try
+ {
+ NeonUri sourceURI( rArgs.SourceURL );
+ NeonUri targetURI( xIdentifier->getContentIdentifier() );
+ aTargetURI = targetURI.GetPathBaseNameUnescaped();
+
+ // Check source's and target's URL scheme
+ //
+ const rtl::OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase();
+ if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
+ {
+ sourceURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
+ }
+ else if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
+ {
+ sourceURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
+ }
+ else if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
+ {
+ sourceURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
+ }
+ else
+ {
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::InteractiveBadTransferURLException(
+ rtl::OUString::createFromAscii(
+ "Unsupported URL scheme!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
+ targetURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
+ else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
+ targetURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
+
+ // @@@ This implementation of 'transfer' only works
+ // if the source and target are located at same host.
+ // (Neon does not support cross-server copy/move)
+
+ // Check for same host
+ //
+ if ( sourceURI.GetHost().getLength() &&
+ ( sourceURI.GetHost() != targetURI.GetHost() ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString::createFromAscii(
+ "Different hosts!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ rtl::OUString aTitle = rArgs.NewTitle;
+
+ if ( !aTitle.getLength() )
+ aTitle = sourceURI.GetPathBaseNameUnescaped();
+
+ if ( aTitle.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "/" ) ) )
+ {
+ // kso: ???
+ aTitle = rtl::OUString();
+ }
+
+ targetURI.AppendPath( aTitle );
+
+ rtl::OUString aTargetURL = xIdentifier->getContentIdentifier();
+ if ( ( aTargetURL.lastIndexOf( '/' ) + 1 )
+ != aTargetURL.getLength() )
+ aTargetURL += rtl::OUString::createFromAscii( "/" );
+
+ aTargetURL += aTitle;
+
+ uno::Reference< ucb::XContentIdentifier > xTargetId
+ = new ::ucbhelper::ContentIdentifier( xSMgr, aTargetURL );
+
+ DAVResourceAccess aSourceAccess( xSMgr,
+ xResAccess->getSessionFactory(),
+ sourceURI.GetURI() );
+
+ if ( rArgs.MoveData == sal_True )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( xSMgr, rArgs.SourceURL );
+
+ // Note: The static cast is okay here, because its sure that
+ // xProvider is always the WebDAVContentProvider.
+ rtl::Reference< Content > xSource
+ = static_cast< Content * >(
+ xProvider->queryContent( xId ).get() );
+
+ // [RFC 2518] - WebDAV
+ // If a resource exists at the destination and the Overwrite
+ // header is "T" then prior to performing the move the server
+ // MUST perform a DELETE with "Depth: infinity" on the
+ // destination resource. If the Overwrite header is set to
+ // "F" then the operation will fail.
+
+ aSourceAccess.MOVE( sourceURI.GetPath(),
+ targetURI.GetURI(),
+ rArgs.NameClash
+ == ucb::NameClash::OVERWRITE,
+ Environment );
+
+ if ( xSource.is() )
+ {
+ // Propagate destruction to listeners.
+ xSource->destroy( sal_True );
+ }
+
+// DAV resources store all additional props on server!
+// // Rename own and all children's Additional Core Properties.
+// renameAdditionalPropertySet( xId->getContentIdentifier(),
+// xTargetId->getContentIdentifier(),
+// sal_True );
+ }
+ else
+ {
+ // [RFC 2518] - WebDAV
+ // If a resource exists at the destination and the Overwrite
+ // header is "T" then prior to performing the copy the server
+ // MUST perform a DELETE with "Depth: infinity" on the
+ // destination resource. If the Overwrite header is set to
+ // "F" then the operation will fail.
+
+ aSourceAccess.COPY( sourceURI.GetPath(),
+ targetURI.GetURI(),
+ rArgs.NameClash
+ == ucb::NameClash::OVERWRITE,
+ Environment );
+
+// DAV resources store all additional props on server!
+// // Copy own and all children's Additional Core Properties.
+// copyAdditionalPropertySet( xId->getContentIdentifier(),
+// xTargetId->getContentIdentifier(),
+// sal_True );
+ }
+
+ // Note: The static cast is okay here, because its sure that
+ // xProvider is always the WebDAVContentProvider.
+ rtl::Reference< Content > xTarget
+ = static_cast< Content * >(
+ xProvider->queryContent( xTargetId ).get() );
+
+ // Announce transfered content in its new folder.
+ xTarget->inserted();
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+ catch ( DAVException const & e )
+ {
+ // [RFC 2518] - WebDAV
+ // 412 (Precondition Failed) - The server was unable to maintain
+ // the liveness of the properties listed in the propertybehavior
+ // XML element or the Overwrite header is "F" and the state of
+ // the destination resource is non-null.
+
+ if ( e.getStatus() == SC_PRECONDITION_FAILED )
+ {
+ switch ( rArgs.NameClash )
+ {
+ case ucb::NameClash::ERROR:
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ aTargetURI ) ),
+ Environment );
+ // Unreachable
+ }
+
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::RENAME:
+ case ucb::NameClash::ASK:
+ default:
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArgs.NameClash ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+ }
+
+ cancelCommandExecution( e, Environment, sal_True );
+ // Unreachable
+ }
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+}
+
+//=========================================================================
+void Content::destroy( sal_Bool bDeletePhysical )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ deleted();
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Process instanciated children...
+
+ ::webdav_ucp::Content::ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical );
+ ++it;
+ }
+}
+
+//=========================================================================
+bool Content::supportsExclusiveWriteLock(
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+{
+ if ( getResourceType( Environment ) == DAV )
+ {
+ if ( m_xCachedProps.get() )
+ {
+ uno::Sequence< ucb::LockEntry > aSupportedLocks;
+ if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK )
+ >>= aSupportedLocks )
+ {
+ for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
+ {
+ if ( aSupportedLocks[ n ].Scope
+ == ucb::LockScope_EXCLUSIVE &&
+ aSupportedLocks[ n ].Type
+ == ucb::LockType_WRITE )
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+//=========================================================================
+void Content::lock(
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception )
+{
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ uno::Any aOwnerAny;
+ aOwnerAny
+ <<= rtl::OUString::createFromAscii( "http://ucb.openoffice.org" );
+
+ ucb::Lock aLock(
+ ucb::LockScope_EXCLUSIVE,
+ ucb::LockType_WRITE,
+ ucb::LockDepth_ZERO,
+ aOwnerAny,
+ 180, // lock timeout in secs
+ //-1, // infinite lock
+ uno::Sequence< ::rtl::OUString >() );
+
+ xResAccess->LOCK( aLock, Environment );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, Environment, sal_False );
+ // Unreachable
+ }
+}
+
+//=========================================================================
+void Content::unlock(
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ throw( uno::Exception )
+{
+ try
+ {
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+
+ xResAccess->UNLOCK( Environment );
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ cancelCommandExecution( e, Environment, sal_False );
+ // Unreachable
+ }
+}
+
+//=========================================================================
+sal_Bool Content::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Already persistent?
+ if ( m_bTransient )
+ {
+ OSL_ENSURE( sal_False, "Content::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+// if ( !hasData( xNewId ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier >
+ xOldChildId = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ return sal_True;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - "
+ "Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool Content::isFolder(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bTransient )
+ return m_bCollection;
+ }
+
+ uno::Sequence< beans::Property > aProperties( 1 );
+ aProperties[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" );
+ aProperties[ 0 ].Handle = -1;
+ uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) );
+ if ( xRow.is() )
+ {
+ try
+ {
+ return xRow->getBoolean( 1 );
+ }
+ catch ( sdbc::SQLException const & )
+ {
+ }
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite )
+{
+ // Map DAVException...
+ uno::Any aException;
+
+ switch ( e.getStatus() )
+ {
+ case SC_NOT_FOUND:
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(m_xIdentifier->getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE);
+
+ aException <<=
+ ucb::InteractiveAugmentedIOException(
+ rtl::OUString::createFromAscii( "Not found!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ ucb::IOErrorCode_NOT_EXISTING,
+ aArgs );
+ return aException;
+ }
+ default:
+ break;
+ }
+
+ switch ( e.getError() )
+ {
+ case DAVException::DAV_HTTP_ERROR:
+ {
+ if ( bWrite )
+ aException <<=
+ ucb::InteractiveNetworkWriteException(
+ e.getData(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ e.getData() );
+ else
+ aException <<=
+ ucb::InteractiveNetworkReadException(
+ e.getData(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ e.getData() );
+ break;
+ }
+
+ case DAVException::DAV_HTTP_LOOKUP:
+ aException <<=
+ ucb::InteractiveNetworkResolveNameException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ e.getData() );
+ break;
+
+// @@@ No matching InteractiveNetwork*Exception
+// case DAVException::DAV_HTTP_AUTH:
+// break;
+
+// @@@ No matching InteractiveNetwork*Exception
+// case DAVException::DAV_HTTP_AUTHPROXY:
+// break;
+
+ case DAVException::DAV_HTTP_CONNECT:
+ aException <<=
+ ucb::InteractiveNetworkConnectException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ e.getData() );
+ break;
+
+// @@@ No matching InteractiveNetwork*Exception
+// case DAVException::DAV_HTTP_TIMEOUT:
+// break;
+
+// @@@ No matching InteractiveNetwork*Exception
+// case DAVException::DAV_HTTP_REDIRECT:
+// break;
+
+// @@@ No matching InteractiveNetwork*Exception
+// case DAVException::DAV_SESSION_CREATE:
+// break;
+
+ case DAVException::DAV_INVALID_ARG:
+ aException <<=
+ lang::IllegalArgumentException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ break;
+
+ case DAVException::DAV_LOCKED:
+#if 1
+ aException <<=
+ ucb::InteractiveLockingLockedException(
+ rtl::OUString::createFromAscii( "Locked!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_xIdentifier->getContentIdentifier(),
+ sal_True );
+#else
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[ 0 ] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(m_xIdentifier->getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE);
+
+ aException <<=
+ ucb::InteractiveAugmentedIOException(
+ rtl::OUString::createFromAscii( "Locked!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ ucb::IOErrorCode_LOCKING_VIOLATION,
+ aArgs );
+ }
+#endif
+ break;
+
+ case DAVException::DAV_LOCKED_SELF:
+ aException <<=
+ ucb::InteractiveLockingLockedException(
+ rtl::OUString::createFromAscii( "Locked (self)!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_xIdentifier->getContentIdentifier(),
+ sal_True );
+ break;
+
+ case DAVException::DAV_NOT_LOCKED:
+ aException <<=
+ ucb::InteractiveLockingNotLockedException(
+ rtl::OUString::createFromAscii( "Not locked!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_xIdentifier->getContentIdentifier() );
+ break;
+
+ case DAVException::DAV_LOCK_EXPIRED:
+ aException <<=
+ ucb::InteractiveLockingLockExpiredException(
+ rtl::OUString::createFromAscii( "Lock expired!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_xIdentifier->getContentIdentifier() );
+ break;
+
+ default:
+ aException <<=
+ ucb::InteractiveNetworkGeneralException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR );
+ break;
+ }
+
+ return aException;
+}
+
+//=========================================================================
+// static
+bool Content::shouldAccessNetworkAfterException( const DAVException & e )
+{
+ if ( ( e.getStatus() == SC_NOT_FOUND ) ||
+ ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) ||
+ ( e.getError() == DAVException::DAV_HTTP_CONNECT ) ||
+ ( e.getError() == DAVException::DAV_HTTP_AUTH ) ||
+ ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY ) )
+ return false;
+
+ return true;
+}
+
+//=========================================================================
+void Content::cancelCommandExecution(
+ const DAVException & e,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv,
+ sal_Bool bWrite /* = sal_False */ )
+ throw ( uno::Exception )
+{
+ ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv );
+ // Unreachable
+}
+
+//=========================================================================
+const rtl::OUString
+Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // First, try to obtain value of response header "Content-Location".
+ if ( m_xCachedProps.get() )
+ {
+ rtl::OUString aLocation;
+ m_xCachedProps->getValue( rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Content-Location" ) ) ) >>= aLocation;
+ if ( aLocation.getLength() )
+ {
+ try
+ {
+ // Do not use m_xIdentifier->getContentIdentifier() because it
+ // for example does not reflect redirects applied to requests
+ // done using the original URI but m_xResAccess' URI does.
+ return rtl::Uri::convertRelToAbs( rResAccess->getURL(),
+ aLocation );
+ }
+ catch ( rtl::MalformedUriException const & )
+ {
+ }
+ }
+ }
+
+ return rtl::OUString( rResAccess->getURL() );
+}
+
+//=========================================================================
+const Content::ResourceType & Content::getResourceType(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv,
+ const std::auto_ptr< DAVResourceAccess > & rResAccess )
+ throw ( uno::Exception )
+{
+ if ( m_eResourceType == UNKNOWN )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ResourceType eResourceType;
+ eResourceType = m_eResourceType;
+
+ const rtl::OUString & rURL = rResAccess->getURL();
+ const rtl::OUString aScheme(
+ rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() );
+
+ if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) )
+ {
+ eResourceType = FTP;
+ }
+ else
+ {
+ try
+ {
+ // Try to fetch some frequently used property value, e.g. those
+ // used when loading documents... along with identifying whether
+ // this is a DAV resource.
+ std::vector< DAVResource > resources;
+ std::vector< rtl::OUString > aPropNames;
+ uno::Sequence< beans::Property > aProperties( 5 );
+ aProperties[ 0 ].Name
+ = rtl::OUString::createFromAscii( "IsFolder" );
+ aProperties[ 1 ].Name
+ = rtl::OUString::createFromAscii( "IsDocument" );
+ aProperties[ 2 ].Name
+ = rtl::OUString::createFromAscii( "IsReadOnly" );
+ aProperties[ 3 ].Name
+ = rtl::OUString::createFromAscii( "MediaType" );
+ aProperties[ 4 ].Name
+ = DAVProperties::SUPPORTEDLOCK;
+
+ ContentProperties::UCBNamesToDAVNames(
+ aProperties, aPropNames );
+
+ rResAccess->PROPFIND(
+ DAVZERO, aPropNames, resources, xEnv );
+
+ if ( resources.size() == 1 )
+ {
+ m_xCachedProps.reset(
+ new ContentProperties( resources[ 0 ] ) );
+ m_xCachedProps->containsAllNames(
+ aProperties, m_aFailedPropNames );
+ }
+
+ eResourceType = DAV;
+ }
+ catch ( DAVException const & e )
+ {
+ rResAccess->resetUri();
+
+ if ( e.getStatus() == SC_METHOD_NOT_ALLOWED )
+ {
+ // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the
+ // resource is NON_DAV
+ eResourceType = NON_DAV;
+ }
+ }
+ }
+ m_eResourceType = eResourceType;
+ }
+ return m_eResourceType;
+}
+
+//=========================================================================
+const Content::ResourceType & Content::getResourceType(
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw ( uno::Exception )
+{
+ return getResourceType( xEnv, m_xResAccess );
+}
diff --git a/ucb/source/ucp/webdav/webdavcontent.hxx b/ucb/source/ucp/webdav/webdavcontent.hxx
new file mode 100644
index 000000000000..0568b2bfbb54
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavcontent.hxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_CONTENT_HXX
+#define _WEBDAV_UCP_CONTENT_HXX
+
+#include <memory>
+#include <list>
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+#include "DAVResourceAccess.hxx"
+#include "PropertyMap.hxx"
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+ struct PropertyValue;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace io {
+ class XInputStream;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class XRow;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ struct OpenCommandArgument2;
+ struct PostCommandArgument2;
+ struct TransferInfo;
+} } } }
+
+namespace webdav_ucp
+{
+
+//=========================================================================
+
+// UNO service name for the content.
+#define WEBDAV_CONTENT_SERVICE_NAME "com.sun.star.ucb.WebDAVContent"
+
+//=========================================================================
+
+class ContentProvider;
+class ContentProperties;
+
+class Content : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ResourceType
+ {
+ UNKNOWN,
+ FTP,
+ NON_DAV,
+ DAV
+ };
+
+ std::auto_ptr< DAVResourceAccess > m_xResAccess;
+ std::auto_ptr< ContentProperties > m_xCachedProps; // locally cached props
+ rtl::OUString m_aEscapedTitle;
+ ResourceType m_eResourceType;
+ ContentProvider* m_pProvider; // No need for a ref, base class holds object
+ bool m_bTransient;
+ bool m_bCollection;
+ bool m_bDidGetOrHead;
+ std::vector< rtl::OUString > m_aFailedPropNames;
+
+private:
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ sal_Bool isFolder( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::uno::Exception );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::uno::Exception );
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::uno::Exception );
+
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+ void queryChildren( ContentRefList& rChildren);
+
+ sal_Bool
+ exchangeIdentity( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+
+ const rtl::OUString
+ getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess );
+
+ const ResourceType &
+ getResourceType( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::uno::Exception );
+
+ const ResourceType &
+ getResourceType( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv,
+ const std::auto_ptr< DAVResourceAccess > & rResAccess )
+ throw ( ::com::sun::star::uno::Exception );
+
+ // Command "open"
+ com::sun::star::uno::Any open(
+ const com::sun::star::ucb::OpenCommandArgument2 & rArg,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "post"
+ void post( const com::sun::star::ucb::PostCommandArgument2 & rArg,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "insert"
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "transfer"
+ void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "delete"
+ void destroy( sal_Bool bDeletePhysical )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "lock"
+ void lock( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "unlock"
+ void unlock( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+ ::com::sun::star::uno::Any MapDAVException( const DAVException & e,
+ sal_Bool bWrite );
+ void cancelCommandExecution(
+ const DAVException & e,
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv,
+ sal_Bool bWrite = sal_False )
+ throw( ::com::sun::star::uno::Exception );
+
+ static bool shouldAccessNetworkAfterException( const DAVException & e );
+
+ bool supportsExclusiveWriteLock(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment );
+
+public:
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ rtl::Reference< DAVSessionFactory > const & rSessionFactory )
+ throw ( ::com::sun::star::ucb::ContentCreationException );
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ rtl::Reference< DAVSessionFactory > const & rSessionFactory,
+ sal_Bool isCollection )
+ throw ( ::com::sun::star::ucb::ContentCreationException );
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XPropertyContainer
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& Name,
+ sal_Int16 Attributes,
+ const com::sun::star::uno::Any& DefaultValue )
+ throw( com::sun::star::beans::PropertyExistException,
+ com::sun::star::beans::IllegalTypeException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ removeProperty( const rtl::OUString& Name )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::NotRemoveableException,
+ com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ DAVResourceAccess & getResourceAccess() { return *m_xResAccess; }
+
+ // Called from resultset data supplier.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ContentProperties& rData,
+ const rtl::Reference<
+ ::ucbhelper::ContentProviderImplHelper >& rProvider,
+ const ::rtl::OUString& rContentId );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/webdavcontentcaps.cxx b/ucb/source/ucp/webdav/webdavcontentcaps.cxx
new file mode 100644
index 000000000000..145c256010f9
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavcontentcaps.cxx
@@ -0,0 +1,672 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <set>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/ucb/Link.hpp>
+#include <com/sun/star/ucb/Lock.hpp>
+#include <com/sun/star/ucb/LockEntry.hpp>
+#include "webdavcontent.hxx"
+#include "webdavprovider.hxx"
+#include "DAVSession.hxx"
+#include "ContentProperties.hxx"
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+//=========================================================================
+//
+// ContentProvider implementation.
+//
+//=========================================================================
+
+bool ContentProvider::getProperty(
+ const rtl::OUString & rPropName, beans::Property & rProp, bool bStrict )
+{
+ if ( !m_pProps )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_pProps )
+ {
+ m_pProps = new PropertyMap;
+
+ //////////////////////////////////////////////////////////////
+ // Fill map of known properties...
+ //////////////////////////////////////////////////////////////
+
+ // Mandatory UCB properties.
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ) );
+
+ // Optional UCB properties.
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
+ -1,
+ getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
+ -1,
+ getCppuType( static_cast< const util::DateTime * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
+ -1,
+ getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Standard DAV properties.
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::CREATIONDATE,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::DISPLAYNAME,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::GETCONTENTLANGUAGE,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::GETCONTENTLENGTH,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::GETCONTENTTYPE ,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::GETETAG,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::GETLASTMODIFIED,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::LOCKDISCOVERY,
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::Lock > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::RESOURCETYPE,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::SOURCE,
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::Link > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::SUPPORTEDLOCK,
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence<
+ ucb::LockEntry > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ m_pProps->insert(
+ beans::Property(
+ DAVProperties::EXECUTABLE,
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND ) );
+ }
+ }
+
+ //////////////////////////////////////////////////////////////
+ // Lookup property.
+ //////////////////////////////////////////////////////////////
+
+ beans::Property aProp;
+ aProp.Name = rPropName;
+ const PropertyMap::const_iterator it = m_pProps->find( aProp );
+ if ( it != m_pProps->end() )
+ {
+ rProp = (*it);
+ }
+ else
+ {
+ if ( bStrict )
+ return false;
+
+ // All unknown props are treated as:
+ rProp = beans::Property(
+ rPropName,
+ - 1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ }
+
+ return true;
+}
+
+//=========================================================================
+//
+// Content implementation.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+{
+ sal_Bool bTransient;
+ std::auto_ptr< DAVResourceAccess > xResAccess;
+ std::auto_ptr< ContentProperties > xCachedProps;
+ rtl::Reference< ContentProvider > xProvider;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ bTransient = m_bTransient;
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ if ( m_xCachedProps.get() )
+ xCachedProps.reset(
+ new ContentProperties( *m_xCachedProps.get() ) );
+ xProvider.set( m_pProvider );
+ }
+
+ typedef std::set< rtl::OUString > StringSet;
+ StringSet aPropSet;
+
+ // No server access for just created (not yet committed) objects.
+ // Only a minimal set of properties supported at this stage.
+ if ( !bTransient )
+ {
+ // Obtain all properties supported for this resource from server.
+ try
+ {
+ std::vector< DAVResourceInfo > props;
+ xResAccess->PROPFIND( DAVZERO, props, xEnv );
+
+ // Note: vector always contains exactly one resource info, because
+ // we used a depth of DAVZERO for PROPFIND.
+ aPropSet.insert( (*props.begin()).properties.begin(),
+ (*props.begin()).properties.end() );
+ }
+ catch ( DAVException const & )
+ {
+ }
+ }
+
+ // Add DAV properties, map DAV properties to UCB properties.
+ sal_Bool bHasCreationDate = sal_False; // creationdate <-> DateCreated
+ sal_Bool bHasGetLastModified = sal_False; // getlastmodified <-> DateModified
+ sal_Bool bHasGetContentType = sal_False; // getcontenttype <-> MediaType
+ sal_Bool bHasGetContentLength = sal_False; // getcontentlength <-> Size
+
+ sal_Bool bHasContentType = sal_False;
+ sal_Bool bHasIsDocument = sal_False;
+ sal_Bool bHasIsFolder = sal_False;
+ sal_Bool bHasTitle = sal_False;
+ sal_Bool bHasBaseURI = sal_False;
+ sal_Bool bHasDateCreated = sal_False;
+ sal_Bool bHasDateModified = sal_False;
+ sal_Bool bHasMediaType = sal_False;
+ sal_Bool bHasSize = sal_False;
+ sal_Bool bHasCreatableInfos = sal_False;
+
+ {
+ std::set< rtl::OUString >::const_iterator it = aPropSet.begin();
+ std::set< rtl::OUString >::const_iterator end = aPropSet.end();
+ while ( it != end )
+ {
+ if ( !bHasCreationDate &&
+ ( (*it) == DAVProperties::CREATIONDATE ) )
+ {
+ bHasCreationDate = sal_True;
+ }
+ else if ( !bHasGetLastModified &&
+ ( (*it) == DAVProperties::GETLASTMODIFIED ) )
+ {
+ bHasGetLastModified = sal_True;
+ }
+ else if ( !bHasGetContentType &&
+ ( (*it) == DAVProperties::GETCONTENTTYPE ) )
+ {
+ bHasGetContentType = sal_True;
+ }
+ else if ( !bHasGetContentLength &&
+ ( (*it) == DAVProperties::GETCONTENTLENGTH ) )
+ {
+ bHasGetContentLength = sal_True;
+ }
+ else if ( !bHasContentType &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
+ {
+ bHasContentType = sal_True;
+ }
+ else if ( !bHasIsDocument &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ bHasIsDocument = sal_True;
+ }
+ else if ( !bHasIsFolder &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ bHasIsFolder = sal_True;
+ }
+ else if ( !bHasTitle &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ bHasTitle = sal_True;
+ }
+ else if ( !bHasBaseURI &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "BaseURI" ) ) )
+ {
+ bHasBaseURI = sal_True;
+ }
+ else if ( !bHasDateCreated &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) )
+ {
+ bHasDateCreated = sal_True;
+ }
+ else if ( !bHasDateModified &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
+ {
+ bHasDateModified = sal_True;
+ }
+ else if ( !bHasMediaType &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
+ {
+ bHasMediaType = sal_True;
+ }
+ else if ( !bHasSize &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
+ {
+ bHasSize = sal_True;
+ }
+ else if ( !bHasCreatableInfos &&
+ (*it).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "CreatableContentsInfo" ) ) )
+ {
+ bHasCreatableInfos = sal_True;
+ }
+ it++;
+ }
+ }
+
+ // Add mandatory properties.
+ if ( !bHasContentType )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ) );
+
+ if ( !bHasIsDocument )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ) );
+
+ if ( !bHasIsFolder )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ) );
+
+ if ( !bHasTitle )
+ {
+ // Always present since it can be calculated from content's URI.
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) );
+ }
+
+ // Add optional properties.
+
+ if ( !bHasBaseURI )
+ {
+ // Always present since it can be calculated from content's URI.
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) );
+ }
+
+ if ( !bHasDateCreated && bHasCreationDate )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ) );
+
+ if ( !bHasDateModified && bHasGetLastModified )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) );
+
+ if ( !bHasMediaType && bHasGetContentType )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) );
+
+ if ( !bHasSize && bHasGetContentLength )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ) );
+
+ if ( !bHasCreatableInfos )
+ aPropSet.insert(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ) );
+
+ // Add cached properties, if present and still missing.
+ if ( xCachedProps.get() )
+ {
+ const std::set< rtl::OUString >::const_iterator set_end
+ = aPropSet.end();
+
+ const std::auto_ptr< PropertyValueMap > & xProps
+ = xCachedProps->getProperties();
+
+ PropertyValueMap::const_iterator map_it = xProps->begin();
+ const PropertyValueMap::const_iterator map_end = xProps->end();
+
+ while ( map_it != map_end )
+ {
+ if ( aPropSet.find( (*map_it).first ) == set_end )
+ aPropSet.insert( (*map_it).first );
+
+ ++map_it;
+ }
+ }
+
+ // std::set -> uno::Sequence
+ sal_Int32 nCount = aPropSet.size();
+ uno::Sequence< beans::Property > aProperties( nCount );
+
+ std::set< rtl::OUString >::const_iterator it = aPropSet.begin();
+ beans::Property aProp;
+
+ for ( sal_Int32 n = 0; n < nCount; ++n, ++it )
+ {
+ xProvider->getProperty( (*it), aProp );
+ aProperties[ n ] = aProp;
+ }
+
+ return aProperties;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< ucb::CommandInfo > aCmdInfo( 8 );
+
+ ///////////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////////
+
+ aCmdInfo[ 0 ] =
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType() );
+ aCmdInfo[ 1 ] =
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType() );
+ aCmdInfo[ 2 ] =
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType( static_cast<
+ uno::Sequence< beans::Property > * >( 0 ) ) );
+ aCmdInfo[ 3 ] =
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType( static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) ) );
+
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
+
+ aCmdInfo[ 4 ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType() );
+ aCmdInfo[ 5 ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuType( static_cast<
+ ucb::InsertCommandArgument * >( 0 ) ) );
+ aCmdInfo[ 6 ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType( static_cast<
+ ucb::OpenCommandArgument2 * >( 0 ) ) );
+
+ ///////////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////////
+
+ aCmdInfo[ 7 ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "post" ) ),
+ -1,
+ getCppuType( static_cast<
+ ucb::PostCommandArgument2 * >( 0 ) ) );
+
+ sal_Bool bFolder = sal_False;
+
+ try
+ {
+ bFolder = isFolder( xEnv );
+ }
+ catch ( uno::Exception const & )
+ {
+ return aCmdInfo;
+ }
+
+ sal_Bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
+
+ sal_Int32 nPos = aCmdInfo.getLength();
+ sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 );
+ if ( nMoreCmds )
+ aCmdInfo.realloc( nPos + nMoreCmds );
+ else
+ return aCmdInfo;
+
+ if ( bFolder )
+ {
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
+
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) ) );
+ nPos++;
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) ) );
+ nPos++;
+ }
+ else
+ {
+ // no document-only commands at the moment.
+ }
+
+ if ( bSupportsLocking )
+ {
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lock" ) ),
+ -1,
+ getCppuVoidType() );
+ nPos++;
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unlock" ) ),
+ -1,
+ getCppuVoidType() );
+ nPos++;
+ }
+ return aCmdInfo;
+}
diff --git a/ucb/source/ucp/webdav/webdavdatasupplier.cxx b/ucb/source/ucp/webdav/webdavdatasupplier.cxx
new file mode 100644
index 000000000000..8d2683939f0d
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavdatasupplier.cxx
@@ -0,0 +1,512 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+#include "webdavdatasupplier.hxx"
+#include "webdavcontent.hxx"
+#include "ContentProperties.hxx"
+#ifndef _WEBDAV_SESSION_HXX
+#include "DAVSession.hxx"
+#endif
+#include "NeonUri.hxx"
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+namespace webdav_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aId;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+ const ContentProperties* pData;
+
+ ResultListEntry( const ContentProperties* pEntry ) : pData( pEntry ) {};
+ ~ResultListEntry() { delete pData; }
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+ sal_Bool m_bThrowException;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ), m_nOpenMode( nOpenMode ),
+ m_bCountFinal( sal_False ), m_bThrowException( sal_False ) {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DataSupplier::DataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+DataSupplier::~DataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ rtl::OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
+
+ const ContentProperties& props
+ = *( m_pImpl->m_aResults[ nIndex ]->pData );
+
+ if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ aId += props.getEscapedTitle();
+
+ if ( props.isTrailingSlash() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent >
+DataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException& )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Obtain values...
+ if ( getData() )
+ {
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::totalCount()
+{
+ // Obtain values...
+ getData();
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 DataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool DataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
+ sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ uno::Reference< sdbc::XRow > xRow
+ = Content::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ *(m_pImpl->m_aResults[ nIndex ]->pData),
+ rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
+ m_pImpl->m_xContent->getProvider().get() ),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void DataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+ if ( m_pImpl->m_bThrowException )
+ throw ucb::ResultSetException();
+}
+
+//=========================================================================
+sal_Bool DataSupplier::getData()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( !m_pImpl->m_bCountFinal )
+ {
+ std::vector< rtl::OUString > propertyNames;
+ ContentProperties::UCBNamesToDAVNames(
+ getResultSet()->getProperties(), propertyNames );
+
+ // Append "resourcetype", if not already present. It's value is
+ // needed to get a valid ContentProperties::pIsFolder value, which
+ // is needed for OpenMode handling.
+
+ std::vector< rtl::OUString >::const_iterator it
+ = propertyNames.begin();
+ std::vector< rtl::OUString >::const_iterator end
+ = propertyNames.end();
+
+ while ( it != end )
+ {
+ if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
+ break;
+
+ it++;
+ }
+
+ if ( it == end )
+ propertyNames.push_back( DAVProperties::RESOURCETYPE );
+
+ std::vector< DAVResource > resources;
+ try
+ {
+ // propfind depth 1, get property values for parent AND for each
+ // child
+ m_pImpl->m_xContent->getResourceAccess()
+ .PROPFIND( DAVONE,
+ propertyNames,
+ resources,
+ getResultSet()->getEnvironment() );
+ }
+ catch ( DAVException & )
+ {
+// OSL_ENSURE( sal_False, "PROPFIND : DAVException" );
+ m_pImpl->m_bThrowException = sal_True;
+ }
+
+ if ( !m_pImpl->m_bThrowException )
+ {
+ try
+ {
+ NeonUri aURI(
+ m_pImpl->m_xContent->getResourceAccess().getURL() );
+ rtl::OUString aPath = aURI.GetPath();
+
+ if ( aPath.getStr()[ aPath.getLength() - 1 ]
+ == sal_Unicode( '/' ) )
+ aPath = aPath.copy( 0, aPath.getLength() - 1 );
+
+ aPath = NeonUri::unescape( aPath );
+ bool bFoundParent = false;
+
+ for ( sal_uInt32 n = 0; n < resources.size(); ++n )
+ {
+ const DAVResource & rRes = resources[ n ];
+
+ // Filter parent, which is contained somewhere(!) in
+ // the vector.
+ if ( !bFoundParent )
+ {
+ try
+ {
+ NeonUri aCurrURI( rRes.uri );
+ rtl::OUString aCurrPath = aCurrURI.GetPath();
+ if ( aCurrPath.getStr()[
+ aCurrPath.getLength() - 1 ]
+ == sal_Unicode( '/' ) )
+ aCurrPath
+ = aCurrPath.copy(
+ 0,
+ aCurrPath.getLength() - 1 );
+
+ aCurrPath = NeonUri::unescape( aCurrPath );
+ if ( aPath == aCurrPath )
+ {
+ bFoundParent = true;
+ continue;
+ }
+ }
+ catch ( DAVException const & )
+ {
+ // do nothing, ignore error. continue.
+ }
+ }
+
+ ContentProperties* pContentProperties
+ = new ContentProperties( rRes );
+
+ // Check resource against open mode.
+ switch ( m_pImpl->m_nOpenMode )
+ {
+ case ucb::OpenMode::FOLDERS:
+ {
+ sal_Bool bFolder = sal_False;
+
+ const uno::Any & rValue
+ = pContentProperties->getValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "IsFolder" ) ) );
+ rValue >>= bFolder;
+
+ if ( !bFolder )
+ continue;
+
+ break;
+ }
+
+ case ucb::OpenMode::DOCUMENTS:
+ {
+ sal_Bool bDocument = sal_False;
+
+ const uno::Any & rValue
+ = pContentProperties->getValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "IsDocument" ) ) );
+ rValue >>= bDocument;
+
+ if ( !bDocument )
+ continue;
+
+ break;
+ }
+
+ case ucb::OpenMode::ALL:
+ default:
+ break;
+ }
+
+ m_pImpl->m_aResults.push_back(
+ new ResultListEntry( pContentProperties ) );
+ }
+ }
+ catch ( DAVException const & )
+ {
+ }
+ }
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ // Callback possible, because listeners may be informed!
+ aGuard.clear();
+ getResultSet()->rowCountFinal();
+ }
+ return !m_pImpl->m_bThrowException;
+}
+
diff --git a/ucb/source/ucp/webdav/webdavdatasupplier.hxx b/ucb/source/ucp/webdav/webdavdatasupplier.hxx
new file mode 100644
index 000000000000..b28263df0201
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavdatasupplier.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_DATASUPPLIER_HXX
+#define _WEBDAV_UCP_DATASUPPLIER_HXX
+
+#include <vector>
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultset.hxx>
+
+namespace webdav_ucp {
+
+struct DataSupplier_Impl;
+class Content;
+struct DAVResource;
+class ContentProperties;
+
+class DataSupplier : public ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+private:
+ sal_Bool getData();
+
+public:
+ DataSupplier( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode);
+
+ virtual ~DataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/webdavprovider.cxx b/ucb/source/ucp/webdav/webdavprovider.cxx
new file mode 100644
index 000000000000..cc9c69a15e25
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavprovider.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+#include <ucbhelper/contentidentifier.hxx>
+#include "webdavprovider.hxx"
+#include "webdavcontent.hxx"
+
+#include "osl/mutex.hxx"
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rSMgr ),
+ m_xDAVSessionFactory( new DAVSessionFactory() ),
+ m_pProps( 0 )
+{
+}
+
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+ delete m_pProps;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_3( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( ContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.WebDAVContentProvider" ),
+ rtl::OUString::createFromAscii(
+ WEBDAV_CONTENT_PROVIDER_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+ContentProvider::queryContent(
+ const uno::Reference<
+ ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException,
+ uno::RuntimeException )
+{
+ // Check URL scheme...
+
+ const rtl::OUString aScheme
+ = Identifier->getContentProviderScheme().toAsciiLowerCase();
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) )
+ throw ucb::IllegalIdentifierException();
+
+ // Normalize URL and create new Id, if nessacary.
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+
+ // At least: <scheme> + "://"
+ if ( aURL.getLength() < ( aScheme.getLength() + 3 ) )
+ throw ucb::IllegalIdentifierException();
+
+ if ( ( aURL.getStr()[ aScheme.getLength() ] != sal_Unicode( ':' ) ) ||
+ ( aURL.getStr()[ aScheme.getLength() + 1 ] != sal_Unicode( '/' ) ) ||
+ ( aURL.getStr()[ aScheme.getLength() + 2 ] != sal_Unicode( '/' ) ) )
+ throw ucb::IllegalIdentifierException();
+
+ uno::Reference< ucb::XContentIdentifier > xCanonicId;
+
+ bool bNewId = false;
+ if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
+ {
+ aURL = aURL.replaceAt( 0,
+ WEBDAV_URL_SCHEME_LENGTH,
+ rtl::OUString::createFromAscii(
+ HTTP_URL_SCHEME ) );
+ bNewId = true;
+ }
+ else if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
+ {
+ aURL = aURL.replaceAt( 0,
+ DAV_URL_SCHEME_LENGTH,
+ rtl::OUString::createFromAscii(
+ HTTP_URL_SCHEME ) );
+ bNewId = true;
+ }
+ else if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
+ {
+ aURL = aURL.replaceAt( 0,
+ DAVS_URL_SCHEME_LENGTH,
+ rtl::OUString::createFromAscii(
+ HTTPS_URL_SCHEME ) );
+ bNewId = true;
+ }
+
+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
+ if ( nPos != aURL.getLength() - 1 )
+ {
+ // Find second slash in URL.
+ nPos = aURL.indexOf( '/', aURL.indexOf( '/' ) + 1 );
+ if ( nPos == -1 )
+ throw ucb::IllegalIdentifierException();
+
+ nPos = aURL.indexOf( '/', nPos + 1 );
+ if ( nPos == -1 )
+ {
+ aURL += rtl::OUString::createFromAscii( "/" );
+ bNewId = true;
+ }
+ }
+
+ if ( bNewId )
+ xCanonicId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
+ else
+ xCanonicId = Identifier;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xCanonicId ).get();
+ if ( xContent.is() )
+ return xContent;
+
+ // Create a new content.
+
+ try
+ {
+ xContent = new ::webdav_ucp::Content(
+ m_xSMgr, this, xCanonicId, m_xDAVSessionFactory );
+ registerNewContent( xContent );
+ }
+ catch ( ucb::ContentCreationException const & )
+ {
+ throw ucb::IllegalIdentifierException();
+ }
+
+ if ( !xContent->getIdentifier().is() )
+ throw ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
diff --git a/ucb/source/ucp/webdav/webdavprovider.hxx b/ucb/source/ucp/webdav/webdavprovider.hxx
new file mode 100644
index 000000000000..286f2e474c16
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavprovider.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_PROVIDER_HXX
+#define _WEBDAV_UCP_PROVIDER_HXX
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/beans/Property.hpp>
+#include "DAVSessionFactory.hxx"
+#include <ucbhelper/providerhelper.hxx>
+#include "PropertyMap.hxx"
+
+namespace webdav_ucp {
+
+//=========================================================================
+
+// UNO service name for the provider. This name will be used by the UCB to
+// create instances of the provider.
+#define WEBDAV_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.WebDAVContentProvider"
+#define WEBDAV_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 38
+
+// URL scheme. This is the scheme the provider will be able to create
+// contents for. The UCB will select the provider ( i.e. in order to create
+// contents ) according to this scheme.
+#define WEBDAV_URL_SCHEME \
+ "vnd.sun.star.webdav"
+#define WEBDAV_URL_SCHEME_LENGTH 19
+
+#define HTTP_URL_SCHEME "http"
+#define HTTP_URL_SCHEME_LENGTH 4
+
+#define HTTPS_URL_SCHEME "https"
+#define HTTPS_URL_SCHEME_LENGTH 5
+
+#define DAV_URL_SCHEME "dav"
+#define DAV_URL_SCHEME_LENGTH 3
+
+#define DAVS_URL_SCHEME "davs"
+#define DAVS_URL_SCHEME_LENGTH 4
+
+
+
+#define FTP_URL_SCHEME "ftp"
+
+#define HTTP_CONTENT_TYPE \
+ "application/" HTTP_URL_SCHEME "-content"
+
+#define WEBDAV_CONTENT_TYPE HTTP_CONTENT_TYPE
+#define WEBDAV_COLLECTION_TYPE \
+ "application/" WEBDAV_URL_SCHEME "-collection"
+
+//=========================================================================
+
+class ContentProvider : public ::ucbhelper::ContentProviderImplHelper
+{
+ rtl::Reference< DAVSessionFactory > m_xDAVSessionFactory;
+ PropertyMap * m_pProps;
+
+public:
+ ContentProvider( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( ::com::sun::star::ucb::IllegalIdentifierException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ rtl::Reference< DAVSessionFactory > getDAVSessionFactory()
+ { return m_xDAVSessionFactory; }
+
+ bool getProperty( const ::rtl::OUString & rPropName,
+ ::com::sun::star::beans::Property & rProp,
+ bool bStrict = false );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/webdavresultset.cxx b/ucb/source/ucp/webdav/webdavresultset.cxx
new file mode 100644
index 000000000000..cf4cc88fd12f
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavresultset.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+#include "webdavresultset.hxx"
+#ifndef _WEBDAV_SESSION_HXX
+#include "DAVSession.hxx"
+#endif
+
+using namespace com::sun::star;
+using namespace webdav_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand,
+ const uno::Reference< ucb::XCommandEnvironment >& rxEnv )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent ),
+ m_xEnv( rxEnv )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet( m_xSMgr,
+ m_aCommand.Properties,
+ new DataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ),
+ m_xEnv );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/webdav/webdavresultset.hxx b/ucb/source/ucp/webdav/webdavresultset.hxx
new file mode 100644
index 000000000000..a438cc208e09
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavresultset.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WEBDAV_UCP_RESULTSET_HXX
+#define _WEBDAV_UCP_RESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "webdavcontent.hxx"
+#include "webdavdatasupplier.hxx"
+
+namespace webdav_ucp {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+ com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+};
+
+}
+
+#endif
diff --git a/ucb/source/ucp/webdav/webdavservices.cxx b/ucb/source/ucp/webdav/webdavservices.cxx
new file mode 100644
index 000000000000..9fb6d9e82bcf
--- /dev/null
+++ b/ucb/source/ucp/webdav/webdavservices.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "webdavprovider.hxx"
+
+using namespace com::sun::star;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // WebDAV Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ ::webdav_ucp::ContentProvider::getImplementationName_Static(),
+ ::webdav_ucp::ContentProvider::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >(
+ pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // WebDAV Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( ::webdav_ucp::ContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = ::webdav_ucp::ContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+