update ooo310-m15
[ooovba.git] / applied_patches / 0111-webdav-locking-from-ooo-build-2-4-1.diff
blob4d34939a8616a1a42aba2ba8976e4eee6c71151f
1 --- officecfg/registry/data/org/openoffice/ucb/Configuration.xcu.old 2009-04-02 11:01:44.000000000 +0000
2 +++ officecfg/registry/data/org/openoffice/ucb/Configuration.xcu 2009-04-06 16:41:46.000000000 +0000
3 @@ -178,6 +178,28 @@
4 <value/>
5 </prop>
6 </node>
7 + <node oor:name="Provider14" oor:op="replace">
8 + <prop oor:name="ServiceName">
9 + <value>com.sun.star.ucb.WebDAVContentProvider</value>
10 + </prop>
11 + <prop oor:name="URLTemplate">
12 + <value>webdav</value>
13 + </prop>
14 + <prop oor:name="Arguments">
15 + <value/>
16 + </prop>
17 + </node>
18 + <node oor:name="Provider15" oor:op="replace">
19 + <prop oor:name="ServiceName">
20 + <value>com.sun.star.ucb.WebDAVContentProvider</value>
21 + </prop>
22 + <prop oor:name="URLTemplate">
23 + <value>webdavs</value>
24 + </prop>
25 + <prop oor:name="Arguments">
26 + <value/>
27 + </prop>
28 + </node>
29 <!-- We want the Provider to be the final fallback provider -->
30 <node oor:name="Provider999" oor:op="replace" install:module="gio">
31 <prop oor:name="ServiceName">
32 --- sal/inc/osl/file.h.old 2009-04-02 10:43:39.000000000 +0000
33 +++ sal/inc/osl/file.h 2009-04-06 16:41:46.000000000 +0000
34 @@ -139,6 +139,7 @@ typedef enum {
35 osl_File_E_USERS,
36 osl_File_E_OVERFLOW,
37 osl_File_E_NOTREADY,
38 + osl_File_E_TXTBSY,
39 osl_File_E_invalidError, /* unmapped error: always last entry in enum! */
40 osl_File_E_TIMEDOUT,
41 osl_File_E_NETWORK,
42 --- sal/inc/osl/file.hxx.old 2009-04-02 10:43:39.000000000 +0000
43 +++ sal/inc/osl/file.hxx 2009-04-06 16:41:46.000000000 +0000
44 @@ -106,6 +106,7 @@ public:
45 E_USERS = osl_File_E_USERS,
46 E_OVERFLOW = osl_File_E_OVERFLOW,
47 E_NOTREADY = osl_File_E_NOTREADY,
48 + E_TXTBSY = osl_File_E_TXTBSY,
49 E_invalidError = osl_File_E_invalidError, /* unmapped error: always last entry in enum! */
50 E_TIMEDOUT = osl_File_E_TIMEDOUT,
51 E_NETWORK = osl_File_E_NETWORK
52 --- sal/osl/unx/file_error_transl.cxx.old 2009-04-02 10:43:46.000000000 +0000
53 +++ sal/osl/unx/file_error_transl.cxx 2009-04-06 16:41:46.000000000 +0000
54 @@ -247,6 +247,10 @@ oslFileError oslTranslateFileError(sal_B
55 osl_error = osl_File_E_TIMEDOUT;
56 break;
58 + case ETXTBSY:
59 + osl_error = osl_File_E_TXTBSY;
60 + break;
62 default:
63 /* FIXME translateFileError: is this alright? Or add a new one: osl_File_E_Unknown? */
64 osl_error = osl_File_E_invalidError;
65 --- sc/source/ui/docshell/docsh.cxx.old 2009-04-02 10:45:27.000000000 +0000
66 +++ sc/source/ui/docshell/docsh.cxx 2009-04-06 16:41:46.000000000 +0000
67 @@ -823,7 +823,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( S
68 // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
69 // darum vorher per CreateFileStream dafuer sorgen, dass die komplette
70 // Datei uebertragen wird.
71 - rMedium.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar
72 + rMedium.GetPhysicalName( sal_False ); //! CreateFileStream direkt rufen, wenn verfuegbar
74 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
75 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
76 --- sfx2/inc/sfx2/docfile.hxx.old 2009-04-02 10:44:03.000000000 +0000
77 +++ sfx2/inc/sfx2/docfile.hxx 2009-04-06 16:41:46.000000000 +0000
78 @@ -186,7 +186,7 @@ public:
79 ::com::sun::star::util::DateTime GetInitFileDate();
81 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > GetContent() const;
82 - const String& GetPhysicalName() const;
83 + const String& GetPhysicalName( sal_Bool bForceCreateTempIfRemote = sal_True ) const;
84 void SetTemporary( sal_Bool bTemp );
85 sal_Bool IsTemporary() const;
86 sal_Bool IsRemote();
87 @@ -260,6 +260,8 @@ public:
88 void SetCharset( ::rtl::OUString );
89 ::rtl::OUString GetBaseURL( bool bForSaving=false );
91 + sal_Bool SupportsActiveStreaming( const rtl::OUString &rName ) const;
93 #if _SOLAR__PRIVATE
94 //REMOVE // the storage will be truncated, if it is still not open then the stream will be truncated
95 //REMOVE ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetOutputStorage_Impl();
96 --- sfx2/source/bastyp/helper.cxx.old 2009-04-02 10:43:55.000000000 +0000
97 +++ sfx2/source/bastyp/helper.cxx 2009-04-06 16:41:46.000000000 +0000
98 @@ -796,16 +796,15 @@ ErrCode SfxContentHelper::QueryDiskSpace
100 // -----------------------------------------------------------------------
102 -ULONG SfxContentHelper::GetSize( const String& rContent )
103 +sal_Int64 SfxContentHelper::GetSize( const String& rContent )
105 - ULONG nSize = 0;
106 - sal_Int64 nTemp = 0;
107 + sal_Int64 nSize = -1;
108 INetURLObject aObj( rContent );
109 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
112 ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment > () );
113 - aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= nTemp;
114 + aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= nSize;
116 catch( ucb::CommandAbortedException& )
118 @@ -815,7 +814,6 @@ ULONG SfxContentHelper::GetSize( const S
120 DBG_ERRORFILE( "Any other exception" );
122 - nSize = (UINT32)nTemp;
123 return nSize;
126 --- sfx2/source/dialog/dinfdlg.cxx.old 2009-04-02 10:43:54.000000000 +0000
127 +++ sfx2/source/dialog/dinfdlg.cxx 2009-04-06 16:41:46.000000000 +0000
128 @@ -1153,8 +1153,9 @@ void SfxDocumentPage::Reset( const SfxIt
130 // determine size and type
131 String aSizeText( aUnknownSize );
132 - if ( aURL.GetProtocol() == INET_PROT_FILE )
133 - aSizeText = CreateSizeText( SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
134 + sal_Int64 nSize = SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
135 + if ( nSize >= 0 )
136 + aSizeText = CreateSizeText( static_cast< ULONG >( nSize ) );
137 aShowSizeFT.SetText( aSizeText );
139 String aDescription = SvFileInformationManager::GetDescription( INetURLObject(rMainURL) );
140 --- sfx2/source/doc/docfile.cxx.old 2009-04-02 10:43:58.000000000 +0000
141 +++ sfx2/source/doc/docfile.cxx 2009-04-06 16:41:46.000000000 +0000
142 @@ -749,10 +749,13 @@ sal_Bool SfxMedium::CloseOutStream_Impl(
145 //------------------------------------------------------------------
146 -const String& SfxMedium::GetPhysicalName() const
147 +const String& SfxMedium::GetPhysicalName( sal_Bool bForceCreateTempIfRemote ) const
149 if ( !aName.Len() && aLogicName.Len() )
150 - (( SfxMedium*)this)->CreateFileStream();
152 + if ( bForceCreateTempIfRemote || !SupportsActiveStreaming( aLogicName ) )
153 + (( SfxMedium*)this)->CreateFileStream();
156 // return the name then
157 return aName;
158 @@ -796,8 +799,6 @@ sal_Bool SfxMedium::Commit()
159 GetInitFileDate();
162 - // remove truncation mode from the flags
163 - nStorOpenMode &= (~STREAM_TRUNC);
164 return bResult;
167 @@ -928,11 +929,31 @@ sal_Bool SfxMedium::TryStorage()
170 //------------------------------------------------------------------
171 +sal_Bool SfxMedium::SupportsActiveStreaming( const rtl::OUString &rName ) const
173 + if ( ::utl::LocalFileHelper::IsLocalFile( rName ) )
174 + return sal_True;
176 + ::ucbhelper::Content aTmpContent;
177 + Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
178 + if ( ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aTmpContent ) )
180 + Any aAny = aTmpContent.getPropertyValue(
181 + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" )) );
183 + sal_Bool bSupportsStreaming = sal_False;
184 + return ( ( aAny >>= bSupportsStreaming ) && bSupportsStreaming );
187 + return sal_False;
190 +//------------------------------------------------------------------
191 sal_Bool SfxMedium::BasedOnOriginalFile_Impl()
193 return ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode )
194 && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength()
195 - && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
196 + && SupportsActiveStreaming( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
197 && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
200 @@ -996,10 +1017,105 @@ uno::Reference < embed::XStorage > SfxMe
202 DBG_ASSERT( !pOutStream, "OutStream in a readonly Medium?!" );
204 - // TODO/LATER: The current solution is to store the document temporary and then copy it to the target location;
205 - // in future it should be stored directly and then copied to the temporary location, since in this case no
206 - // file attributes have to be preserved and system copying mechanics could be used instead of streaming.
207 + // medium based on OutputStream: must work with TempFile
208 + if( aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL
209 + || !::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
210 CreateTempFileNoCopy();
211 + // if Medium already contains a stream - TODO/LATER: store stream/outputstream in ImplData, not in Medium
212 + else if ( GetItemSet()->GetItemState( SID_STREAM ) < SFX_ITEM_SET )
214 + // check whether the backup should be created
215 + StorageBackup_Impl();
217 + if ( GetError() )
218 + return uno::Reference< embed::XStorage >();
220 + ::rtl::OUString aOutputURL = GetOutputStorageURL_Impl();
222 + SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
223 + SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
224 + sal_Bool bRename = pRename ? pRename->GetValue() : FALSE;
225 + sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename;
227 + // the target file must be truncated before a storage based on it is created
228 + try
230 + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
231 + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess(
232 + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ),
233 + uno::UNO_QUERY_THROW );
235 + uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
236 + ::ucbhelper::Content aContent = ::ucbhelper::Content( aOutputURL, xDummyEnv );
238 + uno::Reference< io::XStream > xStream;
239 + sal_Bool bDeleteOnFailure = sal_False;
241 + try
243 + xStream = aContent.openWriteableStreamNoLock();
245 + if ( !bOverWrite )
247 + // the stream should not exist, it should not be possible to open it
248 + if ( xStream->getOutputStream().is() )
249 + xStream->getOutputStream()->closeOutput();
250 + if ( xStream->getInputStream().is() )
251 + xStream->getInputStream()->closeInput();
253 + xStream = uno::Reference< io::XStream >();
254 + SetError( ERRCODE_IO_GENERAL );
257 + catch ( ucb::InteractiveIOException const & e )
259 + if ( e.Code == ucb::IOErrorCode_NOT_EXISTING )
261 + // Create file...
262 + SvMemoryStream aStream(0,0);
263 + uno::Reference< io::XInputStream > xInput( new ::utl::OInputStreamWrapper( aStream ) );
264 + ucb::InsertCommandArgument aInsertArg;
265 + aInsertArg.Data = xInput;
266 + aInsertArg.ReplaceExisting = sal_False;
267 + aContent.executeCommand( rtl::OUString::createFromAscii( "insert" ), uno::makeAny( aInsertArg ) );
269 + // Try to open one more time
270 + xStream = aContent.openWriteableStreamNoLock();
271 + bDeleteOnFailure = sal_True;
273 + else
274 + throw;
277 + if ( xStream.is() )
279 + if ( BasedOnOriginalFile_Impl() )
281 + // the storage will be based on original file, the wrapper should be used
282 + xStream = new OPostponedTruncationFileStream( aOutputURL, xFactory, xSimpleFileAccess, xStream, bDeleteOnFailure );
284 + else
286 + // the storage will be based on the temporary file, the stream can be truncated directly
287 + uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream();
288 + uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY );
289 + if ( !xTruncate.is() )
290 + throw uno::RuntimeException();
292 + xTruncate->truncate();
293 + xOutStream->flush();
296 + pImp->xStream = xStream;
297 + GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( xStream ) ) );
300 + catch( uno::Exception& )
302 + // TODO/LATER: try to use the temporary file in case the target content can not be opened, it might happen in case of some FS, the copy functionality might work in this case
303 + SetError( ERRCODE_IO_GENERAL );
307 return GetStorage();
309 @@ -1381,7 +1497,7 @@ uno::Reference < embed::XStorage > SfxMe
313 - if ( IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
314 + if ( IsReadOnly() && SupportsActiveStreaming( aLogicName ) )
316 //TODO/LATER: performance problem if not controlled by special Mode in SfxMedium
317 //(should be done only for permanently open storages)
318 @@ -2210,7 +2326,7 @@ void SfxMedium::Transfer_Impl()
319 xComEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
320 Reference< ::com::sun::star::ucb::XProgressHandler >() );
322 - if ( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) || !aDest.removeSegment() )
323 + if ( SupportsActiveStreaming( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) || !aDest.removeSegment() )
325 TransactedTransferForFS_Impl( aSource, aDest, xComEnv );
327 @@ -2542,7 +2658,7 @@ void SfxMedium::GetMedium_Impl()
328 aMedium.erase( comphelper::MediaDescriptor::PROP_READONLY() );
329 aMedium.addInputStream();
331 - else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
332 + else if ( SupportsActiveStreaming( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
334 // use the special locking approach only for file URLs
335 aMedium.addInputStreamOwnLock();
336 --- sfx2/source/inc/helper.hxx.old 2009-04-02 10:43:59.000000000 +0000
337 +++ sfx2/source/inc/helper.hxx 2009-04-06 16:41:46.000000000 +0000
338 @@ -69,7 +69,7 @@ public:
340 static sal_Bool MakeFolder( const String& rFolder );
341 static ErrCode QueryDiskSpace( const String& rPath, sal_Int64& rFreeBytes );
342 - static ULONG GetSize( const String& rContent );
343 + static sal_Int64 GetSize( const String& rContent );
344 static sal_Bool IsYounger( const String& rIsYoung, const String& rIsOlder );
346 // please don't use this!
347 --- sfx2/source/view/viewfrm.cxx.old 2009-04-02 10:44:00.000000000 +0000
348 +++ sfx2/source/view/viewfrm.cxx 2009-04-06 16:41:46.000000000 +0000
349 @@ -631,6 +631,11 @@ void SfxViewFrame::ExecReload_Impl( SfxR
350 sal_Bool bHandsOff =
351 ( pMedium->GetURLObject().GetProtocol() == INET_PROT_FILE && !xOldObj->IsDocShared() );
353 + // we must do the same for the contents that support active
354 + // streaming
355 + if ( !bHandsOff && pMedium && pMedium->SupportsActiveStreaming( aURL ) )
356 + bHandsOff = sal_True;
358 // bestehende SfxMDIFrames f"ur dieses Doc leeren
359 // eigenes Format oder R/O jetzt editierbar "offnen?
360 SfxViewNotificatedFrameList_Impl aFrames;
361 --- tools/inc/tools/urlobj.hxx.old 2009-04-06 16:41:45.000000000 +0000
362 +++ tools/inc/tools/urlobj.hxx 2009-04-06 16:41:46.000000000 +0000
363 @@ -141,9 +141,14 @@ enum INetProtocol
364 INET_PROT_TELNET = 28,
365 INET_PROT_VND_SUN_STAR_EXPAND = 29,
366 INET_PROT_VND_SUN_STAR_TDOC = 30,
367 - INET_PROT_GENERIC = 31,
368 - INET_PROT_SMB = 32,
369 - INET_PROT_END = 33
370 + INET_PROT_SMB = 31,
371 + INET_PROT_DAV = 32,
372 + INET_PROT_DAVS = 33,
373 + INET_PROT_WEBDAV = 34,
374 + INET_PROT_WEBDAVS = 35,
375 + INET_PROT_GENERIC = 36,
376 + INET_PROT_GENERIC_HIERARCHICAL = 37,
377 + INET_PROT_END = 38
380 //============================================================================
381 --- tools/source/fsys/urlobj.cxx.old 2009-04-06 16:41:45.000000000 +0000
382 +++ tools/source/fsys/urlobj.cxx 2009-04-06 16:41:46.000000000 +0000
383 @@ -374,21 +374,21 @@ static INetURLObject::SchemeInfo const a
384 false },
385 { "ftp", "ftp://", 21, true, true, false, true, true, true, true,
386 false },
387 - { "http", "http://", 80, true, false, false, false, true, true,
388 + { "http", "http://", 80, true, true, false, true, true, true,
389 true, true },
390 { "file", "file://", 0, true, false, false, false, true, false,
391 true, false },
392 { "mailto", "mailto:", 0, false, false, false, false, false,
393 false, false, true },
394 - { "vnd.sun.star.webdav", "vnd.sun.star.webdav://", 80, true, false,
395 - false, false, true, true, true, true },
396 + { "vnd.sun.star.webdav", "vnd.sun.star.webdav://", 80, true, true,
397 + false, true, true, true, true, true },
398 { "news", "news:", 0, false, false, false, false, false, false, false,
399 false },
400 { "private", "private:", 0, false, false, false, false, false,
401 false, false, true },
402 { "vnd.sun.star.help", "vnd.sun.star.help://", 0, true, false, false,
403 false, false, false, true, true },
404 - { "https", "https://", 443, true, false, false, false, true, true,
405 + { "https", "https://", 443, true, true, false, true, true, true,
406 true, true },
407 { "slot", "slot:", 0, false, false, false, false, false, false,
408 false, true },
409 @@ -432,9 +432,19 @@ static INetURLObject::SchemeInfo const a
410 false, false, false, false, false },
411 { "vnd.sun.star.tdoc", "vnd.sun.star.tdoc:", 0, false, false, false,
412 false, false, false, true, false },
413 - { "", "", 0, false, false, false, false, false, false, false, false },
414 { "smb", "smb://", 139, true, true, false, true, true, true, true,
415 - true } };
416 + true },
417 + { "dav", "dav://", 80, true, true, false, true, true, true, true,
418 + true },
419 + { "davs", "davs://", 443, true, true, false, true, true, true,
420 + true, true },
421 + { "webdav", "webdav://", 80, true, true, false, true, true, true, true,
422 + true },
423 + { "webdavs", "webdavs://", 443, true, true, false, true, true, true,
424 + true, true },
425 + { "", "", 0, false, false, false, false, false, false, false, false },
426 + { "", "", 0, false, false, false, false, false, false, true, false }
427 + };
429 // static
430 inline INetURLObject::SchemeInfo const &
431 @@ -849,7 +859,10 @@ bool INetURLObject::setAbsURIRef(rtl::OU
432 aSynScheme = parseScheme(&p1, pEnd, nFragmentDelimiter);
433 if (aSynScheme.getLength() > 0)
435 - m_eScheme = INET_PROT_GENERIC;
436 + if (p1 != pEnd && *p1 == '/')
437 + m_eScheme = INET_PROT_GENERIC_HIERARCHICAL;
438 + else
439 + m_eScheme = INET_PROT_GENERIC;
440 pPos = p1;
443 @@ -866,8 +879,9 @@ bool INetURLObject::setAbsURIRef(rtl::OU
444 return false;
447 - if (m_eScheme != INET_PROT_GENERIC) {
448 - aSynScheme = rtl::OUString::createFromAscii(getSchemeInfo().m_pScheme);
449 + const char *pSchemeName = getSchemeInfo().m_pScheme;
450 + if (pSchemeName[0] != '\0') {
451 + aSynScheme = rtl::OUString::createFromAscii(pSchemeName);
453 m_aScheme.set(aSynAbsURIRef, aSynScheme, aSynAbsURIRef.getLength());
454 aSynAbsURIRef.append(sal_Unicode(':'));
455 @@ -2120,6 +2134,8 @@ INetURLObject::getPrefix(sal_Unicode con
456 PrefixInfo::INTERNAL },
457 { "cid:", 0, INET_PROT_CID, PrefixInfo::OFFICIAL },
458 { "data:", 0, INET_PROT_DATA, PrefixInfo::OFFICIAL },
459 + { "dav:", 0, INET_PROT_DAV, PrefixInfo::OFFICIAL },
460 + { "davs:", 0, INET_PROT_DAVS, PrefixInfo::OFFICIAL },
461 { "db:", "staroffice.db:", INET_PROT_DB, PrefixInfo::INTERNAL },
462 { "file:", 0, INET_PROT_FILE, PrefixInfo::OFFICIAL },
463 { "ftp:", 0, INET_PROT_FTP, PrefixInfo::OFFICIAL },
464 @@ -2201,6 +2217,8 @@ INetURLObject::getPrefix(sal_Unicode con
465 PrefixInfo::OFFICIAL },
466 { "vnd.sun.star.wfs:", 0, INET_PROT_VND_SUN_STAR_WFS,
467 PrefixInfo::OFFICIAL },
468 + { "webdav:", 0, INET_PROT_WEBDAV, PrefixInfo::OFFICIAL },
469 + { "webdavs:", 0, INET_PROT_WEBDAVS, PrefixInfo::OFFICIAL },
470 { "wfs:", "vnd.sun.star.wfs:", INET_PROT_VND_SUN_STAR_WFS,
471 PrefixInfo::ALIAS } };
472 PrefixInfo const * pFirst = aMap + 1;
473 @@ -3004,6 +3022,10 @@ bool INetURLObject::parsePath(INetProtoc
474 case INET_PROT_VND_SUN_STAR_WEBDAV:
475 case INET_PROT_HTTPS:
476 case INET_PROT_SMB:
477 + case INET_PROT_DAV:
478 + case INET_PROT_DAVS:
479 + case INET_PROT_WEBDAV:
480 + case INET_PROT_WEBDAVS:
481 if (pPos < pEnd && *pPos != '/')
482 return false;
483 while (pPos < pEnd && *pPos != nQueryDelimiter
484 @@ -3422,6 +3444,7 @@ bool INetURLObject::parsePath(INetProtoc
485 break;
487 case INET_PROT_GENERIC:
488 + case INET_PROT_GENERIC_HIERARCHICAL:
489 while (pPos < pEnd && *pPos != nFragmentDelimiter)
491 EscapeType eEscapeType;
492 @@ -4133,10 +4156,13 @@ bool INetURLObject::ConcatData(INetProto
494 setInvalid();
495 m_eScheme = eTheScheme;
496 - if (HasError() || m_eScheme == INET_PROT_GENERIC)
497 + const char *pSchemeName = getSchemeInfo().m_pScheme;
499 + if (HasError() || pSchemeName[0] == '\0')
500 return false;
502 m_aAbsURIRef.setLength(0);
503 - m_aAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
504 + m_aAbsURIRef.appendAscii(pSchemeName);
505 m_aAbsURIRef.append(sal_Unicode(':'));
506 if (getSchemeInfo().m_bAuthority)
508 --- tools/workben/urltest.cxx.old 2009-04-02 10:36:25.000000000 +0000
509 +++ tools/workben/urltest.cxx 2009-04-06 16:41:46.000000000 +0000
510 @@ -1476,7 +1476,7 @@ main()
512 url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A-b.3:/%2f?x#y"));
513 urlobj = INetURLObject(url);
514 - bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
515 + bSuccess &= assertEqual(url, INET_PROT_GENERIC_HIERARCHICAL, urlobj.GetProtocol());
516 bSuccess &= assertEqual(
517 url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a-b.3:/%2F?x#y")),
518 rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
519 @@ -1504,7 +1504,7 @@ main()
521 url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:/"));
522 urlobj = INetURLObject(url);
523 - bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
524 + bSuccess &= assertEqual(url, INET_PROT_GENERIC_HIERARCHICAL, urlobj.GetProtocol());
525 bSuccess &= assertEqual(
526 url, url,
527 rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
528 @@ -1542,7 +1542,7 @@ main()
530 url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A-b.3:/%2f?x#y"));
531 urlobj = INetURLObject(url, INET_PROT_CID);
532 - bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
533 + bSuccess &= assertEqual(url, INET_PROT_GENERIC_HIERARCHICAL, urlobj.GetProtocol());
534 bSuccess &= assertEqual(
535 url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a-b.3:/%2F?x#y")),
536 rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
537 @@ -1563,7 +1563,7 @@ main()
539 url = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:/"));
540 urlobj = INetURLObject(url, INET_PROT_CID);
541 - bSuccess &= assertEqual(url, INET_PROT_GENERIC, urlobj.GetProtocol());
542 + bSuccess &= assertEqual(url, INET_PROT_GENERIC_HIERARCHICAL, urlobj.GetProtocol());
543 bSuccess &= assertEqual(
544 url, url,
545 rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
546 --- ucb/source/ucp/file/filglob.cxx.old 2009-04-02 11:01:37.000000000 +0000
547 +++ ucb/source/ucp/file/filglob.cxx 2009-04-06 16:41:46.000000000 +0000
548 @@ -361,17 +361,13 @@ namespace fileaccess {
549 // not enough memory for allocating structures
550 ioErrorCode = IOErrorCode_OUT_OF_MEMORY;
551 break;
552 - case FileBase::E_BUSY:
553 - // Text file busy
554 - ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
555 - break;
556 - case FileBase::E_AGAIN:
557 - // Operation would block
559 + case FileBase::E_BUSY: // Text file busy
560 + case FileBase::E_AGAIN: // Operation would block
561 + case FileBase::E_NOLCK: // No record locks available
562 + case FileBase::E_TXTBSY:// Text file busy
563 ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
564 break;
565 - case FileBase::E_NOLCK: // No record locks available
566 - ioErrorCode = IOErrorCode_LOCKING_VIOLATION;
567 - break;
569 case FileBase::E_FAULT: // Bad address
570 case FileBase::E_LOOP: // Too many symbolic links encountered
571 --- ucb/source/ucp/webdav/DAVRequestEnvironment.hxx.old 2009-04-02 11:01:38.000000000 +0000
572 +++ ucb/source/ucp/webdav/DAVRequestEnvironment.hxx 2009-04-06 16:41:46.000000000 +0000
573 @@ -34,6 +34,10 @@
574 #include <rtl/ref.hxx>
575 #include "DAVAuthListener.hxx"
577 +#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
578 +#include <com/sun/star/ucb/XCommandEnvironment.hpp>
579 +#endif
581 namespace webdav_ucp
583 typedef std::pair< rtl::OUString, rtl::OUString > DAVRequestHeader;
584 @@ -46,12 +50,12 @@ struct DAVRequestEnvironment
585 // rtl::Reference< DAVStatusListener > m_xStatusListener;
586 // rtl::Reference< DAVProgressListener > m_xStatusListener;
587 DAVRequestHeaders m_aRequestHeaders;
588 - uno::Reference< ucb::XCommandEnvironment > m_xEnv;
589 + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv;
591 -DAVRequestEnvironment( const rtl::OUString & rRequestURI,
592 + DAVRequestEnvironment( const rtl::OUString & rRequestURI,
593 const rtl::Reference< DAVAuthListener > & xListener,
594 const DAVRequestHeaders & rRequestHeaders,
595 - const uno::Reference< ucb::XCommandEnvironment > & xEnv)
596 + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv)
597 : m_aRequestURI( rRequestURI ),
598 m_xAuthListener( xListener ),
599 m_aRequestHeaders( rRequestHeaders ),
600 --- ucb/source/ucp/webdav/DAVResourceAccess.cxx.old 2009-04-02 11:01:38.000000000 +0000
601 +++ ucb/source/ucp/webdav/DAVResourceAccess.cxx 2009-04-06 16:41:46.000000000 +0000
602 @@ -42,6 +42,9 @@
603 #include "DAVAuthListenerImpl.hxx"
604 #include "DAVResourceAccess.hxx"
606 +#include <comphelper/processfactory.hxx>
607 +#include <ucbhelper/commandenvironment.hxx>
609 using namespace webdav_ucp;
610 using namespace com::sun::star;
612 @@ -61,56 +64,55 @@ int DAVAuthListener_Impl::authenticate(
613 ::rtl::OUString & inoutUserName,
614 ::rtl::OUString & outPassWord )
616 - if ( m_xEnv.is() )
618 - uno::Reference< task::XInteractionHandler > xIH
619 - = m_xEnv->getInteractionHandler();
620 - if ( xIH.is() )
622 - // #102871# - Supply username and password from previous try.
623 - // Password container service depends on this!
624 - if ( inoutUserName.getLength() == 0 )
625 - inoutUserName = m_aPrevUsername;
627 - if ( outPassWord.getLength() == 0 )
628 - outPassWord = m_aPrevPassword;
630 - rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
631 - = new ucbhelper::SimpleAuthenticationRequest( inHostName,
632 - inRealm,
633 - inoutUserName,
634 - outPassWord );
635 - xIH->handle( xRequest.get() );
636 + uno::Reference< task::XInteractionHandler > xIH;
638 - rtl::Reference< ucbhelper::InteractionContinuation > xSelection
639 - = xRequest->getSelection();
641 - if ( xSelection.is() )
643 - // Handler handled the request.
644 - uno::Reference< task::XInteractionAbort > xAbort(
645 - xSelection.get(), uno::UNO_QUERY );
646 - if ( !xAbort.is() )
648 - const rtl::Reference<
649 - ucbhelper::InteractionSupplyAuthentication > & xSupp
650 - = xRequest->getAuthenticationSupplier();
652 - inoutUserName = xSupp->getUserName();
653 - outPassWord = xSupp->getPassword();
655 - // #102871# - Remember username and password.
656 - m_aPrevUsername = inoutUserName;
657 - m_aPrevPassword = outPassWord;
658 + if ( m_xEnv.is() )
659 + xIH = m_xEnv->getInteractionHandler();
660 + else
661 + xIH = DAVResourceAccess::createCommandEnvironment()->getInteractionHandler();
663 + if ( !xIH.is() )
664 + return -1;
666 + // #102871# - Supply username and password from previous try.
667 + // Password container service depends on this!
668 + if ( inoutUserName.getLength() == 0 )
669 + inoutUserName = m_aPrevUsername;
671 + if ( outPassWord.getLength() == 0 )
672 + outPassWord = m_aPrevPassword;
674 + rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
675 + = new ucbhelper::SimpleAuthenticationRequest( inHostName,
676 + inRealm,
677 + inoutUserName,
678 + outPassWord );
679 + xIH->handle( xRequest.get() );
681 + rtl::Reference< ucbhelper::InteractionContinuation > xSelection
682 + = xRequest->getSelection();
684 + if ( !xSelection.is() )
685 + return -1;
687 + // Handler handled the request.
688 + uno::Reference< task::XInteractionAbort > xAbort(
689 + xSelection.get(), uno::UNO_QUERY );
690 + if ( xAbort.is() )
691 + return -1;
693 + const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
694 + = xRequest->getAuthenticationSupplier();
696 + inoutUserName = xSupp->getUserName();
697 + outPassWord = xSupp->getPassword();
699 + // #102871# - Remember username and password.
700 + m_aPrevUsername = inoutUserName;
701 + m_aPrevPassword = outPassWord;
703 - // go on.
704 - return 0;
709 - // Abort.
710 - return -1;
711 + // go on.
712 + return 0;
715 //=========================================================================
716 @@ -444,15 +446,16 @@ void DAVResourceAccess::GET(
719 //=========================================================================
720 -uno::Reference< io::XInputStream > DAVResourceAccess::GET(
721 +uno::Reference< io::XStream > DAVResourceAccess::GET(
722 const std::vector< rtl::OUString > & rHeaderNames,
723 DAVResource & rResource,
724 - const uno::Reference< ucb::XCommandEnvironment > & xEnv )
725 + const uno::Reference< ucb::XCommandEnvironment > & xEnv,
726 + sal_Bool bAllowEmpty )
727 throw( DAVException )
729 initialize();
731 - uno::Reference< io::XInputStream > xStream;
732 + uno::Reference< io::XStream > xStream;
733 int errorCount = 0;
734 bool bRetry;
736 @@ -472,7 +475,8 @@ uno::Reference< io::XInputStream > DAVRe
737 DAVRequestEnvironment(
738 getRequestURI(),
739 new DAVAuthListener_Impl( xEnv ),
740 - aHeaders, xEnv ) );
741 + aHeaders, xEnv ),
742 + bAllowEmpty );
744 catch ( DAVException & e )
746 @@ -606,6 +610,45 @@ void DAVResourceAccess::PUT(
749 //=========================================================================
750 +void DAVResourceAccess::PUT(
751 + const char * buffer, size_t size,
752 + const uno::Reference< ucb::XCommandEnvironment > & xEnv )
753 +throw( DAVException )
755 + initialize();
757 + bool bRetry = false;
758 + int errorCount = 0;
759 + do
761 + bRetry = false;
762 + try
764 + DAVRequestHeaders aHeaders;
765 + getUserRequestHeaders( xEnv,
766 + getRequestURI(),
767 + rtl::OUString::createFromAscii( "PUT" ),
768 + aHeaders );
770 + m_xSession->PUT( getRequestURI(),
771 + buffer, size,
772 + DAVRequestEnvironment(
773 + getRequestURI(),
774 + new DAVAuthListener_Impl( xEnv ),
775 + aHeaders, xEnv ) );
777 + catch ( DAVException & e )
779 + errorCount++;
780 + bRetry = handleException( e, errorCount );
781 + if ( !bRetry )
782 + throw;
785 + while ( bRetry );
788 +//=========================================================================
789 uno::Reference< io::XInputStream > DAVResourceAccess::POST(
790 const rtl::OUString & rContentType,
791 const rtl::OUString & rReferer,
792 @@ -888,22 +931,44 @@ void DAVResourceAccess::DESTROY(
794 //=========================================================================
795 void DAVResourceAccess::LOCK (
796 - const ucb::Lock & /*rLock*/,
797 - const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
798 + ucb::Lock & rLock,
799 + const uno::Reference< ucb::XCommandEnvironment > & xEnv )
800 throw( DAVException )
802 -// initialize();
803 - OSL_ENSURE( sal_False, "DAVResourceAccess::LOCK - NYI" );
804 + initialize();
806 + DAVRequestHeaders aHeaders;
807 + getUserRequestHeaders( xEnv,
808 + getRequestURI(),
809 + rtl::OUString::createFromAscii( "LOCK" ),
810 + aHeaders );
812 + m_xSession->LOCK( rLock,
813 + DAVRequestEnvironment(
814 + getRequestURI(),
815 + new DAVAuthListener_Impl( xEnv ),
816 + aHeaders, xEnv ) );
819 //=========================================================================
820 void DAVResourceAccess::UNLOCK (
821 - const ucb::Lock & /*rLock*/,
822 - const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
823 + ucb::Lock & rLock,
824 + const uno::Reference< ucb::XCommandEnvironment > & xEnv )
825 throw( DAVException )
827 -// initialize();
828 - OSL_ENSURE( sal_False, "DAVResourceAccess::UNLOCK - NYI" );
829 + initialize();
831 + DAVRequestHeaders aHeaders;
832 + getUserRequestHeaders( xEnv,
833 + getRequestURI(),
834 + rtl::OUString::createFromAscii( "UNLOCK" ),
835 + aHeaders );
837 + m_xSession->UNLOCK( rLock,
838 + DAVRequestEnvironment(
839 + getRequestURI(),
840 + new DAVAuthListener_Impl( xEnv ),
841 + aHeaders, xEnv ) );
844 //=========================================================================
845 @@ -1008,6 +1073,18 @@ void DAVResourceAccess::getUserRequestHe
849 +// static
850 +com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > DAVResourceAccess::createCommandEnvironment( void )
852 + uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
853 + uno::Reference< task::XInteractionHandler > xInteractionHandler = uno::Reference< task::XInteractionHandler > (
854 + xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), uno::UNO_QUERY );
855 + ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, uno::Reference< ucb::XProgressHandler >() );
857 + return uno::Reference< ucb::XCommandEnvironment >( static_cast< ucb::XCommandEnvironment* >( pCommandEnv ), uno::UNO_QUERY );
861 //=========================================================================
862 sal_Bool DAVResourceAccess::detectRedirectCycle(
863 const rtl::OUString& rRedirectURL )
864 --- ucb/source/ucp/webdav/DAVResourceAccess.hxx.old 2009-04-02 11:01:38.000000000 +0000
865 +++ ucb/source/ucp/webdav/DAVResourceAccess.hxx 2009-04-06 16:41:46.000000000 +0000
866 @@ -134,11 +134,12 @@ public:
867 com::sun::star::ucb::XCommandEnvironment > & xEnv )
868 throw( DAVException );
870 - com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
871 + com::sun::star::uno::Reference< com::sun::star::io::XStream >
872 GET( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
873 DAVResource & rResource,
874 const com::sun::star::uno::Reference<
875 - com::sun::star::ucb::XCommandEnvironment > & xEnv )
876 + com::sun::star::ucb::XCommandEnvironment > & xEnv,
877 + sal_Bool bAllowEmpty = sal_False )
878 throw( DAVException );
880 void
881 @@ -157,6 +158,11 @@ public:
882 com::sun::star::ucb::XCommandEnvironment > & xEnv )
883 throw( DAVException );
885 + void
886 + PUT( const char * buffer, size_t size,
887 + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
888 + throw( DAVException );
890 com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
891 POST( const rtl::OUString & rContentType,
892 const rtl::OUString & rReferer,
893 @@ -204,13 +210,13 @@ public:
894 throw( DAVException );
896 void
897 - LOCK( const com::sun::star::ucb::Lock & rLock,
898 + LOCK( com::sun::star::ucb::Lock & rLock,
899 const com::sun::star::uno::Reference<
900 com::sun::star::ucb::XCommandEnvironment > & xEnv )
901 throw( DAVException );
903 void
904 - UNLOCK( const com::sun::star::ucb::Lock & rLock,
905 + UNLOCK( com::sun::star::ucb::Lock & rLock,
906 const com::sun::star::uno::Reference<
907 com::sun::star::ucb::XCommandEnvironment > & xEnv )
908 throw( DAVException );
909 @@ -223,6 +229,8 @@ public:
910 const rtl::OUString & rMethod,
911 DAVRequestHeaders & rRequestHeaders );
913 + static com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > createCommandEnvironment( void );
915 private:
916 const rtl::OUString & getRequestURI() const;
917 sal_Bool detectRedirectCycle( const rtl::OUString& rRedirectURL )
918 --- ucb/source/ucp/webdav/DAVSession.hxx.old 2009-04-02 11:01:38.000000000 +0000
919 +++ ucb/source/ucp/webdav/DAVSession.hxx 2009-04-06 16:41:46.000000000 +0000
920 @@ -33,8 +33,11 @@
922 #include <memory>
923 #include <rtl/ustring.hxx>
924 +#include <com/sun/star/io/XStream.hpp>
925 #include <com/sun/star/io/XInputStream.hpp>
926 #include <com/sun/star/io/XOutputStream.hpp>
927 +#include <com/sun/star/ucb/Lock.hpp>
929 #include "DAVException.hxx"
930 #include "DAVProperties.hxx"
931 #include "DAVResource.hxx"
932 @@ -42,8 +45,6 @@
933 #include "DAVTypes.hxx"
934 #include "DAVRequestEnvironment.hxx"
938 namespace webdav_ucp
941 @@ -114,11 +115,12 @@ public:
942 const DAVRequestEnvironment & rEnv )
943 throw( DAVException ) = 0;
945 - virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
946 + virtual com::sun::star::uno::Reference< com::sun::star::io::XStream >
947 GET( const ::rtl::OUString & inPath,
948 const std::vector< ::rtl::OUString > & inHeaderNames,
949 DAVResource & ioResource,
950 - const DAVRequestEnvironment & rEnv )
951 + const DAVRequestEnvironment & rEnv,
952 + sal_Bool bAllowEmpty )
953 throw( DAVException ) = 0;
955 virtual void GET( const ::rtl::OUString & inPath,
956 @@ -134,6 +136,12 @@ public:
957 const DAVRequestEnvironment & rEnv )
958 throw( DAVException ) = 0;
960 + virtual void PUT( const ::rtl::OUString & inPath,
961 + const char * buffer,
962 + size_t size,
963 + const DAVRequestEnvironment & rEnv )
964 + throw ( DAVException ) = 0;
966 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
967 POST( const rtl::OUString & inPath,
968 const rtl::OUString & rContentType,
969 @@ -173,16 +181,14 @@ public:
970 const DAVRequestEnvironment & rEnv )
971 throw( DAVException ) = 0;
973 - // Note: Uncomment the following if locking support is required
974 - /*
975 - virtual void LOCK ( const Lock & inLock,
976 + virtual void LOCK ( com::sun::star::ucb::Lock & rLock,
977 const DAVRequestEnvironment & rEnv )
978 throw( DAVException ) = 0;
980 - virtual void UNLOCK ( const Lock & inLock,
981 + virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock,
982 const DAVRequestEnvironment & rEnv )
983 throw( DAVException ) = 0;
984 - */
986 protected:
987 rtl::Reference< DAVSessionFactory > m_xFactory;
989 --- ucb/source/ucp/webdav/NeonInputStream.cxx.old 2009-04-02 11:01:38.000000000 +0000
990 +++ ucb/source/ucp/webdav/NeonInputStream.cxx 2009-04-06 16:41:46.000000000 +0000
991 @@ -31,21 +31,28 @@
992 // MARKER(update_precomp.py): autogen include statement, do not remove
993 #include "precompiled_ucb.hxx"
994 #include "NeonInputStream.hxx"
995 +#include "DAVResourceAccess.hxx"
997 #include <rtl/memory.h>
998 +#include <com/sun/star/ucb/CommandFailedException.hpp>
1000 +#include <comphelper/processfactory.hxx>
1001 +#include <com/sun/star/lang/XMultiServiceFactory.hpp>
1003 +#include <cstdio>
1005 using namespace cppu;
1006 -using namespace rtl;
1007 using namespace com::sun::star::io;
1008 -using namespace com::sun::star::uno;
1009 +using namespace com::sun::star;
1010 using namespace webdav_ucp;
1013 // -------------------------------------------------------------------
1014 // Constructor
1015 // -------------------------------------------------------------------
1016 -NeonInputStream::NeonInputStream( void )
1017 -: mLen( 0 ),
1018 - mPos( 0 )
1019 +NeonInputStream::NeonInputStream()
1020 +: m_nLen( 0 ),
1021 + m_nPos( 0 ),
1022 + m_bDirty( sal_False )
1026 @@ -62,24 +69,59 @@ NeonInputStream::~NeonInputStream( void
1027 // -------------------------------------------------------------------
1028 void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen )
1030 - mInputBuffer.realloc( sal::static_int_cast<sal_Int32>(mLen) + inLen );
1031 - rtl_copyMemory( mInputBuffer.getArray() + mLen, inBuf, inLen );
1032 - mLen += inLen;
1033 + OSL_ENSURE( !m_bDirty, "Cannot AddToStream() when it was already written to it." );
1035 + m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>(m_nLen) + inLen );
1036 + rtl_copyMemory( m_aInputBuffer.getArray() + m_nLen, inBuf, inLen );
1037 + m_nLen += inLen;
1040 +// -------------------------------------------------------------------
1041 +// Associate a URL with this stream
1042 +// -------------------------------------------------------------------
1043 +void NeonInputStream::SetURL( const rtl::OUString &rURL )
1045 + osl::MutexGuard aGuard( m_aLock );
1047 + m_aURL = rURL;
1050 // -------------------------------------------------------------------
1051 // queryInterface
1052 // -------------------------------------------------------------------
1053 -Any NeonInputStream::queryInterface( const Type &type )
1054 - throw( RuntimeException )
1055 +uno::Any NeonInputStream::queryInterface( const uno::Type &type )
1056 + throw( uno::RuntimeException )
1058 - Any aRet = ::cppu::queryInterface( type,
1059 - static_cast< XInputStream * >( this ),
1060 - static_cast< XSeekable * >( this ) );
1061 + uno::Any aRet = ::cppu::queryInterface( type,
1062 + static_cast< XStream * >( this ),
1063 + static_cast< XInputStream * >( this ),
1064 + static_cast< XOutputStream * >( this ),
1065 + static_cast< XSeekable * >( this ),
1066 + static_cast< XTruncate * >( this ) );
1067 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type );
1070 // -------------------------------------------------------------------
1071 +// getInputStream
1072 +// -------------------------------------------------------------------
1073 +com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL
1074 +NeonInputStream::getInputStream( void )
1075 + throw( com::sun::star::uno::RuntimeException )
1077 + return uno::Reference< XInputStream >( this );
1080 +// -------------------------------------------------------------------
1081 +// getOutputStream
1082 +// -------------------------------------------------------------------
1083 +com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL
1084 +NeonInputStream::getOutputStream( void )
1085 + throw( com::sun::star::uno::RuntimeException )
1087 + return uno::Reference< XOutputStream >( this );
1090 +// -------------------------------------------------------------------
1091 // readBytes
1092 // "Reads" the specified number of bytes from the stream
1093 // -------------------------------------------------------------------
1094 @@ -92,7 +134,7 @@ sal_Int32 SAL_CALL NeonInputStream::read
1096 // Work out how much we're actually going to write
1097 sal_Int32 theBytes2Read = nBytesToRead;
1098 - sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(mLen - mPos);
1099 + sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(m_nLen - m_nPos);
1100 if ( theBytes2Read > theBytesLeft )
1101 theBytes2Read = theBytesLeft;
1103 @@ -101,10 +143,10 @@ sal_Int32 SAL_CALL NeonInputStream::read
1105 // Write the data
1106 rtl_copyMemory(
1107 - aData.getArray(), mInputBuffer.getConstArray() + mPos, theBytes2Read );
1108 + aData.getArray(), m_aInputBuffer.getConstArray() + m_nPos, theBytes2Read );
1110 // Update our stream position for next time
1111 - mPos += theBytes2Read;
1112 + m_nPos += theBytes2Read;
1114 return theBytes2Read;
1116 @@ -133,9 +175,9 @@ void SAL_CALL NeonInputStream::skipBytes
1117 ::com::sun::star::io::IOException,
1118 ::com::sun::star::uno::RuntimeException )
1120 - mPos += nBytesToSkip;
1121 - if ( mPos >= mLen )
1122 - mPos = mLen;
1123 + m_nPos += nBytesToSkip;
1124 + if ( m_nPos >= m_nLen )
1125 + m_nPos = m_nLen;
1128 // -------------------------------------------------------------------
1129 @@ -147,7 +189,7 @@ sal_Int32 SAL_CALL NeonInputStream::avai
1130 ::com::sun::star::io::IOException,
1131 ::com::sun::star::uno::RuntimeException )
1133 - return sal::static_int_cast<sal_Int32>(mLen - mPos);
1134 + return sal::static_int_cast<sal_Int32>(m_nLen - m_nPos);
1137 // -------------------------------------------------------------------
1138 @@ -168,12 +210,12 @@ void SAL_CALL NeonInputStream::seek( sal
1139 ::com::sun::star::io::IOException,
1140 ::com::sun::star::uno::RuntimeException )
1142 - if ( location < 0 )
1143 - throw ::com::sun::star::lang::IllegalArgumentException();
1144 + if ( location < 0 )
1145 + throw ::com::sun::star::lang::IllegalArgumentException();
1147 - if ( location <= mLen )
1148 - mPos = location;
1149 - else
1150 + if ( location <= m_nLen )
1151 + m_nPos = location;
1152 + else
1153 throw ::com::sun::star::lang::IllegalArgumentException();
1156 @@ -184,7 +226,7 @@ sal_Int64 SAL_CALL NeonInputStream::getP
1157 throw( ::com::sun::star::io::IOException,
1158 ::com::sun::star::uno::RuntimeException )
1160 - return mPos;
1161 + return m_nPos;
1164 // -------------------------------------------------------------------
1165 @@ -194,5 +236,108 @@ sal_Int64 SAL_CALL NeonInputStream::getL
1166 throw( ::com::sun::star::io::IOException,
1167 ::com::sun::star::uno::RuntimeException )
1169 - return mLen;
1170 + return m_nLen;
1173 +// -------------------------------------------------------------------
1174 +// writeBytes
1175 +// -------------------------------------------------------------------
1176 +void SAL_CALL NeonInputStream::writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
1177 + throw( com::sun::star::io::NotConnectedException,
1178 + com::sun::star::io::BufferSizeExceededException,
1179 + com::sun::star::io::IOException,
1180 + com::sun::star::uno::RuntimeException)
1182 +#if OSL_DEBUG_LEVEL > 0
1183 + fprintf( stderr, "WebDAV: writeBytes()\n" );
1184 +#endif
1186 + sal_Int32 nDataLen = aData.getLength();
1187 + OSL_ASSERT( nDataLen >= 0 );
1189 + // Anything to do?
1190 + if ( nDataLen == 0 )
1191 + return;
1193 + // Update the length of the stream & size of the buffer
1194 + if ( m_nLen < m_nPos + nDataLen )
1196 + m_nLen = m_nPos + nDataLen;
1197 + if ( m_aInputBuffer.getLength() < m_nLen )
1198 + m_aInputBuffer.realloc( sal::static_int_cast<sal_Int32>( m_nLen ) );
1201 + rtl_copyMemory( m_aInputBuffer.getArray() + m_nPos, aData.getConstArray(), nDataLen );
1202 + m_nPos += nDataLen;
1204 + m_bDirty = sal_True;
1207 +// -------------------------------------------------------------------
1208 +// flush
1209 +// -------------------------------------------------------------------
1210 +void SAL_CALL NeonInputStream::flush( void )
1211 + throw( NotConnectedException, BufferSizeExceededException,
1212 + IOException, uno::RuntimeException )
1214 + if ( m_bDirty )
1216 +#if OSL_DEBUG_LEVEL > 0
1217 + fprintf( stderr, "WebDAV: flush(), saving the changed file.\n" );
1218 +#endif
1219 + // FIXME It's really hacky to create the new session
1220 + // But so far it seems I have no other chance...
1221 + uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
1222 + rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
1224 + DAVResourceAccess aResourceAccess( xFactory, rDAVFactory, m_aURL );
1226 + try {
1227 + aResourceAccess.PUT( reinterpret_cast<const char*>( m_aInputBuffer.getConstArray() ), m_nLen,
1228 + DAVResourceAccess::createCommandEnvironment() );
1230 + catch ( DAVException & e )
1232 + throw ucb::CommandFailedException(
1233 + e.getData(),
1234 + uno::Reference< uno::XInterface >(),
1235 + uno::makeAny( e.getData() ) );
1238 + m_bDirty = sal_False;
1242 +// -------------------------------------------------------------------
1243 +// closeOutput
1244 +// -------------------------------------------------------------------
1245 +void SAL_CALL NeonInputStream::closeOutput( void )
1246 + throw( com::sun::star::io::NotConnectedException,
1247 + com::sun::star::io::IOException,
1248 + com::sun::star::uno::RuntimeException )
1250 + if ( m_bDirty )
1252 +#if OSL_DEBUG_LEVEL > 0
1253 + fprintf( stderr, "WebDAV: TODO write on closeOutput(), the stream is dirty!\n" );
1254 +#endif
1258 +// -------------------------------------------------------------------
1259 +// truncate
1260 +// -------------------------------------------------------------------
1261 +void SAL_CALL NeonInputStream::truncate( void )
1262 + throw( com::sun::star::io::IOException,
1263 + com::sun::star::uno::RuntimeException )
1265 +#if OSL_DEBUG_LEVEL > 0
1266 + fprintf( stderr, "WebDAV: truncate()\n" );
1267 +#endif
1269 + if ( m_nLen > 0 )
1271 + m_nLen = m_nPos = 0;
1272 + m_bDirty = sal_True;
1275 --- ucb/source/ucp/webdav/NeonInputStream.hxx.old 2009-04-02 11:01:38.000000000 +0000
1276 +++ ucb/source/ucp/webdav/NeonInputStream.hxx 2009-04-06 16:41:46.000000000 +0000
1277 @@ -31,11 +31,19 @@
1278 #define _NEONINPUTSTREAM_HXX_
1280 #include <sal/types.h>
1281 +#include <osl/mutex.hxx>
1282 +#include <osl/signal.h>
1283 #include <rtl/ustring.hxx>
1284 #include <cppuhelper/weak.hxx>
1286 +#include <com/sun/star/io/XStream.hpp>
1287 #include <com/sun/star/io/XInputStream.hpp>
1288 +#include <com/sun/star/io/XOutputStream.hpp>
1289 #include <com/sun/star/io/XSeekable.hpp>
1290 +#include <com/sun/star/io/XTruncate.hpp>
1291 +#include <com/sun/star/ucb/Lock.hpp>
1293 +#include "DAVRequestEnvironment.hxx"
1295 namespace webdav_ucp
1297 @@ -45,21 +53,33 @@ namespace webdav_ucp
1298 // A simple XInputStream implementation provided specifically for use
1299 // by the DAVSession::GET method.
1300 // -------------------------------------------------------------------
1301 -class NeonInputStream : public ::com::sun::star::io::XInputStream,
1302 +class NeonInputStream : public ::com::sun::star::io::XStream,
1303 + public ::com::sun::star::io::XInputStream,
1304 + public ::com::sun::star::io::XOutputStream,
1305 public ::com::sun::star::io::XSeekable,
1306 + public ::com::sun::star::io::XTruncate,
1307 public ::cppu::OWeakObject
1309 - private:
1310 - com::sun::star::uno::Sequence< sal_Int8 > mInputBuffer;
1311 - sal_Int64 mLen;
1312 - sal_Int64 mPos;
1314 - public:
1315 - NeonInputStream( void );
1316 - virtual ~NeonInputStream();
1317 +private:
1318 + com::sun::star::uno::Sequence< sal_Int8 > m_aInputBuffer;
1319 + sal_Int64 m_nLen; // cannot be just m_aInputBuffer.getLength() - the buffer can be bigger
1320 + sal_Int64 m_nPos;
1322 + sal_Bool m_bDirty;
1324 + rtl::OUString m_aURL;
1326 + osl::Mutex m_aLock;
1328 - // Add some data to the end of the stream
1329 - void AddToStream( const char * inBuf, sal_Int32 inLen );
1330 +public:
1331 + NeonInputStream( void );
1332 + virtual ~NeonInputStream();
1334 + // Add some data to the end of the stream
1335 + void AddToStream( const char * inBuf, sal_Int32 inLen );
1337 + // Associate a URL with this stream
1338 + void SetURL( const rtl::OUString &rURL );
1340 // XInterface
1341 virtual com::sun::star::uno::Any SAL_CALL queryInterface(
1342 @@ -74,6 +94,12 @@ class NeonInputStream : public ::com::su
1343 throw()
1344 { OWeakObject::release(); }
1346 + // XStream
1347 + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL getInputStream( void )
1348 + throw( com::sun::star::uno::RuntimeException );
1350 + virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( void )
1351 + throw( com::sun::star::uno::RuntimeException );
1353 // XInputStream
1354 virtual sal_Int32 SAL_CALL readBytes(
1355 @@ -121,6 +147,30 @@ class NeonInputStream : public ::com::su
1356 virtual sal_Int64 SAL_CALL getLength()
1357 throw( ::com::sun::star::io::IOException,
1358 ::com::sun::star::uno::RuntimeException );
1360 + // XOutputStream
1361 + virtual void SAL_CALL writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
1362 + throw( com::sun::star::io::NotConnectedException,
1363 + com::sun::star::io::BufferSizeExceededException,
1364 + com::sun::star::io::IOException,
1365 + com::sun::star::uno::RuntimeException);
1367 + virtual void SAL_CALL flush( void )
1368 + throw( com::sun::star::io::NotConnectedException,
1369 + com::sun::star::io::BufferSizeExceededException,
1370 + com::sun::star::io::IOException,
1371 + com::sun::star::uno::RuntimeException);
1374 + virtual void SAL_CALL closeOutput( void )
1375 + throw( com::sun::star::io::NotConnectedException,
1376 + com::sun::star::io::IOException,
1377 + com::sun::star::uno::RuntimeException );
1379 + // XTruncate
1380 + virtual void SAL_CALL truncate( void )
1381 + throw( com::sun::star::io::IOException,
1382 + com::sun::star::uno::RuntimeException );
1385 } // namespace webdav_ucp
1386 --- ucb/source/ucp/webdav/NeonSession.cxx.old 2009-04-02 11:01:38.000000000 +0000
1387 +++ ucb/source/ucp/webdav/NeonSession.cxx 2009-04-06 16:41:46.000000000 +0000
1388 @@ -65,6 +65,7 @@
1389 #ifndef _SIMPLECERTIFICATIONVALIDATIONREQUEST_HXX_
1390 #include "ucbhelper/simplecertificatevalidationrequest.hxx"
1391 #endif
1392 +#include <ucbhelper/cancelcommandexecution.hxx>
1394 #include <cppuhelper/bootstrap.hxx>
1396 @@ -153,6 +154,12 @@ static sal_uInt16 makeStatusCode( const
1397 return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() );
1400 +static sal_uInt16 getStatusCode( HttpSession *pSession )
1402 + rtl::OUString aText = rtl::OUString::createFromAscii( ne_get_error( pSession ) );
1403 + return makeStatusCode( aText );
1406 // -------------------------------------------------------------------
1407 struct NeonRequestContext
1409 @@ -196,12 +203,13 @@ struct NeonRequestContext
1410 // -------------------------------------------------------------------
1412 #if NEON_VERSION >= 0x0250
1413 -extern "C" int NeonSession_ResponseBlockReader(void * inUserData,
1414 +extern "C" int
1415 #else
1416 -extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
1417 +extern "C" void
1418 #endif
1419 - const char * inBuf,
1420 - size_t inLen )
1421 +NeonSession_ResponseBlockReader( void * inUserData,
1422 + const char * inBuf,
1423 + size_t inLen )
1425 // neon calls this function with (inLen == 0)...
1426 if ( inLen > 0 )
1427 @@ -226,12 +234,13 @@ extern "C" void NeonSession_ResponseBloc
1428 // -------------------------------------------------------------------
1430 #if NEON_VERSION >= 0x0250
1431 -extern "C" int NeonSession_ResponseBlockWriter( void * inUserData,
1432 +extern "C" int
1433 #else
1434 -extern "C" void NeonSession_ResponseBlockWriter( void * inUserData,
1435 +extern "C" void
1436 #endif
1437 - const char * inBuf,
1438 - size_t inLen )
1439 +NeonSession_ResponseBlockWriter( void * inUserData,
1440 + const char * inBuf,
1441 + size_t inLen )
1443 // neon calls this function with (inLen == 0)...
1444 if ( inLen > 0 )
1445 @@ -299,11 +308,10 @@ extern "C" int NeonSession_NeonAuth( voi
1449 - NeonUri uri( theSession->getRequestEnvironment().m_aRequestURI );
1450 - rtl::OUString aUserInfo( uri.GetUserInfo() );
1451 + rtl::OUString aUserInfo( theSession->getUserInfo() );
1452 if ( aUserInfo.getLength() )
1454 - sal_Int32 nPos = aUserInfo.indexOf( '@' );
1455 + sal_Int32 nPos = aUserInfo.indexOf( ':' );
1456 if ( nPos == -1 )
1458 theUserName = aUserInfo;
1459 @@ -564,6 +572,8 @@ extern "C" void NeonSession_PreSendReque
1463 +NeonLockStore * NeonSession::s_aNeonLockStore = NULL;
1465 // -------------------------------------------------------------------
1466 // Constructor
1467 // -------------------------------------------------------------------
1468 @@ -581,6 +591,7 @@ NeonSession::NeonSession(
1469 m_aScheme = theUri.GetScheme();
1470 m_aHostName = theUri.GetHost();
1471 m_nPort = theUri.GetPort();
1472 + m_aUserInfo = theUri.GetUserInfo();
1474 // Init();
1476 @@ -594,14 +605,6 @@ NeonSession::~NeonSession( )
1478 ne_session_destroy( m_pHttpSession );
1479 m_pHttpSession = 0;
1480 - // Note: Uncomment the following if locking support is required
1481 - /*
1482 - if ( mNeonLockSession != NULL )
1484 - ne_lock_unregister( mNeonLockSession );
1485 - mNeonLockSession = NULL;
1487 - */
1490 delete static_cast<RequestDataMap*>(m_pRequestData);
1491 @@ -629,6 +632,9 @@ void NeonSession::Init()
1492 throw DAVException( DAVException::DAV_SESSION_CREATE,
1493 NeonUri::makeConnectionEndPointString(
1494 m_aHostName, m_nPort ) );
1495 +#if OSL_DEBUG_LEVEL > 0
1496 + ne_debug_init( stderr, NE_DBG_LOCKS );
1497 +#endif
1498 // #122205# - libxml2 needs to be initialized once if used by
1499 // multithreaded programs like OOo.
1500 xmlInitParser();
1501 @@ -746,14 +752,15 @@ void NeonSession::Init()
1502 m_nProxyPort );
1505 - // Note: Uncomment the following if locking support is required
1506 - /*
1507 - mNeonLockSession = ne_lock_register( m_pHttpSession );
1508 + if ( !s_aNeonLockStore )
1509 + s_aNeonLockStore = ne_lockstore_create();
1511 - if ( mNeonLockSession == NULL )
1512 + if ( s_aNeonLockStore == NULL )
1513 throw DAVException( DAVException::DAV_SESSION_CREATE,
1514 - theUri::makeConnectionEndPointString() );
1515 - */
1516 + NeonUri::makeConnectionEndPointString( m_aHostName, m_nPort ) );
1518 + // Register the lock store
1519 + ne_lockstore_register( s_aNeonLockStore, m_pHttpSession );
1521 // Register for redirects.
1522 ne_redirect_register( m_pHttpSession );
1523 @@ -1088,11 +1095,12 @@ void NeonSession::GET( const rtl::OUStri
1524 // -------------------------------------------------------------------
1525 // GET
1526 // -------------------------------------------------------------------
1527 -uno::Reference< io::XInputStream >
1528 +uno::Reference< io::XStream >
1529 NeonSession::GET( const rtl::OUString & inPath,
1530 const std::vector< ::rtl::OUString > & inHeaderNames,
1531 DAVResource & ioResource,
1532 - const DAVRequestEnvironment & rEnv )
1533 + const DAVRequestEnvironment & rEnv,
1534 + sal_Bool bAllowEmpty )
1535 throw ( DAVException )
1537 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1538 @@ -1104,16 +1112,23 @@ NeonSession::GET( const rtl::OUString &
1539 ioResource.uri = inPath;
1540 ioResource.properties.clear();
1542 - rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
1543 - NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource );
1544 + rtl::Reference< NeonInputStream > xStream( new NeonInputStream );
1545 + NeonRequestContext aCtx( xStream, inHeaderNames, ioResource );
1546 int theRetVal = GET( m_pHttpSession,
1547 rtl::OUStringToOString(
1548 inPath, RTL_TEXTENCODING_UTF8 ),
1549 NeonSession_ResponseBlockReader,
1550 true,
1551 &aCtx );
1552 - HandleError( theRetVal );
1553 - return uno::Reference< io::XInputStream >( xInputStream.get() );
1554 + try {
1555 + HandleError( theRetVal );
1557 + catch ( DAVException const & e )
1559 + if ( !bAllowEmpty || ( e.getStatus() != SC_NOT_FOUND ) )
1560 + throw;
1562 + return uno::Reference< io::XStream >( xStream.get() );
1565 // -------------------------------------------------------------------
1566 @@ -1153,22 +1168,38 @@ void NeonSession::PUT( const rtl::OUStri
1567 const DAVRequestEnvironment & rEnv )
1568 throw ( DAVException )
1570 + // initialization etc. is performed in the other PUT
1572 + uno::Sequence< sal_Int8 > aDataToSend;
1573 + if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
1574 + throw DAVException( DAVException::DAV_INVALID_ARG );
1576 + PUT( inPath,
1577 + reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
1578 + aDataToSend.getLength(),
1579 + rEnv );
1582 +// -------------------------------------------------------------------
1583 +// PUT
1584 +// -------------------------------------------------------------------
1585 +void NeonSession::PUT( const rtl::OUString &inPath,
1586 + const char * buffer,
1587 + size_t size,
1588 + const DAVRequestEnvironment & rEnv )
1589 + throw ( DAVException )
1591 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1593 Init();
1595 m_aEnv = rEnv;
1597 - uno::Sequence< sal_Int8 > aDataToSend;
1598 - if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
1599 - throw DAVException( DAVException::DAV_INVALID_ARG );
1601 int theRetVal = PUT( m_pHttpSession,
1602 rtl::OUStringToOString(
1603 inPath, RTL_TEXTENCODING_UTF8 ),
1604 - reinterpret_cast< const char * >(
1605 - aDataToSend.getConstArray() ),
1606 - aDataToSend.getLength() );
1607 + buffer,
1608 + size );
1610 HandleError( theRetVal );
1612 @@ -1344,9 +1375,7 @@ void NeonSession::DESTROY( const rtl::OU
1613 // -------------------------------------------------------------------
1614 // LOCK
1615 // -------------------------------------------------------------------
1616 -// Note: Uncomment the following if locking support is required
1618 -void NeonSession::LOCK( const Lock & inLock,
1619 +void NeonSession::LOCK( ucb::Lock & rLock,
1620 const DAVRequestEnvironment & rEnv )
1621 throw ( DAVException )
1623 @@ -1356,16 +1385,13 @@ void NeonSession::LOCK( const Lock & inL
1625 m_aEnv = rEnv;
1627 - Lockit( inLock, true );
1628 + Lockit( rLock, true );
1632 // -------------------------------------------------------------------
1633 // UNLOCK
1634 // -------------------------------------------------------------------
1635 -// Note: Uncomment the following if locking support is required
1637 -void NeonSession::UNLOCK( const Lock & inLock,
1638 +void NeonSession::UNLOCK( ucb::Lock & rLock,
1639 const DAVRequestEnvironment & rEnv )
1640 throw ( DAVException )
1642 @@ -1375,9 +1401,8 @@ void NeonSession::UNLOCK( const Lock & i
1644 m_aEnv = rEnv;
1646 - Lockit( inLock, false );
1647 + Lockit( rLock, false );
1651 // -------------------------------------------------------------------
1652 const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
1653 @@ -1416,7 +1441,10 @@ void NeonSession::HandleError( int nErro
1654 case NE_ERROR: // Generic error
1656 rtl::OUString aText = rtl::OUString::createFromAscii(
1657 - ne_get_error( m_pHttpSession ) );
1658 + ne_get_error( m_pHttpSession ) );
1659 +#if OSL_DEBUG_LEVEL > 0
1660 + fprintf( stderr, "WebDAV: got error '%s'\n", rtl::OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ).getStr() );
1661 +#endif
1662 throw DAVException( DAVException::DAV_HTTP_ERROR,
1663 aText,
1664 makeStatusCode( aText ) );
1665 @@ -1473,77 +1501,156 @@ void NeonSession::HandleError( int nErro
1669 -// Note: Uncomment the following if locking support is required
1671 -void NeonSession::Lockit( const Lock & inLock, bool inLockit )
1672 +void NeonSession::Lockit( ucb::Lock & rLock, bool bLockit )
1673 throw ( DAVException )
1675 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1677 - // Create the neon lock
1678 - NeonLock * theLock = new NeonLock;
1679 - int theRetVal;
1681 - // Set the lock uri
1682 - NeonUri theUri( inLock.uri );
1683 - theLock->uri = const_cast< char * >
1684 - ( rtl::OUStringToOString(
1685 - theUri.GetPath(), RTL_TEXTENCODING_UTF8 ).getStr() );
1686 + if ( !s_aNeonLockStore )
1687 + throw DAVException( DAVException::DAV_INVALID_ARG );
1689 - if ( inLockit )
1691 - // Set the lock depth
1692 - switch( inLock.depth )
1694 - case DAVZERO:
1695 - case DAVINFINITY:
1696 - theLock->depth = int ( inLock.depth );
1697 - break;
1698 - default:
1699 - throw DAVException( DAVException::DAV_INVALID_ARG );
1700 - break;
1702 + ne_uri aUri;
1703 + ne_uri_parse( rtl::OUStringToOString( m_aEnv.m_aRequestURI, RTL_TEXTENCODING_UTF8 ).getStr(),
1704 + &aUri );
1706 +#if NEON_VERSION < 0x0260
1707 +#define FILLIN( field, val ) aUri.field = aUri.field? aUri.field: strdup( rtl::OUStringToOString( val, RTL_TEXTENCODING_UTF8 ).getStr() )
1708 + FILLIN( scheme, m_aScheme );
1709 + FILLIN( host, m_aHostName );
1710 + aUri.port = aUri.port? aUri.port: m_nPort;
1711 +#undef FILLIN
1712 +#endif
1714 - // Set the lock scope
1715 - switch ( inLock.scope )
1717 - case EXCLUSIVE:
1718 - theLock->scope = ne_lockscope_exclusive;
1719 - break;
1720 - case SHARED:
1721 - theLock->scope = ne_lockscope_shared;
1722 - break;
1723 - default:
1724 - throw DAVException( DAVException::DAV_INVALID_ARG );
1725 - break;
1727 + // Create the neon lock
1728 + NeonLock * theLock = ne_lockstore_findbyuri( s_aNeonLockStore, &aUri );
1729 + bool bAlreadyExists = false;
1730 + if ( theLock )
1731 + bAlreadyExists = true;
1732 + else
1734 + theLock = ne_lock_create();
1736 - // Set the lock owner
1737 - const char * theOwner = rtl::OUStringToOString( inLock.owner,
1738 - RTL_TEXTENCODING_UTF8 );
1739 - theLock->owner = const_cast< char * > ( theOwner );
1741 - // Set the lock timeout
1742 - // Note: Neon ignores the timeout
1743 - //theLock->timeout = inLock.timeout;
1744 + // Set the lock uri
1745 + theLock->uri = aUri;
1747 - theRetVal = ne_lock( m_pHttpSession, theLock );
1749 - else
1751 + // Set the lock depth
1752 + switch( rLock.Depth )
1754 + case ucb::LockDepth_ZERO: theLock->depth = NE_DEPTH_ZERO; break;
1755 + case ucb::LockDepth_ONE: theLock->depth = NE_DEPTH_ONE; break;
1756 + case ucb::LockDepth_INFINITY: theLock->depth = NE_DEPTH_INFINITE; break;
1757 + default:
1758 + throw DAVException( DAVException::DAV_INVALID_ARG );
1761 - // Set the lock token
1762 - rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ];
1763 - theLock->token = const_cast< char * >
1764 - ( rtl::OUStringToOString(
1765 - theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
1766 + // Set the lock scope
1767 + switch ( rLock.Scope )
1769 + case ucb::LockScope_EXCLUSIVE: theLock->scope = ne_lockscope_exclusive; break;
1770 + case ucb::LockScope_SHARED: theLock->scope = ne_lockscope_shared; break;
1771 + default:
1772 + throw DAVException( DAVException::DAV_INVALID_ARG );
1773 + break;
1776 - theRetVal = ne_unlock( m_pHttpSession, theLock );
1778 + // Set the lock owner
1779 + rtl::OUString aValue;
1780 + rLock.Owner >>= aValue;
1782 - HandleError( theRetVal );
1783 + theLock->owner = strdup( rtl::OUStringToOString( aValue, RTL_TEXTENCODING_UTF8 ).getStr() );
1785 + // Set the lock timeout
1786 + // We re-new the lock while the stream is open
1787 + theLock->timeout = rLock.Timeout;
1790 + if ( bLockit )
1792 + int nRet;
1793 + if ( bAlreadyExists )
1795 +#if NEON_VERSION >= 0x0260
1796 + nRet = ne_lock_refresh( m_pHttpSession, theLock );
1797 +#else
1798 + // workaround for a bug in neon 0.24
1799 + // we have to call with a bigger structure that is used internally
1800 + // and initialize parts of it
1802 + struct lock_ctx
1804 + struct ne_lock active; /* activelock */
1805 + char *token; /* the token we're after. */
1806 + int found;
1807 + ne_buffer *cdata;
1808 + };
1810 + struct lock_ctx ctx;
1812 + memset( &ctx, 0, sizeof ctx );
1813 + ctx.cdata = ne_buffer_create();
1815 + memcpy( &ctx, theLock, sizeof( *theLock ) );
1816 + nRet = ne_lock_refresh( m_pHttpSession, reinterpret_cast<NeonLock*>( &ctx ) );
1818 + ne_buffer_destroy( ctx.cdata );
1819 +#endif
1820 + if ( ( nRet == NE_ERROR ) && strncmp (ne_get_error (m_pHttpSession), "No activelock ", strlen ("No activelock ")) == 0 )
1822 + bAlreadyExists = false;
1823 + ne_lockstore_remove( s_aNeonLockStore, theLock );
1826 + if ( !bAlreadyExists )
1828 + nRet = ne_lock( m_pHttpSession, theLock );
1830 + if ( nRet == NE_OK )
1832 + ne_lockstore_add( s_aNeonLockStore, theLock );
1834 + uno::Sequence< rtl::OUString > aTokens( 1 );
1835 + aTokens[0] = rtl::OUString::createFromAscii( theLock->token );
1836 + rLock.LockTokens = aTokens;
1838 +#if OSL_DEBUG_LEVEL > 0
1839 + fprintf( stderr, "WebDAV: locked the URL, the token is: %s\n", theLock->token );
1840 +#endif
1844 + if ( ( nRet == NE_ERROR ) && getStatusCode( m_pHttpSession ) == SC_LOCKED )
1846 + ucbhelper::cancelCommandExecution( ucb::IOErrorCode_LOCKING_VIOLATION,
1847 + uno::Sequence< uno::Any >( 0 ), // FIXME more info about the file?
1848 + m_aEnv.m_xEnv,
1849 + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a locking error occured" ) ),
1850 + uno::Reference< ucb::XCommandProcessor >() );
1852 +#if OSL_DEBUG_LEVEL > 0
1853 + else if ( nRet == NE_OK )
1854 + fprintf( stderr, "WebDAV: locked/refreshed lock OK\n" );
1855 + else
1856 + fprintf( stderr, "WebDAV: failed to lock the file: %s\n", ne_get_error( m_pHttpSession ) );
1857 +#endif
1859 + else
1861 + // Set the lock token
1862 + if ( rLock.LockTokens.getLength() > 0 )
1864 + rtl::OUString theToken = rLock.LockTokens.getConstArray()[ 0 ];
1865 + theLock->token = strdup( rtl::OUStringToOString( theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
1867 +#if OSL_DEBUG_LEVEL > 0
1868 + fprintf( stderr, "WebDAV: going to unlock the URL, the token is: %s\n", theLock->token );
1869 +#endif
1871 + ne_unlock( m_pHttpSession, theLock );
1872 + ne_lockstore_remove( s_aNeonLockStore, theLock );
1873 + // FIXME even ne_lock_destroy( theLock )?
1879 // -------------------------------------------------------------------
1880 namespace {
1881 --- ucb/source/ucp/webdav/NeonSession.hxx.old 2009-04-02 11:01:38.000000000 +0000
1882 +++ ucb/source/ucp/webdav/NeonSession.hxx 2009-04-06 16:41:46.000000000 +0000
1883 @@ -57,6 +57,7 @@ class NeonSession : public DAVSession
1884 rtl::OUString m_aScheme;
1885 rtl::OUString m_aHostName;
1886 rtl::OUString m_aProxyName;
1887 + rtl::OUString m_aUserInfo;
1888 sal_Int32 m_nPort;
1889 sal_Int32 m_nProxyPort;
1890 HttpSession * m_pHttpSession;
1891 @@ -70,8 +71,7 @@ class NeonSession : public DAVSession
1892 // moment.
1893 DAVRequestEnvironment m_aEnv;
1895 - // Note: Uncomment the following if locking support is required
1896 - // NeonLockSession * mNeonLockSession;
1897 + static NeonLockStore *s_aNeonLockStore;
1899 static bool m_bGlobalsInited;
1901 @@ -92,6 +92,8 @@ class NeonSession : public DAVSession
1902 const DAVRequestEnvironment & getRequestEnvironment() const
1903 { return m_aEnv; }
1905 + const rtl::OUString & getUserInfo() const { return m_aUserInfo; }
1907 virtual void
1908 OPTIONS( const ::rtl::OUString & inPath,
1909 DAVCapabilities & outCapabilities,
1910 @@ -142,11 +144,12 @@ class NeonSession : public DAVSession
1911 throw ( DAVException );
1913 virtual com::sun::star::uno::Reference<
1914 - com::sun::star::io::XInputStream >
1915 + com::sun::star::io::XStream >
1916 GET( const ::rtl::OUString & inPath,
1917 const std::vector< ::rtl::OUString > & inHeaderNames,
1918 DAVResource & ioResource,
1919 - const DAVRequestEnvironment & rEnv )
1920 + const DAVRequestEnvironment & rEnv,
1921 + sal_Bool bAllowEmpty = sal_False )
1922 throw ( DAVException );
1924 virtual void
1925 @@ -165,6 +168,13 @@ class NeonSession : public DAVSession
1926 const DAVRequestEnvironment & rEnv )
1927 throw ( DAVException );
1929 + virtual void
1930 + PUT( const ::rtl::OUString & inPath,
1931 + const char * buffer,
1932 + size_t size,
1933 + const DAVRequestEnvironment & rEnv )
1934 + throw ( DAVException );
1936 virtual com::sun::star::uno::Reference<
1937 com::sun::star::io::XInputStream >
1938 POST( const rtl::OUString & inPath,
1939 @@ -209,16 +219,13 @@ class NeonSession : public DAVSession
1940 const DAVRequestEnvironment & rEnv )
1941 throw ( DAVException );
1943 - // Note: Uncomment the following if locking support is required
1944 - /*
1945 - virtual void LOCK (const Lock & inLock,
1946 - const DAVRequestEnvironment & rEnv )
1947 + virtual void LOCK ( com::sun::star::ucb::Lock & rLock,
1948 + const DAVRequestEnvironment & rEnv )
1949 throw ( DAVException );
1951 - virtual void UNLOCK (const Lock & inLock,
1952 - const DAVRequestEnvironment & rEnv )
1953 + virtual void UNLOCK ( com::sun::star::ucb::Lock & rLock,
1954 + const DAVRequestEnvironment & rEnv )
1955 throw ( DAVException );
1956 - */
1958 // helpers
1959 const rtl::OUString & getHostName() const { return m_aHostName; }
1960 @@ -239,9 +246,8 @@ class NeonSession : public DAVSession
1962 const ucbhelper::InternetProxyServer & getProxySettings() const;
1964 - // Note: Uncomment the following if locking support is required
1965 - // void Lockit( const Lock & inLock, bool inLockit )
1966 - // throw ( DAVException );
1967 + void Lockit( com::sun::star::ucb::Lock & rLock, bool bLockit )
1968 + throw ( DAVException );
1970 // low level GET implementation, used by public GET implementations
1971 static int GET( ne_session * sess,
1972 --- ucb/source/ucp/webdav/NeonTypes.hxx.old 2009-04-02 11:01:38.000000000 +0000
1973 +++ ucb/source/ucp/webdav/NeonTypes.hxx 2009-04-06 16:41:46.000000000 +0000
1974 @@ -35,6 +35,7 @@
1975 #include <ne_utils.h>
1976 #include <ne_basic.h>
1977 #include <ne_props.h>
1978 +#include <ne_locks.h>
1980 typedef ne_session HttpSession;
1981 typedef ne_status HttpStatus;
1982 @@ -43,4 +44,7 @@ typedef ne_server_capabilities Http
1983 typedef ne_propname NeonPropName;
1984 typedef ne_prop_result_set NeonPropFindResultSet;
1986 +typedef ne_lock_store NeonLockStore;
1987 +typedef struct ne_lock NeonLock;
1989 #endif // _NEONTYPES_HXX_
1990 --- ucb/source/ucp/webdav/webdavcontent.cxx.old 2009-04-02 11:01:38.000000000 +0000
1991 +++ ucb/source/ucp/webdav/webdavcontent.cxx 2009-04-06 16:41:46.000000000 +0000
1992 @@ -37,6 +37,7 @@
1994 *************************************************************************/
1995 #include <osl/diagnose.h>
1996 +#include <osl/thread.hxx>
1998 #include "osl/doublecheckedlocking.h"
1999 #include <rtl/uri.hxx>
2000 @@ -48,20 +49,17 @@
2001 #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
2002 #include <com/sun/star/beans/PropertyValue.hpp>
2003 #include <com/sun/star/io/XActiveDataSink.hpp>
2004 +#include <com/sun/star/io/XActiveDataStreamer.hpp>
2005 #include <com/sun/star/io/XOutputStream.hpp>
2006 #include <com/sun/star/lang/IllegalAccessException.hpp>
2007 #include "com/sun/star/ucb/AuthenticationRequest.hpp"
2008 #include <com/sun/star/ucb/CommandFailedException.hpp>
2009 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
2010 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
2011 -#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
2012 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
2013 -#endif
2014 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
2015 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
2016 -#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_
2017 #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
2018 -#endif
2019 #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
2020 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
2021 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
2022 @@ -90,6 +88,8 @@
2023 #include "NeonUri.hxx"
2024 #include "UCBDeadPropertyValue.hxx"
2026 +#include "NeonInputStream.hxx"
2028 using namespace com::sun::star;
2029 using namespace webdav_ucp;
2031 @@ -345,6 +345,123 @@ void SAL_CALL CommandEnvironment_Impl::h
2032 //=========================================================================
2033 //=========================================================================
2035 +// Our signal - 246 is just a random number ;-)
2036 +#define TICKER_THREAD_USER_SIGNAL ( OSL_SIGNAL_USER_RESERVED + 246 )
2038 +// -------------------------------------------------------------------
2039 +// A thread that 'ticks' - emits the user signal every second
2040 +// -------------------------------------------------------------------
2041 +class TickerThread : public osl::Thread
2043 + bool m_bFinish;
2045 +public:
2047 + TickerThread() : osl::Thread(), m_bFinish( false ) {}
2049 + void finish() { m_bFinish = true; }
2051 +protected:
2053 + virtual void SAL_CALL run();
2056 +void TickerThread::run()
2058 + // we have to go through the loop more often to be able to finish ~quickly
2059 + const int nNth = 25;
2061 + int nCount = nNth;
2062 + while ( !m_bFinish )
2064 + if ( nCount-- <= 0 )
2066 + osl_raiseSignal( TICKER_THREAD_USER_SIGNAL, NULL );
2067 + nCount = nNth;
2070 + TimeValue aTV;
2071 + aTV.Seconds = 0;
2072 + aTV.Nanosec = 1000000000/nNth;
2073 + wait( aTV );
2077 +// -------------------------------------------------------------------
2078 +// A class that takes care of creating and destroying the ticker thread
2079 +// -------------------------------------------------------------------
2080 +class TickerThreadController
2082 + osl::Mutex m_aMutex;
2083 + int m_nCount;
2084 + TickerThread *m_pTickerThread;
2086 +public:
2088 + TickerThreadController() : m_nCount( 0 ), m_pTickerThread( NULL ) {}
2090 + void start();
2091 + void stop();
2094 +void TickerThreadController::start()
2096 + osl::MutexGuard aGuard( m_aMutex );
2098 + if ( ( m_nCount++ == 0 ) && !m_pTickerThread )
2100 + m_pTickerThread = new TickerThread();
2101 + m_pTickerThread->create();
2105 +void TickerThreadController::stop()
2107 + osl::MutexGuard aGuard( m_aMutex );
2109 + if ( ( --m_nCount == 0 ) && m_pTickerThread )
2111 + m_pTickerThread->finish();
2112 + m_pTickerThread->join();
2114 + delete m_pTickerThread;
2115 + m_pTickerThread = NULL;
2119 +// -------------------------------------------------------------------
2120 +// Signal handler
2121 +// -------------------------------------------------------------------
2122 +oslSignalAction Content::HandleLockingSignal( void* pData, oslSignalInfo* pSignalInfo )
2124 + Content *pContent = static_cast< Content *>( pData );
2126 +#if OSL_DEBUG_LEVEL > 0
2127 + fprintf( stderr, "Content::HandleLockingSignal: pContent=%p\n", pContent );
2128 +#endif
2130 + if ( !pContent )
2131 + return osl_Signal_ActCallNextHdl;
2133 + if ( pSignalInfo &&
2134 + pSignalInfo->Signal == osl_Signal_User &&
2135 + pSignalInfo->UserSignal == TICKER_THREAD_USER_SIGNAL )
2137 + pContent->RefreshLock();
2139 + else if ( !pSignalInfo || ( pSignalInfo->Signal != osl_Signal_User ) )
2141 + // terminating or something
2142 + pContent->m_xResAccess->UNLOCK( *pContent->m_pLock, pContent->m_xLockEnv );
2143 + delete pContent->m_pLock;
2144 + pContent->m_pLock = NULL;
2147 + return osl_Signal_ActCallNextHdl;
2150 +static TickerThreadController sTickerThreadController;
2152 //=========================================================================
2153 // ctr for content on an existing webdav resource
2154 Content::Content(
2155 @@ -358,7 +475,11 @@ Content::Content(
2156 m_pProvider( pProvider ),
2157 m_bTransient( false ),
2158 m_bCollection( false ),
2159 - m_bDidGetOrHead( false )
2160 + m_bDidGetOrHead( false ),
2161 + m_bForceReadOnly( false ),
2162 + m_pLock( NULL ),
2163 + m_nToExpire( -1 ),
2164 + m_pSignalHandler( NULL )
2168 @@ -369,6 +490,13 @@ Content::Content(
2170 NeonUri aURI( Identifier->getContentIdentifier() );
2171 m_aEscapedTitle = aURI.GetPathBaseName();
2173 + m_pSignalHandler = osl_addSignalHandler( HandleLockingSignal, this );
2175 +#if OSL_DEBUG_LEVEL > 0
2176 + fprintf( stderr, "Content::Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
2177 +#endif
2178 + sTickerThreadController.start();
2180 catch ( DAVException const & )
2182 @@ -390,12 +518,23 @@ Content::Content(
2183 m_pProvider( pProvider ),
2184 m_bTransient( true ),
2185 m_bCollection( isCollection ),
2186 - m_bDidGetOrHead( false )
2187 + m_bDidGetOrHead( false ),
2188 + m_bForceReadOnly( false ),
2189 + m_pLock( NULL ),
2190 + m_nToExpire( -1 ),
2191 + m_pSignalHandler( NULL )
2195 m_xResAccess.reset( new DAVResourceAccess(
2196 rxSMgr, rSessionFactory, Identifier->getContentIdentifier() ) );
2198 + m_pSignalHandler = osl_addSignalHandler( HandleLockingSignal, this );
2200 +#if OSL_DEBUG_LEVEL > 0
2201 + fprintf( stderr, "Content::Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
2202 +#endif
2203 + sTickerThreadController.start();
2205 catch ( DAVException const & )
2207 @@ -409,6 +548,48 @@ Content::Content(
2208 // virtual
2209 Content::~Content()
2211 +#if OSL_DEBUG_LEVEL > 0
2212 + fprintf( stderr, "Content::~Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
2213 +#endif
2214 + sTickerThreadController.stop();
2216 + osl_removeSignalHandler( m_pSignalHandler );
2218 + if (m_pLock != NULL)
2220 + try {
2221 + m_xResAccess->UNLOCK( *m_pLock, m_xLockEnv );
2222 + delete m_pLock;
2223 + m_pLock = NULL;
2225 + catch ( ucb::CommandFailedException const & )
2231 +// -------------------------------------------------------------------
2232 +// Lock the resource again
2233 +// -------------------------------------------------------------------
2234 +void Content::RefreshLock( void )
2236 + osl::MutexGuard aGuard( m_aLock );
2238 +#if OSL_DEBUG_LEVEL > 0
2239 + if (m_nToExpire > 0)
2240 + fprintf( stderr, "WebDAV: RefreshLock() - will refresh in %d sec\n", m_nToExpire - 30 );
2241 +#endif
2243 + if ( m_nToExpire > 0 )
2244 + --m_nToExpire;
2246 + // Refresh the lock if it expires in less than 30 s
2247 + if ( m_pLock && m_nToExpire >= 0 && m_nToExpire < 30 )
2249 + m_xResAccess->LOCK( *m_pLock, m_xLockEnv );
2251 + m_nToExpire = m_pLock->Timeout;
2255 //=========================================================================
2256 @@ -630,6 +811,11 @@ uno::Any SAL_CALL Content::execute(
2257 ucb::CommandAbortedException,
2258 uno::RuntimeException )
2260 +#if OSL_DEBUG_LEVEL > 0
2261 + fprintf( stderr, "WebDAV: Execute command '%s'\n",
2262 + rtl::OUStringToOString( aCommand.Name, RTL_TEXTENCODING_UTF8 ).getStr() );
2263 +#endif
2265 uno::Any aRet;
2267 if ( aCommand.Name.equalsAsciiL(
2268 @@ -1349,6 +1535,31 @@ uno::Reference< sdbc::XRow > Content::ge
2269 uno::Reference< ucb::XContentIdentifier > xIdentifier;
2270 rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
2272 +#if OSL_DEBUG_LEVEL > 0
2273 + fprintf( stderr, "WebDAV: getPropertyValues: answering the following properties: " );
2274 + for ( int i = 0; i < rProperties.getLength(); ++i )
2275 + fprintf( stderr, " %s,",
2276 + rtl::OUStringToOString( rProperties[i].Name, RTL_TEXTENCODING_UTF8 ).getStr() );
2277 + fprintf( stderr, "\n" );
2278 +#endif
2280 + // WebDAV supports XActiveDataStreamer
2281 + // We have to return TRUE on
2282 + // - SupportsActiveStreaming - always
2283 + // - IsReadOnly - if we forced read only due to failed locking
2284 + if ( rProperties.getLength() == 1 )
2286 + if ( rProperties[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SupportsActiveStreaming" ) ) ||
2287 + ( rProperties[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsReadOnly" ) ) && m_bForceReadOnly ) )
2289 + rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
2290 + = new ::ucbhelper::PropertyValueSet( m_xSMgr );
2291 + xRow->appendBoolean( rProperties[0], sal_True );
2293 + return uno::Reference< sdbc::XRow >( xRow.get() );
2298 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2300 @@ -1475,8 +1686,13 @@ uno::Reference< sdbc::XRow > Content::ge
2302 if ( !bNetworkAccessAllowed )
2304 - cancelCommandExecution( e, xEnv );
2305 - // unreachable
2306 + if ( e.getStatus() == SC_NOT_FOUND )
2307 + xProps.reset();
2308 + else
2310 + cancelCommandExecution( e, xEnv );
2311 + // unreachable
2316 @@ -2092,9 +2308,10 @@ uno::Any Content::open(
2320 - if ( rArg.Sink.is() )
2322 - // Open document.
2323 + if ( !rArg.Sink.is() )
2324 + return aRet;
2326 + // Open document.
2328 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
2329 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
2330 @@ -2115,6 +2332,9 @@ uno::Any Content::open(
2331 = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
2332 if ( xOut.is() )
2334 +#if OSL_DEBUG_LEVEL > 0
2335 + fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" );
2336 +#endif
2337 // PUSH: write data
2340 @@ -2159,6 +2379,60 @@ uno::Any Content::open(
2341 uno::UNO_QUERY );
2342 if ( xDataSink.is() )
2344 +#if OSL_DEBUG_LEVEL > 0
2345 + fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" );
2346 +#endif
2347 + // PULL: wait for client read
2348 + try
2351 + osl::MutexGuard aGuard( m_aMutex );
2353 + // throw away previously cached headers.
2354 + m_xCachedProps.reset();
2356 + // fill inputsream sync; return if all data present
2357 + DAVResource aResource;
2358 + std::vector< rtl::OUString > aHeaders;
2359 + // // Obtain list containing all HTTP headers that can
2360 + // // be mapped to UCB properties.
2361 + // ContentProperties::getMappableHTTPHeaders( aHeaders );
2362 + uno::Reference< io::XInputStream > xIn
2363 + = m_xResAccess->GET( aHeaders, aResource, xEnv )->getInputStream();
2366 + osl::MutexGuard aGuard( m_aMutex );
2368 + m_xCachedProps.reset(
2369 + new ContentProperties( aResource ) );
2372 + xDataSink->setInputStream( xIn );
2374 + catch ( DAVException const & e )
2376 + cancelCommandExecution( e, xEnv );
2377 + // Unreachable
2380 + else
2382 + uno::Reference< io::XActiveDataStreamer > xDataStreamer
2383 + = uno::Reference< io::XActiveDataStreamer >( rArg.Sink,
2384 + uno::UNO_QUERY );
2385 + if ( xDataStreamer.is() && !m_bForceReadOnly )
2387 +#if OSL_DEBUG_LEVEL > 0
2388 + fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer\n" );
2389 +#endif
2390 + // prepare the lock
2391 + m_pLock = new ucb::Lock;
2392 + m_pLock->Depth = ucb::LockDepth_ZERO;
2393 + m_pLock->Scope = ucb::LockScope_EXCLUSIVE;
2394 + m_pLock->Timeout = 2*60; // 2 minutes
2396 + m_nToExpire = m_pLock->Timeout;
2398 // PULL: wait for client read
2401 @@ -2174,9 +2448,31 @@ uno::Any Content::open(
2402 DAVResource aResource;
2403 std::vector< rtl::OUString > aHeaders;
2405 - uno::Reference< io::XInputStream > xIn
2406 - = xResAccess->GET( aHeaders, aResource, xEnv );
2407 + try {
2408 + m_xResAccess->LOCK( *m_pLock, xEnv );
2409 + m_xLockEnv = xEnv;
2411 + catch ( ucb::CommandFailedException const &e )
2413 + // stream locked?
2414 + ucb::InteractiveIOException aIoException;
2415 + if ( ( e.Reason >>= aIoException ) && ( aIoException.Code == ucb::IOErrorCode_LOCKING_VIOLATION ) )
2417 + delete m_pLock;
2418 + m_pLock = NULL;
2419 + // yes => we must be read only at the next try
2420 + m_bForceReadOnly = sal_True;
2423 + throw;
2426 + uno::Reference< io::XStream > xStream
2427 + = xResAccess->GET( aHeaders, aResource, xEnv, sal_True );
2428 m_bDidGetOrHead = true;
2430 + // pass the URL to the stream
2431 + static_cast< NeonInputStream* >( xStream.get() )->SetURL( m_xResAccess->getURL() );
2434 osl::MutexGuard aGuard( m_aMutex );
2435 @@ -2191,16 +2487,24 @@ uno::Any Content::open(
2436 new DAVResourceAccess( *xResAccess.get() ) );
2439 - xDataSink->setInputStream( xIn );
2440 + xDataStreamer->setStream( xStream );
2442 catch ( DAVException const & e )
2444 + m_xResAccess->UNLOCK( *m_pLock, xEnv );
2445 + delete m_pLock;
2446 + m_pLock = NULL;
2447 + m_bForceReadOnly = sal_False;
2449 cancelCommandExecution( e, xEnv );
2450 // Unreachable
2453 else
2455 +#if OSL_DEBUG_LEVEL > 0
2456 + fprintf( stderr, "WebDAV: unsupported rArg.Sink\n" );
2457 +#endif
2458 // Note: aOpenCommand.Sink may contain an XStream
2459 // implementation. Support for this type of
2460 // sink is optional...
2461 @@ -2228,6 +2532,9 @@ void Content::post(
2462 uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
2463 if ( xSink.is() )
2465 +#if OSL_DEBUG_LEVEL > 0
2466 + fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataSink\n" );
2467 +#endif
2470 std::auto_ptr< DAVResourceAccess > xResAccess;
2471 @@ -2262,6 +2569,9 @@ void Content::post(
2472 uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
2473 if ( xResult.is() )
2475 +#if OSL_DEBUG_LEVEL > 0
2476 + fprintf( stderr, "WebDAV: rArg.Sink is XOutputStream\n" );
2477 +#endif
2480 std::auto_ptr< DAVResourceAccess > xResAccess;
2481 @@ -2291,6 +2601,9 @@ void Content::post(
2483 else
2485 +#if OSL_DEBUG_LEVEL > 0
2486 + fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer (or something)\n" );
2487 +#endif
2488 ucbhelper::cancelCommandExecution(
2489 uno::makeAny(
2490 ucb::UnsupportedDataSinkException(
2491 @@ -2643,11 +2956,23 @@ void Content::transfer(
2492 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2494 else if ( aScheme.equalsAsciiL(
2495 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) )
2497 + sourceURI.SetScheme(
2498 + rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2500 + else if ( aScheme.equalsAsciiL(
2501 RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
2503 sourceURI.SetScheme(
2504 rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
2506 + else if ( aScheme.equalsAsciiL(
2507 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) )
2509 + sourceURI.SetScheme(
2510 + rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
2512 else
2514 if ( !aScheme.equalsAsciiL(
2515 @@ -2674,6 +2999,18 @@ void Content::transfer(
2516 RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
2517 targetURI.SetScheme(
2518 rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2519 + else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
2520 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) )
2521 + targetURI.SetScheme(
2522 + rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
2523 + else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
2524 + RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
2525 + targetURI.SetScheme(
2526 + rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
2527 + else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
2528 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) )
2529 + targetURI.SetScheme(
2530 + rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
2532 // @@@ This implementation of 'transfer' only works
2533 // if the source and target are located at same host.
2534 --- ucb/source/ucp/webdav/webdavcontent.hxx.old 2009-04-02 11:01:38.000000000 +0000
2535 +++ ucb/source/ucp/webdav/webdavcontent.hxx 2009-04-06 16:41:46.000000000 +0000
2536 @@ -33,10 +33,13 @@
2538 #include <memory>
2539 #include <list>
2540 +#include <osl/signal.h>
2541 #include <rtl/ref.hxx>
2542 #include <com/sun/star/ucb/ContentCreationException.hpp>
2543 #include <com/sun/star/ucb/XContentCreator.hpp>
2544 +#include <com/sun/star/ucb/Lock.hpp>
2545 #include <ucbhelper/contenthelper.hxx>
2547 #include "DAVResourceAccess.hxx"
2548 #include "PropertyMap.hxx"
2550 @@ -91,6 +94,9 @@ class Content : public ::ucbhelper::Cont
2551 bool m_bTransient;
2552 bool m_bCollection;
2553 bool m_bDidGetOrHead;
2554 + bool m_bForceReadOnly;
2555 + com::sun::star::ucb::Lock *m_pLock;
2556 + uno::Reference< ucb::XCommandEnvironment > m_xLockEnv;
2557 std::vector< rtl::OUString > m_aFailedPropNames;
2559 private:
2560 @@ -184,6 +190,17 @@ private:
2562 static bool shouldAccessNetworkAfterException( const DAVException & e );
2564 + oslSignalHandler m_pSignalHandler;
2565 + int m_nToExpire;
2566 + osl::Mutex m_aLock;
2568 + // Refresh the lock of the resource
2569 + void RefreshLock( void );
2571 + // Refresh the lock if necessary, or unlock the resource when
2572 + // OOo crashes or is terminated
2573 + static oslSignalAction HandleLockingSignal( void* pData, oslSignalInfo* pInfo );
2575 public:
2576 Content( const ::com::sun::star::uno::Reference<
2577 ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
2578 --- ucb/source/ucp/webdav/webdavcontentcaps.cxx.old 2009-04-02 11:01:38.000000000 +0000
2579 +++ ucb/source/ucp/webdav/webdavcontentcaps.cxx 2009-04-06 16:41:46.000000000 +0000
2580 @@ -263,6 +263,24 @@ bool ContentProvider::getProperty(
2582 getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
2583 beans::PropertyAttribute::BOUND ) );
2585 + m_pProps->insert(
2586 + beans::Property(
2587 + rtl::OUString(
2588 + RTL_CONSTASCII_USTRINGPARAM( "SupportsActiveStreaming" ) ),
2589 + -1,
2590 + getCppuBooleanType(),
2591 + beans::PropertyAttribute::BOUND
2592 + | beans::PropertyAttribute::READONLY ) );
2594 + m_pProps->insert(
2595 + beans::Property(
2596 + rtl::OUString(
2597 + RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
2598 + -1,
2599 + getCppuBooleanType(),
2600 + beans::PropertyAttribute::BOUND
2601 + | beans::PropertyAttribute::READONLY ) );
2605 --- ucb/source/ucp/webdav/webdavprovider.cxx.old 2009-04-02 11:01:38.000000000 +0000
2606 +++ ucb/source/ucp/webdav/webdavprovider.cxx 2009-04-06 16:41:46.000000000 +0000
2607 @@ -36,6 +36,9 @@
2608 **************************************************************************
2610 *************************************************************************/
2612 +#include <string.h>
2614 #include <ucbhelper/contentidentifier.hxx>
2615 #include "webdavprovider.hxx"
2616 #include "webdavcontent.hxx"
2617 @@ -138,7 +141,11 @@ ContentProvider::queryContent(
2618 RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
2619 !aScheme.equalsAsciiL(
2620 RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) &&
2621 - !aScheme.equalsAsciiL(
2622 + !aScheme.equalsAsciiL(
2623 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) &&
2624 + !aScheme.equalsAsciiL(
2625 + RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) &&
2626 + !aScheme.equalsAsciiL(
2627 RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) )
2628 throw ucb::IllegalIdentifierException();
2630 @@ -157,32 +164,27 @@ ContentProvider::queryContent(
2631 uno::Reference< ucb::XContentIdentifier > xCanonicId;
2633 bool bNewId = false;
2634 - if ( aScheme.equalsAsciiL(
2635 - RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
2636 + struct {
2637 + const char *from;
2638 + const char *to;
2639 + } const *pScheme, pReplace[] = {
2640 + { WEBDAV_URL_SCHEME, HTTP_URL_SCHEME },
2641 + { DAV_URL_SCHEME, HTTP_URL_SCHEME },
2642 + { DAVS_URL_SCHEME, HTTPS_URL_SCHEME },
2643 + { PLAIN_WEBDAV_URL_SCHEME, HTTP_URL_SCHEME },
2644 + { PLAIN_WEBDAVS_URL_SCHEME, HTTPS_URL_SCHEME },
2645 + { NULL, NULL }
2646 + };
2647 + for ( pScheme = pReplace; pScheme->from ; ++pScheme )
2649 - aURL = aURL.replaceAt( 0,
2650 - WEBDAV_URL_SCHEME_LENGTH,
2651 - rtl::OUString::createFromAscii(
2652 - HTTP_URL_SCHEME ) );
2653 - bNewId = true;
2655 - else if ( aScheme.equalsAsciiL(
2656 - RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
2658 - aURL = aURL.replaceAt( 0,
2659 - DAV_URL_SCHEME_LENGTH,
2660 - rtl::OUString::createFromAscii(
2661 - HTTP_URL_SCHEME ) );
2662 - bNewId = true;
2664 - else if ( aScheme.equalsAsciiL(
2665 - RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
2667 - aURL = aURL.replaceAt( 0,
2668 - DAVS_URL_SCHEME_LENGTH,
2669 - rtl::OUString::createFromAscii(
2670 - HTTPS_URL_SCHEME ) );
2671 - bNewId = true;
2672 + if ( aScheme.equalsAscii( pScheme->from ) )
2674 + aURL = aURL.replaceAt( 0,
2675 + strlen( pScheme->from ),
2676 + rtl::OUString::createFromAscii( pScheme->to ) );
2677 + bNewId = true;
2678 + break;
2682 sal_Int32 nPos = aURL.lastIndexOf( '/' );
2683 @@ -232,4 +234,3 @@ ContentProvider::queryContent(
2685 return xContent;
2688 --- ucb/source/ucp/webdav/webdavprovider.hxx.old 2009-04-02 11:01:38.000000000 +0000
2689 +++ ucb/source/ucp/webdav/webdavprovider.hxx 2009-04-06 16:41:46.000000000 +0000
2690 @@ -52,13 +52,10 @@ namespace webdav_ucp {
2691 // contents ) according to this scheme.
2692 #define WEBDAV_URL_SCHEME \
2693 "vnd.sun.star.webdav"
2694 -#define WEBDAV_URL_SCHEME_LENGTH 19
2696 #define HTTP_URL_SCHEME "http"
2697 -#define HTTP_URL_SCHEME_LENGTH 4
2699 #define HTTPS_URL_SCHEME "https"
2700 -#define HTTPS_URL_SCHEME_LENGTH 5
2702 #define DAV_URL_SCHEME "dav"
2703 #define DAV_URL_SCHEME_LENGTH 3
2704 @@ -70,6 +67,12 @@ namespace webdav_ucp {
2706 #define FTP_URL_SCHEME "ftp"
2708 +#define DAV_URL_SCHEME "dav"
2709 +#define DAVS_URL_SCHEME "davs"
2711 +#define PLAIN_WEBDAV_URL_SCHEME "webdav"
2712 +#define PLAIN_WEBDAVS_URL_SCHEME "webdavs"
2714 #define HTTP_CONTENT_TYPE \
2715 "application/" HTTP_URL_SCHEME "-content"
2717 --- unotools/source/ucbhelper/ucblockbytes.cxx.old 2009-04-02 10:57:40.000000000 +0000
2718 +++ unotools/source/ucbhelper/ucblockbytes.cxx 2009-04-06 16:41:46.000000000 +0000
2719 @@ -964,6 +964,10 @@ static sal_Bool UCBOpenContentSync(
2720 if( ! aScheme.equalsIgnoreAsciiCaseAscii("http") &&
2721 ! aScheme.equalsIgnoreAsciiCaseAscii("https") &&
2722 ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
2723 + ! aScheme.equalsIgnoreAsciiCaseAscii("dav") &&
2724 + ! aScheme.equalsIgnoreAsciiCaseAscii("davs") &&
2725 + ! aScheme.equalsIgnoreAsciiCaseAscii("webdav") &&
2726 + ! aScheme.equalsIgnoreAsciiCaseAscii("webdavs") &&
2727 ! aScheme.equalsIgnoreAsciiCaseAscii("ftp"))
2728 return _UCBOpenContentSync(
2729 xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
2730 @@ -1541,7 +1545,13 @@ ErrCode UcbLockBytes::Flush() const
2731 Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
2732 if ( !xOutputStream.is() )
2733 return ERRCODE_IO_CANTWRITE;
2734 - xOutputStream->flush();
2735 + try {
2736 + xOutputStream->flush();
2738 + catch (...)
2740 + return ERRCODE_IO_CANTWRITE;
2742 return ERRCODE_NONE;