Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : /**************************************************************************
31 : TODO
32 : **************************************************************************
33 :
34 : *************************************************************************/
35 :
36 : #include <comphelper/processfactory.hxx>
37 : #include <osl/diagnose.h>
38 : #include "osl/doublecheckedlocking.h"
39 : #include <rtl/uri.hxx>
40 : #include <rtl/ustrbuf.hxx>
41 : #include <ucbhelper/contentidentifier.hxx>
42 : #include <ucbhelper/propertyvalueset.hxx>
43 : #include <ucbhelper/simpleinteractionrequest.hxx>
44 : #include <ucbhelper/cancelcommandexecution.hxx>
45 :
46 : #include <com/sun/star/beans/PropertyAttribute.hpp>
47 : #include <com/sun/star/beans/PropertySetInfoChange.hpp>
48 : #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
49 : #include <com/sun/star/beans/PropertyValue.hpp>
50 : #include <com/sun/star/io/XActiveDataSink.hpp>
51 : #include <com/sun/star/io/XOutputStream.hpp>
52 : #include <com/sun/star/lang/IllegalAccessException.hpp>
53 : #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp>
54 : #include <com/sun/star/ucb/CommandEnvironment.hpp>
55 : #include <com/sun/star/ucb/CommandFailedException.hpp>
56 : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
57 : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
58 : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
59 : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
60 : #include "com/sun/star/ucb/InteractiveLockingLockedException.hpp"
61 : #include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp"
62 : #include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp"
63 : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
64 : #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
65 : #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
66 : #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
67 : #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
68 : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
69 : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
70 : #include <com/sun/star/ucb/NameClash.hpp>
71 : #include <com/sun/star/ucb/NameClashException.hpp>
72 : #include <com/sun/star/ucb/OpenCommandArgument3.hpp>
73 : #include <com/sun/star/ucb/OpenMode.hpp>
74 : #include <com/sun/star/ucb/PostCommandArgument2.hpp>
75 : #include <com/sun/star/ucb/TransferInfo.hpp>
76 : #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
77 : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
78 : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
79 : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
80 : #include <com/sun/star/ucb/XCommandInfo.hpp>
81 : #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
82 : #include <com/sun/star/uno/XComponentContext.hpp>
83 :
84 : #include "webdavcontent.hxx"
85 : #include "webdavprovider.hxx"
86 : #include "webdavresultset.hxx"
87 : #include "ContentProperties.hxx"
88 : #include "NeonUri.hxx"
89 : #include "UCBDeadPropertyValue.hxx"
90 :
91 : using namespace com::sun::star;
92 : using namespace webdav_ucp;
93 :
94 : //=========================================================================
95 : //=========================================================================
96 : //
97 : // Content Implementation.
98 : //
99 : //=========================================================================
100 : //=========================================================================
101 :
102 : //=========================================================================
103 : // ctr for content on an existing webdav resource
104 1 : Content::Content(
105 : const uno::Reference< uno::XComponentContext >& rxContext,
106 : ContentProvider* pProvider,
107 : const uno::Reference< ucb::XContentIdentifier >& Identifier,
108 : rtl::Reference< DAVSessionFactory > const & rSessionFactory )
109 : throw ( ucb::ContentCreationException )
110 : : ContentImplHelper( rxContext, pProvider, Identifier ),
111 : m_eResourceType( UNKNOWN ),
112 : m_pProvider( pProvider ),
113 : m_bTransient( false ),
114 : m_bCollection( false ),
115 1 : m_bDidGetOrHead( false )
116 : {
117 : try
118 : {
119 : m_xResAccess.reset( new DAVResourceAccess(
120 : rxContext,
121 : rSessionFactory,
122 1 : Identifier->getContentIdentifier() ) );
123 :
124 1 : NeonUri aURI( Identifier->getContentIdentifier() );
125 1 : m_aEscapedTitle = aURI.GetPathBaseName();
126 : }
127 0 : catch ( DAVException const & )
128 : {
129 0 : throw ucb::ContentCreationException();
130 : }
131 1 : }
132 :
133 : //=========================================================================
134 : // ctr for content on an non-existing webdav resource
135 0 : Content::Content(
136 : const uno::Reference< uno::XComponentContext >& rxContext,
137 : ContentProvider* pProvider,
138 : const uno::Reference< ucb::XContentIdentifier >& Identifier,
139 : rtl::Reference< DAVSessionFactory > const & rSessionFactory,
140 : sal_Bool isCollection )
141 : throw ( ucb::ContentCreationException )
142 : : ContentImplHelper( rxContext, pProvider, Identifier ),
143 : m_eResourceType( UNKNOWN ),
144 : m_pProvider( pProvider ),
145 : m_bTransient( true ),
146 : m_bCollection( isCollection ),
147 0 : m_bDidGetOrHead( false )
148 : {
149 : try
150 : {
151 : m_xResAccess.reset( new DAVResourceAccess(
152 0 : rxContext, rSessionFactory, Identifier->getContentIdentifier() ) );
153 : }
154 0 : catch ( DAVException const & )
155 : {
156 0 : throw ucb::ContentCreationException();
157 : }
158 :
159 : // Do not set m_aEscapedTitle here! Content::insert relays on this!!!
160 0 : }
161 :
162 : //=========================================================================
163 : // virtual
164 2 : Content::~Content()
165 : {
166 2 : }
167 :
168 : //=========================================================================
169 : //
170 : // XInterface methods.
171 : //
172 : //=========================================================================
173 :
174 : // virtual
175 15 : void SAL_CALL Content::acquire()
176 : throw( )
177 : {
178 15 : ContentImplHelper::acquire();
179 15 : }
180 :
181 : //=========================================================================
182 : // virtual
183 15 : void SAL_CALL Content::release()
184 : throw( )
185 : {
186 15 : ContentImplHelper::release();
187 15 : }
188 :
189 : //=========================================================================
190 : // virtual
191 4 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
192 : throw ( uno::RuntimeException )
193 : {
194 : // Note: isFolder may require network activities! So call it only
195 : // if it is really necessary!!!
196 : uno::Any aRet = cppu::queryInterface(
197 : rType,
198 4 : static_cast< ucb::XContentCreator * >( this ) );
199 4 : if ( aRet.hasValue() )
200 : {
201 : try
202 : {
203 : uno::Reference< task::XInteractionHandler > xIH(
204 0 : task::PasswordContainerInteractionHandler::create( m_xContext ) );
205 :
206 : // Supply a command env to isFolder() that contains an interaction
207 : // handler that uses the password container service to obtain
208 : // credentials without displaying a password gui.
209 :
210 : uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
211 : ucb::CommandEnvironment::create(
212 : m_xContext,
213 : xIH,
214 0 : uno::Reference< ucb::XProgressHandler >() ) );
215 :
216 0 : return isFolder( xCmdEnv ) ? aRet : uno::Any();
217 : }
218 0 : catch ( uno::RuntimeException const & )
219 : {
220 0 : throw;
221 : }
222 0 : catch ( uno::Exception const & )
223 : {
224 0 : return uno::Any();
225 : }
226 : }
227 4 : return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
228 : }
229 :
230 : //=========================================================================
231 : //
232 : // XTypeProvider methods.
233 : //
234 : //=========================================================================
235 :
236 0 : XTYPEPROVIDER_COMMON_IMPL( Content );
237 :
238 : //=========================================================================
239 : // virtual
240 0 : uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
241 : throw( uno::RuntimeException )
242 : {
243 0 : sal_Bool bFolder = sal_False;
244 : try
245 : {
246 : bFolder
247 0 : = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
248 : }
249 0 : catch ( uno::RuntimeException const & )
250 : {
251 0 : throw;
252 : }
253 0 : catch ( uno::Exception const & )
254 : {
255 : }
256 :
257 0 : cppu::OTypeCollection * pCollection = 0;
258 :
259 0 : if ( bFolder )
260 : {
261 : static cppu::OTypeCollection* pFolderTypes = 0;
262 :
263 0 : pCollection = pFolderTypes;
264 0 : if ( !pCollection )
265 : {
266 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
267 :
268 0 : pCollection = pFolderTypes;
269 0 : if ( !pCollection )
270 : {
271 : static cppu::OTypeCollection aCollection(
272 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
273 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
274 0 : CPPU_TYPE_REF( lang::XComponent ),
275 0 : CPPU_TYPE_REF( ucb::XContent ),
276 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
277 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
278 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
279 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
280 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
281 0 : CPPU_TYPE_REF( container::XChild ),
282 0 : CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
283 0 : pCollection = &aCollection;
284 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
285 0 : pFolderTypes = pCollection;
286 0 : }
287 : }
288 : else {
289 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
290 : }
291 : }
292 : else
293 : {
294 : static cppu::OTypeCollection* pDocumentTypes = 0;
295 :
296 0 : pCollection = pDocumentTypes;
297 0 : if ( !pCollection )
298 : {
299 0 : osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
300 :
301 0 : pCollection = pDocumentTypes;
302 0 : if ( !pCollection )
303 : {
304 : static cppu::OTypeCollection aCollection(
305 0 : CPPU_TYPE_REF( lang::XTypeProvider ),
306 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
307 0 : CPPU_TYPE_REF( lang::XComponent ),
308 0 : CPPU_TYPE_REF( ucb::XContent ),
309 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
310 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
311 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
312 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
313 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
314 0 : CPPU_TYPE_REF( container::XChild ) );
315 0 : pCollection = &aCollection;
316 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
317 0 : pDocumentTypes = pCollection;
318 0 : }
319 : }
320 : else {
321 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
322 : }
323 : }
324 :
325 0 : return (*pCollection).getTypes();
326 : }
327 :
328 : //=========================================================================
329 : //
330 : // XServiceInfo methods.
331 : //
332 : //=========================================================================
333 :
334 : // virtual
335 0 : OUString SAL_CALL Content::getImplementationName()
336 : throw( uno::RuntimeException )
337 : {
338 0 : return OUString( "com.sun.star.comp.ucb.WebDAVContent" );
339 : }
340 :
341 : //=========================================================================
342 : // virtual
343 0 : uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
344 : throw( uno::RuntimeException )
345 : {
346 0 : uno::Sequence< OUString > aSNS( 1 );
347 : aSNS.getArray()[ 0 ]
348 0 : = OUString( WEBDAV_CONTENT_SERVICE_NAME );
349 0 : return aSNS;
350 : }
351 :
352 : //=========================================================================
353 : //
354 : // XContent methods.
355 : //
356 : //=========================================================================
357 :
358 : // virtual
359 0 : OUString SAL_CALL Content::getContentType()
360 : throw( uno::RuntimeException )
361 : {
362 0 : sal_Bool bFolder = sal_False;
363 : try
364 : {
365 : bFolder
366 0 : = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
367 : }
368 0 : catch ( uno::RuntimeException const & )
369 : {
370 0 : throw;
371 : }
372 0 : catch ( uno::Exception const & )
373 : {
374 : }
375 :
376 0 : if ( bFolder )
377 0 : return OUString( WEBDAV_COLLECTION_TYPE );
378 :
379 0 : return OUString( WEBDAV_CONTENT_TYPE );
380 : }
381 :
382 : //=========================================================================
383 : //
384 : // XCommandProcessor methods.
385 : //
386 : //=========================================================================
387 :
388 : // virtual
389 0 : uno::Any SAL_CALL Content::execute(
390 : const ucb::Command& aCommand,
391 : sal_Int32 /*CommandId*/,
392 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
393 : throw( uno::Exception,
394 : ucb::CommandAbortedException,
395 : uno::RuntimeException )
396 : {
397 : SAL_INFO( "ucb.ucp.webdav", "Content::execute: start: command: " <<
398 : aCommand.Name << ", env: " <<
399 : (Environment.is() ? "present" : "missing") );
400 :
401 0 : uno::Any aRet;
402 :
403 0 : if ( aCommand.Name == "getPropertyValues" )
404 : {
405 : //////////////////////////////////////////////////////////////////
406 : // getPropertyValues
407 : //////////////////////////////////////////////////////////////////
408 :
409 0 : uno::Sequence< beans::Property > Properties;
410 0 : if ( !( aCommand.Argument >>= Properties ) )
411 : {
412 : ucbhelper::cancelCommandExecution(
413 : uno::makeAny( lang::IllegalArgumentException(
414 : OUString( "Wrong argument type!" ),
415 : static_cast< cppu::OWeakObject * >( this ),
416 : -1 ) ),
417 0 : Environment );
418 : // Unreachable
419 : }
420 :
421 0 : aRet <<= getPropertyValues( Properties, Environment );
422 : }
423 0 : else if ( aCommand.Name == "setPropertyValues" )
424 : {
425 : //////////////////////////////////////////////////////////////////
426 : // setPropertyValues
427 : //////////////////////////////////////////////////////////////////
428 :
429 0 : uno::Sequence< beans::PropertyValue > aProperties;
430 0 : if ( !( aCommand.Argument >>= aProperties ) )
431 : {
432 : ucbhelper::cancelCommandExecution(
433 : uno::makeAny( lang::IllegalArgumentException(
434 : OUString( "Wrong argument type!" ),
435 : static_cast< cppu::OWeakObject * >( this ),
436 : -1 ) ),
437 0 : Environment );
438 : // Unreachable
439 : }
440 :
441 0 : if ( !aProperties.getLength() )
442 : {
443 : ucbhelper::cancelCommandExecution(
444 : uno::makeAny( lang::IllegalArgumentException(
445 : OUString( "No properties!" ),
446 : static_cast< cppu::OWeakObject * >( this ),
447 : -1 ) ),
448 0 : Environment );
449 : // Unreachable
450 : }
451 :
452 0 : aRet <<= setPropertyValues( aProperties, Environment );
453 : }
454 0 : else if ( aCommand.Name == "getPropertySetInfo" )
455 : {
456 : //////////////////////////////////////////////////////////////////
457 : // getPropertySetInfo
458 : //////////////////////////////////////////////////////////////////
459 :
460 : // Note: Implemented by base class.
461 0 : aRet <<= getPropertySetInfo( Environment,
462 0 : sal_False /* don't cache data */ );
463 : }
464 0 : else if ( aCommand.Name == "getCommandInfo" )
465 : {
466 : //////////////////////////////////////////////////////////////////
467 : // getCommandInfo
468 : //////////////////////////////////////////////////////////////////
469 :
470 : // Note: Implemented by base class.
471 0 : aRet <<= getCommandInfo( Environment, sal_False );
472 : }
473 0 : else if ( aCommand.Name == "open" )
474 : {
475 : //////////////////////////////////////////////////////////////////
476 : // open
477 : //////////////////////////////////////////////////////////////////
478 :
479 0 : ucb::OpenCommandArgument3 aOpenCommand;
480 0 : ucb::OpenCommandArgument2 aTmp;
481 0 : if ( !( aCommand.Argument >>= aTmp ) )
482 : {
483 : ucbhelper::cancelCommandExecution(
484 : uno::makeAny( lang::IllegalArgumentException(
485 : OUString( "Wrong argument type!" ),
486 : static_cast< cppu::OWeakObject * >( this ),
487 : -1 ) ),
488 0 : Environment );
489 : // Unreachable
490 : }
491 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
492 : {
493 : // compat mode, extract Arg2 info into newer structure
494 0 : aOpenCommand.Mode = aTmp.Mode;
495 0 : aOpenCommand.Priority = aTmp.Priority;
496 0 : aOpenCommand.Sink = aTmp.Sink;
497 0 : aOpenCommand.Properties = aTmp.Properties;
498 0 : aOpenCommand.SortingInfo = aTmp.SortingInfo;
499 : }
500 :
501 0 : aRet = open( aOpenCommand, Environment );
502 :
503 0 : if ( (aOpenCommand.Mode == ucb::OpenMode::DOCUMENT ||
504 0 : aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE) &&
505 0 : supportsExclusiveWriteLock( Environment ) )
506 0 : lock( Environment );
507 : }
508 0 : else if ( aCommand.Name == "insert" )
509 : {
510 : //////////////////////////////////////////////////////////////////
511 : // insert
512 : //////////////////////////////////////////////////////////////////
513 :
514 0 : ucb::InsertCommandArgument arg;
515 0 : if ( !( aCommand.Argument >>= arg ) )
516 : {
517 : ucbhelper::cancelCommandExecution(
518 : uno::makeAny( lang::IllegalArgumentException(
519 : OUString( "Wrong argument type!" ),
520 : static_cast< cppu::OWeakObject * >( this ),
521 : -1 ) ),
522 0 : Environment );
523 : // Unreachable
524 : }
525 :
526 0 : insert( arg.Data, arg.ReplaceExisting, Environment );
527 : }
528 0 : else if ( aCommand.Name == "delete" )
529 : {
530 : //////////////////////////////////////////////////////////////////
531 : // delete
532 : //////////////////////////////////////////////////////////////////
533 :
534 0 : sal_Bool bDeletePhysical = sal_False;
535 0 : aCommand.Argument >>= bDeletePhysical;
536 :
537 : // KSO: Ignore parameter and destroy the content, if you don't support
538 : // putting objects into trashcan. ( Since we do not have a trash can
539 : // service yet (src603), you actually have no other choice. )
540 : // if ( bDeletePhysical )
541 : // {
542 : try
543 : {
544 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
545 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
546 : SAL_WNODEPRECATED_DECLARATIONS_POP
547 : {
548 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
549 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
550 : }
551 0 : xResAccess->DESTROY( Environment );
552 : {
553 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
554 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
555 0 : }
556 : }
557 0 : catch ( DAVException const & e )
558 : {
559 0 : cancelCommandExecution( e, Environment, sal_True );
560 : // Unreachable
561 : }
562 : // }
563 :
564 : // Propagate destruction.
565 0 : destroy( bDeletePhysical );
566 :
567 : // Remove own and all children's Additional Core Properties.
568 0 : removeAdditionalPropertySet( sal_True );
569 : }
570 0 : else if ( aCommand.Name == "transfer" && isFolder( Environment ) )
571 : {
572 : //////////////////////////////////////////////////////////////////
573 : // transfer
574 : // ( Not available at documents )
575 : //////////////////////////////////////////////////////////////////
576 :
577 0 : ucb::TransferInfo transferArgs;
578 0 : if ( !( aCommand.Argument >>= transferArgs ) )
579 : {
580 : ucbhelper::cancelCommandExecution(
581 : uno::makeAny( lang::IllegalArgumentException(
582 : OUString( "Wrong argument type!" ),
583 : static_cast< cppu::OWeakObject * >( this ),
584 : -1 ) ),
585 0 : Environment );
586 : // Unreachable
587 : }
588 :
589 0 : transfer( transferArgs, Environment );
590 : }
591 0 : else if ( aCommand.Name == "post" )
592 : {
593 : //////////////////////////////////////////////////////////////////
594 : // post
595 : //////////////////////////////////////////////////////////////////
596 :
597 0 : ucb::PostCommandArgument2 aArg;
598 0 : if ( !( aCommand.Argument >>= aArg ) )
599 : {
600 : ucbhelper::cancelCommandExecution(
601 : uno::makeAny( lang::IllegalArgumentException(
602 : OUString( "Wrong argument type!" ),
603 : static_cast< cppu::OWeakObject * >( this ),
604 : -1 ) ),
605 0 : Environment );
606 : // Unreachable
607 : }
608 :
609 0 : post( aArg, Environment );
610 : }
611 0 : else if ( aCommand.Name == "lock" && supportsExclusiveWriteLock( Environment ) )
612 : {
613 : //////////////////////////////////////////////////////////////////
614 : // lock
615 : //////////////////////////////////////////////////////////////////
616 :
617 0 : lock( Environment );
618 : }
619 0 : else if ( aCommand.Name == "unlock" && supportsExclusiveWriteLock( Environment ) )
620 : {
621 : //////////////////////////////////////////////////////////////////
622 : // unlock
623 : //////////////////////////////////////////////////////////////////
624 :
625 0 : unlock( Environment );
626 : }
627 0 : else if ( aCommand.Name == "createNewContent" && isFolder( Environment ) )
628 : {
629 : //////////////////////////////////////////////////////////////////
630 : // createNewContent
631 : //////////////////////////////////////////////////////////////////
632 :
633 0 : ucb::ContentInfo aArg;
634 0 : if ( !( aCommand.Argument >>= aArg ) )
635 : {
636 : ucbhelper::cancelCommandExecution(
637 : uno::makeAny( lang::IllegalArgumentException(
638 : OUString( "Wrong argument type!" ),
639 : static_cast< cppu::OWeakObject * >( this ),
640 : -1 ) ),
641 0 : Environment );
642 : // Unreachable
643 : }
644 :
645 0 : aRet = uno::makeAny( createNewContent( aArg ) );
646 : }
647 : else
648 : {
649 : //////////////////////////////////////////////////////////////////
650 : // Unsupported command
651 : //////////////////////////////////////////////////////////////////
652 :
653 : ucbhelper::cancelCommandExecution(
654 : uno::makeAny( ucb::UnsupportedCommandException(
655 : aCommand.Name,
656 : static_cast< cppu::OWeakObject * >( this ) ) ),
657 0 : Environment );
658 : // Unreachable
659 : }
660 :
661 : OSL_TRACE( "<<<<< Content::execute: end: command: %s",
662 : OUStringToOString( aCommand.Name,
663 : RTL_TEXTENCODING_UTF8 ).getStr() );
664 :
665 0 : return aRet;
666 : }
667 :
668 : //=========================================================================
669 : // virtual
670 0 : void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
671 : throw( uno::RuntimeException )
672 : {
673 : try
674 : {
675 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
676 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
677 : SAL_WNODEPRECATED_DECLARATIONS_POP
678 : {
679 0 : osl::MutexGuard aGuard( m_aMutex );
680 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
681 : }
682 0 : xResAccess->abort();
683 : {
684 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
685 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
686 0 : }
687 : }
688 0 : catch ( DAVException const & )
689 : {
690 : // abort failed!
691 : }
692 0 : }
693 :
694 : //=========================================================================
695 : //
696 : // XPropertyContainer methods.
697 : //
698 : //=========================================================================
699 :
700 : // virtual
701 0 : void SAL_CALL Content::addProperty( const OUString& Name,
702 : sal_Int16 Attributes,
703 : const uno::Any& DefaultValue )
704 : throw( beans::PropertyExistException,
705 : beans::IllegalTypeException,
706 : lang::IllegalArgumentException,
707 : uno::RuntimeException )
708 : {
709 : // if ( m_bTransient )
710 : // @@@ ???
711 :
712 0 : if ( Name.isEmpty() )
713 0 : throw lang::IllegalArgumentException();
714 :
715 : // Check property type.
716 0 : if ( !UCBDeadPropertyValue::supportsType( DefaultValue.getValueType() ) )
717 : {
718 : OSL_FAIL( "Content::addProperty - Unsupported property type!" );
719 0 : throw beans::IllegalTypeException();
720 : }
721 :
722 : //////////////////////////////////////////////////////////////////////
723 : // Make sure a property with the requested name does not already
724 : // exist in dynamic and static(!) properties.
725 : //////////////////////////////////////////////////////////////////////
726 :
727 : // @@@ Need real command environment here, but where to get it from?
728 : // XPropertyContainer interface should be replaced by
729 : // XCommandProcessor commands!
730 0 : uno::Reference< ucb::XCommandEnvironment > xEnv;
731 :
732 : // Note: This requires network access!
733 0 : if ( getPropertySetInfo( xEnv, sal_False /* don't cache data */ )
734 0 : ->hasPropertyByName( Name ) )
735 : {
736 : // Property does already exist.
737 0 : throw beans::PropertyExistException();
738 : }
739 :
740 : //////////////////////////////////////////////////////////////////////
741 : // Add a new dynamic property.
742 : //////////////////////////////////////////////////////////////////////
743 :
744 0 : ProppatchValue aValue( PROPSET, Name, DefaultValue );
745 :
746 0 : std::vector< ProppatchValue > aProppatchValues;
747 0 : aProppatchValues.push_back( aValue );
748 :
749 : try
750 : {
751 : // Set property value at server.
752 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
753 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
754 : SAL_WNODEPRECATED_DECLARATIONS_POP
755 : {
756 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
757 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
758 : }
759 0 : xResAccess->PROPPATCH( aProppatchValues, xEnv );
760 : {
761 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
762 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
763 : }
764 :
765 : // Notify propertyset info change listeners.
766 : beans::PropertySetInfoChangeEvent evt(
767 : static_cast< cppu::OWeakObject * >( this ),
768 : Name,
769 : -1, // No handle available
770 0 : beans::PropertySetInfoChange::PROPERTY_INSERTED );
771 0 : notifyPropertySetInfoChange( evt );
772 : }
773 0 : catch ( DAVException const & e )
774 : {
775 0 : if ( e.getStatus() == SC_FORBIDDEN )
776 : {
777 : // Support for setting arbitrary dead properties is optional!
778 :
779 : // Store property locally.
780 : ContentImplHelper::addProperty(
781 0 : Name, Attributes, DefaultValue );
782 : }
783 : else
784 : {
785 0 : if ( shouldAccessNetworkAfterException( e ) )
786 : {
787 : try
788 : {
789 0 : ResourceType eType = getResourceType( xEnv );
790 0 : switch ( eType )
791 : {
792 : case UNKNOWN:
793 : case DAV:
794 0 : throw lang::IllegalArgumentException();
795 :
796 : case FTP:
797 : case NON_DAV:
798 : // Store property locally.
799 : ContentImplHelper::addProperty( Name,
800 : Attributes,
801 0 : DefaultValue );
802 0 : break;
803 :
804 : default:
805 : OSL_FAIL( "Content::addProperty - "
806 : "Unsupported resource type!" );
807 0 : break;
808 : }
809 : }
810 0 : catch ( uno::Exception const & )
811 : {
812 : OSL_FAIL( "Content::addProperty - "
813 : "Unable to determine resource type!" );
814 : }
815 : }
816 : else
817 : {
818 : OSL_FAIL( "Content::addProperty - "
819 : "Unable to determine resource type!" );
820 : }
821 : }
822 0 : }
823 0 : }
824 :
825 : //=========================================================================
826 : // virtual
827 0 : void SAL_CALL Content::removeProperty( const OUString& Name )
828 : throw( beans::UnknownPropertyException,
829 : beans::NotRemoveableException,
830 : uno::RuntimeException )
831 : {
832 : // @@@ Need real command environment here, but where to get it from?
833 : // XPropertyContainer interface should be replaced by
834 : // XCommandProcessor commands!
835 0 : uno::Reference< ucb::XCommandEnvironment > xEnv;
836 :
837 : //////////////////////////////////////////////////////////////////////
838 : // Try to remove property from server.
839 : //////////////////////////////////////////////////////////////////////
840 :
841 : try
842 : {
843 0 : std::vector< ProppatchValue > aProppatchValues;
844 0 : ProppatchValue aValue( PROPREMOVE, Name, uno::Any() );
845 0 : aProppatchValues.push_back( aValue );
846 :
847 : // Remove property value from server.
848 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
849 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
850 : SAL_WNODEPRECATED_DECLARATIONS_POP
851 : {
852 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
853 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
854 : }
855 0 : xResAccess->PROPPATCH( aProppatchValues, xEnv );
856 : {
857 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
858 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
859 : }
860 :
861 : // Notify propertyset info change listeners.
862 : beans::PropertySetInfoChangeEvent evt(
863 : static_cast< cppu::OWeakObject * >( this ),
864 : Name,
865 : -1, // No handle available
866 0 : beans::PropertySetInfoChange::PROPERTY_REMOVED );
867 0 : notifyPropertySetInfoChange( evt );
868 : }
869 0 : catch ( DAVException const & e )
870 : {
871 0 : if ( e.getStatus() == SC_FORBIDDEN )
872 : {
873 : // Support for setting arbitrary dead properties is optional!
874 :
875 : // Try to remove property from local store.
876 0 : ContentImplHelper::removeProperty( Name );
877 : }
878 : else
879 : {
880 0 : if ( shouldAccessNetworkAfterException( e ) )
881 : {
882 : try
883 : {
884 0 : ResourceType eType = getResourceType( xEnv );
885 0 : switch ( eType )
886 : {
887 : case UNKNOWN:
888 : case DAV:
889 0 : throw beans::UnknownPropertyException();
890 :
891 : case FTP:
892 : case NON_DAV:
893 : // Try to remove property from local store.
894 0 : ContentImplHelper::removeProperty( Name );
895 0 : break;
896 :
897 : default:
898 : OSL_FAIL( "Content::removeProperty - "
899 : "Unsupported resource type!" );
900 0 : break;
901 : }
902 : }
903 0 : catch ( uno::Exception const & )
904 : {
905 : OSL_FAIL( "Content::removeProperty - "
906 : "Unable to determine resource type!" );
907 : }
908 : }
909 : else
910 : {
911 : OSL_FAIL( "Content::removeProperty - "
912 : "Unable to determine resource type!" );
913 : // throw beans::UnknownPropertyException();
914 : }
915 : }
916 0 : }
917 0 : }
918 :
919 : //=========================================================================
920 : //
921 : // XContentCreator methods.
922 : //
923 : //=========================================================================
924 :
925 : // virtual
926 : uno::Sequence< ucb::ContentInfo > SAL_CALL
927 0 : Content::queryCreatableContentsInfo()
928 : throw( uno::RuntimeException )
929 : {
930 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
931 :
932 0 : uno::Sequence< ucb::ContentInfo > aSeq( 2 );
933 :
934 : // document.
935 0 : aSeq.getArray()[ 0 ].Type
936 0 : = OUString( WEBDAV_CONTENT_TYPE );
937 0 : aSeq.getArray()[ 0 ].Attributes
938 : = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
939 0 : | ucb::ContentInfoAttribute::KIND_DOCUMENT;
940 :
941 0 : beans::Property aProp;
942 : m_pProvider->getProperty(
943 0 : OUString( "Title" ), aProp );
944 :
945 0 : uno::Sequence< beans::Property > aDocProps( 1 );
946 0 : aDocProps.getArray()[ 0 ] = aProp;
947 0 : aSeq.getArray()[ 0 ].Properties = aDocProps;
948 :
949 : // folder.
950 0 : aSeq.getArray()[ 1 ].Type
951 0 : = OUString( WEBDAV_COLLECTION_TYPE );
952 0 : aSeq.getArray()[ 1 ].Attributes
953 0 : = ucb::ContentInfoAttribute::KIND_FOLDER;
954 :
955 0 : uno::Sequence< beans::Property > aFolderProps( 1 );
956 0 : aFolderProps.getArray()[ 0 ] = aProp;
957 0 : aSeq.getArray()[ 1 ].Properties = aFolderProps;
958 0 : return aSeq;
959 : }
960 :
961 : //=========================================================================
962 : // virtual
963 : uno::Reference< ucb::XContent > SAL_CALL
964 0 : Content::createNewContent( const ucb::ContentInfo& Info )
965 : throw( uno::RuntimeException )
966 : {
967 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
968 :
969 0 : if ( Info.Type.isEmpty() )
970 0 : return uno::Reference< ucb::XContent >();
971 :
972 0 : if ( ( Info.Type != WEBDAV_COLLECTION_TYPE ) && ( Info.Type != WEBDAV_CONTENT_TYPE ) )
973 0 : return uno::Reference< ucb::XContent >();
974 :
975 0 : OUString aURL = m_xIdentifier->getContentIdentifier();
976 :
977 : OSL_ENSURE( !aURL.isEmpty(),
978 : "WebdavContent::createNewContent - empty identifier!" );
979 :
980 0 : if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
981 0 : aURL += OUString("/");
982 :
983 : sal_Bool isCollection;
984 0 : if ( Info.Type == WEBDAV_COLLECTION_TYPE )
985 : {
986 0 : aURL += OUString("New_Collection");
987 0 : isCollection = sal_True;
988 : }
989 : else
990 : {
991 0 : aURL += OUString("New_Content");
992 0 : isCollection = sal_False;
993 : }
994 :
995 : uno::Reference< ucb::XContentIdentifier > xId(
996 0 : new ::ucbhelper::ContentIdentifier( aURL ) );
997 :
998 : // create the local content
999 : try
1000 : {
1001 : return new ::webdav_ucp::Content( m_xContext,
1002 : m_pProvider,
1003 : xId,
1004 : m_xResAccess->getSessionFactory(),
1005 0 : isCollection );
1006 : }
1007 0 : catch ( ucb::ContentCreationException & )
1008 : {
1009 0 : return uno::Reference< ucb::XContent >();
1010 0 : }
1011 : }
1012 :
1013 : //=========================================================================
1014 : // virtual
1015 0 : OUString Content::getParentURL()
1016 : {
1017 : // <scheme>:// -> ""
1018 : // <scheme>://foo -> ""
1019 : // <scheme>://foo/ -> ""
1020 : // <scheme>://foo/bar -> <scheme>://foo/
1021 : // <scheme>://foo/bar/ -> <scheme>://foo/
1022 : // <scheme>://foo/bar/abc -> <scheme>://foo/bar/
1023 :
1024 0 : OUString aURL = m_xIdentifier->getContentIdentifier();
1025 :
1026 0 : sal_Int32 nPos = aURL.lastIndexOf( '/' );
1027 0 : if ( nPos == ( aURL.getLength() - 1 ) )
1028 : {
1029 : // Trailing slash found. Skip.
1030 0 : nPos = aURL.lastIndexOf( '/', nPos );
1031 : }
1032 :
1033 0 : sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
1034 0 : if ( nPos1 != -1 )
1035 0 : nPos1 = aURL.lastIndexOf( '/', nPos1 );
1036 :
1037 0 : if ( nPos1 == -1 )
1038 0 : return OUString();
1039 :
1040 0 : return OUString( aURL.copy( 0, nPos + 1 ) );
1041 : }
1042 :
1043 : //=========================================================================
1044 : //
1045 : // Non-interface methods.
1046 : //
1047 : //=========================================================================
1048 :
1049 : // static
1050 0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
1051 : const uno::Reference< uno::XComponentContext >& rxContext,
1052 : const uno::Sequence< beans::Property >& rProperties,
1053 : const ContentProperties& rData,
1054 : const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
1055 : const OUString& rContentId )
1056 : {
1057 : // Note: Empty sequence means "get values of all supported properties".
1058 :
1059 : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
1060 0 : = new ::ucbhelper::PropertyValueSet( rxContext );
1061 :
1062 0 : sal_Int32 nCount = rProperties.getLength();
1063 0 : if ( nCount )
1064 : {
1065 0 : uno::Reference< beans::XPropertySet > xAdditionalPropSet;
1066 0 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1067 :
1068 0 : const beans::Property* pProps = rProperties.getConstArray();
1069 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1070 : {
1071 0 : const beans::Property& rProp = pProps[ n ];
1072 :
1073 : // Process standard UCB, DAV and HTTP properties.
1074 0 : const uno::Any & rValue = rData.getValue( rProp.Name );
1075 0 : if ( rValue.hasValue() )
1076 : {
1077 0 : xRow->appendObject( rProp, rValue );
1078 : }
1079 : else
1080 : {
1081 : // Process local Additional Properties.
1082 0 : if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
1083 : {
1084 : xAdditionalPropSet
1085 0 : = uno::Reference< beans::XPropertySet >(
1086 : rProvider->getAdditionalPropertySet( rContentId,
1087 : sal_False ),
1088 0 : uno::UNO_QUERY );
1089 0 : bTriedToGetAdditonalPropSet = sal_True;
1090 : }
1091 :
1092 0 : if ( !xAdditionalPropSet.is() ||
1093 : !xRow->appendPropertySetValue(
1094 0 : xAdditionalPropSet, rProp ) )
1095 : {
1096 : // Append empty entry.
1097 0 : xRow->appendVoid( rProp );
1098 : }
1099 : }
1100 0 : }
1101 : }
1102 : else
1103 : {
1104 : // Append all standard UCB, DAV and HTTP properties.
1105 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1106 0 : const std::auto_ptr< PropertyValueMap > & xProps = rData.getProperties();
1107 : SAL_WNODEPRECATED_DECLARATIONS_POP
1108 :
1109 0 : PropertyValueMap::const_iterator it = xProps->begin();
1110 0 : PropertyValueMap::const_iterator end = xProps->end();
1111 :
1112 : ContentProvider * pProvider
1113 0 : = static_cast< ContentProvider * >( rProvider.get() );
1114 0 : beans::Property aProp;
1115 :
1116 0 : while ( it != end )
1117 : {
1118 0 : if ( pProvider->getProperty( (*it).first, aProp ) )
1119 0 : xRow->appendObject( aProp, (*it).second.value() );
1120 :
1121 0 : ++it;
1122 : }
1123 :
1124 : // Append all local Additional Properties.
1125 : uno::Reference< beans::XPropertySet > xSet(
1126 : rProvider->getAdditionalPropertySet( rContentId, sal_False ),
1127 0 : uno::UNO_QUERY );
1128 0 : xRow->appendPropertySet( xSet );
1129 : }
1130 :
1131 0 : return uno::Reference< sdbc::XRow >( xRow.get() );
1132 : }
1133 :
1134 : //=========================================================================
1135 0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
1136 : const uno::Sequence< beans::Property >& rProperties,
1137 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1138 : throw ( uno::Exception )
1139 : {
1140 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1141 0 : std::auto_ptr< ContentProperties > xProps;
1142 0 : std::auto_ptr< ContentProperties > xCachedProps;
1143 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
1144 : SAL_WNODEPRECATED_DECLARATIONS_POP
1145 0 : OUString aUnescapedTitle;
1146 0 : bool bHasAll = false;
1147 0 : uno::Reference< ucb::XContentIdentifier > xIdentifier;
1148 0 : rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
1149 :
1150 : {
1151 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1152 :
1153 0 : aUnescapedTitle = NeonUri::unescape( m_aEscapedTitle );
1154 0 : xIdentifier.set( m_xIdentifier );
1155 0 : xProvider.set( m_xProvider.get() );
1156 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1157 :
1158 : // First, ask cache...
1159 0 : if ( m_xCachedProps.get() )
1160 : {
1161 0 : xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
1162 :
1163 0 : std::vector< OUString > aMissingProps;
1164 0 : if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) )
1165 : {
1166 : // All properties are already in cache! No server access needed.
1167 0 : bHasAll = true;
1168 : }
1169 :
1170 : // use the cached ContentProperties instance
1171 0 : xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1172 0 : }
1173 : }
1174 :
1175 0 : if ( !m_bTransient && !bHasAll )
1176 : {
1177 : /////////////////////////////////////////////////////////////////////
1178 : // Obtain values from server...
1179 : /////////////////////////////////////////////////////////////////////
1180 :
1181 : // First, identify whether resource is DAV or not
1182 0 : bool bNetworkAccessAllowed = true;
1183 : ResourceType eType = getResourceType(
1184 0 : xEnv, xResAccess, &bNetworkAccessAllowed );
1185 :
1186 0 : if ( eType == DAV )
1187 : {
1188 : // cache lookup... getResourceType may fill the props cache via
1189 : // PROPFIND!
1190 0 : if ( m_xCachedProps.get() )
1191 : {
1192 : xCachedProps.reset(
1193 0 : new ContentProperties( *m_xCachedProps.get() ) );
1194 :
1195 0 : std::vector< OUString > aMissingProps;
1196 0 : if ( xCachedProps->containsAllNames(
1197 0 : rProperties, aMissingProps ) )
1198 : {
1199 : // All properties are already in cache! No server access
1200 : // needed.
1201 0 : bHasAll = true;
1202 : }
1203 :
1204 : // use the cached ContentProperties instance
1205 0 : xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1206 : }
1207 :
1208 0 : if ( !bHasAll )
1209 : {
1210 : // Only DAV resources support PROPFIND
1211 0 : std::vector< OUString > aPropNames;
1212 :
1213 : uno::Sequence< beans::Property > aProperties(
1214 0 : rProperties.getLength() );
1215 :
1216 0 : if ( !m_aFailedPropNames.empty() )
1217 : {
1218 0 : sal_Int32 nProps = 0;
1219 0 : sal_Int32 nCount = rProperties.getLength();
1220 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1221 : {
1222 0 : const OUString & rName = rProperties[ n ].Name;
1223 :
1224 : std::vector< OUString >::const_iterator it
1225 0 : = m_aFailedPropNames.begin();
1226 : std::vector< OUString >::const_iterator end
1227 0 : = m_aFailedPropNames.end();
1228 :
1229 0 : while ( it != end )
1230 : {
1231 0 : if ( *it == rName )
1232 0 : break;
1233 :
1234 0 : ++it;
1235 : }
1236 :
1237 0 : if ( it == end )
1238 : {
1239 0 : aProperties[ nProps ] = rProperties[ n ];
1240 0 : nProps++;
1241 : }
1242 : }
1243 :
1244 0 : aProperties.realloc( nProps );
1245 : }
1246 : else
1247 : {
1248 0 : aProperties = rProperties;
1249 : }
1250 :
1251 0 : if ( aProperties.getLength() > 0 )
1252 : ContentProperties::UCBNamesToDAVNames(
1253 0 : aProperties, aPropNames );
1254 :
1255 0 : if ( !aPropNames.empty() )
1256 : {
1257 0 : std::vector< DAVResource > resources;
1258 : try
1259 : {
1260 : xResAccess->PROPFIND(
1261 0 : DAVZERO, aPropNames, resources, xEnv );
1262 :
1263 0 : if ( 1 == resources.size() )
1264 : {
1265 0 : if ( xProps.get())
1266 : xProps->addProperties(
1267 : aPropNames,
1268 0 : ContentProperties( resources[ 0 ] ));
1269 : else
1270 : xProps.reset(
1271 0 : new ContentProperties( resources[ 0 ] ) );
1272 : }
1273 : }
1274 0 : catch ( DAVException const & e )
1275 : {
1276 : bNetworkAccessAllowed = bNetworkAccessAllowed
1277 0 : && shouldAccessNetworkAfterException( e );
1278 :
1279 0 : if ( !bNetworkAccessAllowed )
1280 : {
1281 0 : cancelCommandExecution( e, xEnv );
1282 : // unreachable
1283 : }
1284 0 : }
1285 0 : }
1286 : }
1287 : }
1288 :
1289 0 : if ( bNetworkAccessAllowed )
1290 : {
1291 : // All properties obtained already?
1292 0 : std::vector< OUString > aMissingProps;
1293 0 : if ( !( xProps.get()
1294 : && xProps->containsAllNames(
1295 0 : rProperties, aMissingProps ) )
1296 0 : && !m_bDidGetOrHead )
1297 : {
1298 : // Possibly the missing props can be obtained using a HEAD
1299 : // request.
1300 :
1301 0 : std::vector< OUString > aHeaderNames;
1302 : ContentProperties::UCBNamesToHTTPNames(
1303 : rProperties,
1304 : aHeaderNames,
1305 0 : true /* bIncludeUnmatched */ );
1306 :
1307 0 : if ( !aHeaderNames.empty() )
1308 : {
1309 : try
1310 : {
1311 0 : DAVResource resource;
1312 0 : xResAccess->HEAD( aHeaderNames, resource, xEnv );
1313 0 : m_bDidGetOrHead = true;
1314 :
1315 0 : if ( xProps.get() )
1316 : xProps->addProperties(
1317 : aMissingProps,
1318 0 : ContentProperties( resource ) );
1319 : else
1320 0 : xProps.reset ( new ContentProperties( resource ) );
1321 :
1322 0 : if ( m_eResourceType == NON_DAV )
1323 : xProps->addProperties( aMissingProps,
1324 : ContentProperties(
1325 : aUnescapedTitle,
1326 0 : false ) );
1327 : }
1328 0 : catch ( DAVException const & e )
1329 : {
1330 : bNetworkAccessAllowed
1331 0 : = shouldAccessNetworkAfterException( e );
1332 :
1333 0 : if ( !bNetworkAccessAllowed )
1334 : {
1335 0 : cancelCommandExecution( e, xEnv );
1336 : // unreachable
1337 : }
1338 : }
1339 0 : }
1340 0 : }
1341 : }
1342 :
1343 : // might trigger HTTP redirect.
1344 : // Therefore, title must be updated here.
1345 0 : NeonUri aUri( xResAccess->getURL() );
1346 0 : aUnescapedTitle = aUri.GetPathBaseNameUnescaped();
1347 :
1348 0 : if ( eType == UNKNOWN )
1349 : {
1350 0 : xProps.reset( new ContentProperties( aUnescapedTitle ) );
1351 : }
1352 :
1353 : // For DAV resources we only know the Title, for non-DAV
1354 : // resources we additionally know that it is a document.
1355 :
1356 0 : if ( eType == DAV )
1357 : {
1358 : //xProps.reset(
1359 : // new ContentProperties( aUnescapedTitle ) );
1360 : xProps->addProperty(
1361 : OUString( "Title" ),
1362 : uno::makeAny( aUnescapedTitle ),
1363 0 : true );
1364 : }
1365 : else
1366 : {
1367 0 : if ( !xProps.get() )
1368 0 : xProps.reset( new ContentProperties( aUnescapedTitle, false ) );
1369 : else
1370 : xProps->addProperty(
1371 : OUString( "Title" ),
1372 : uno::makeAny( aUnescapedTitle ),
1373 0 : true );
1374 :
1375 : xProps->addProperty(
1376 : OUString( "IsFolder" ),
1377 : uno::makeAny( false ),
1378 0 : true );
1379 : xProps->addProperty(
1380 : OUString( "IsDocument" ),
1381 : uno::makeAny( true ),
1382 0 : true );
1383 0 : }
1384 : }
1385 : else
1386 : {
1387 : // No server access for just created (not yet committed) objects.
1388 : // Only a minimal set of properties supported at this stage.
1389 0 : if (m_bTransient)
1390 : xProps.reset( new ContentProperties( aUnescapedTitle,
1391 0 : m_bCollection ) );
1392 : }
1393 :
1394 0 : sal_Int32 nCount = rProperties.getLength();
1395 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1396 : {
1397 0 : const OUString rName = rProperties[ n ].Name;
1398 0 : if ( rName == "BaseURI" )
1399 : {
1400 : // Add BaseURI property, if requested.
1401 : xProps->addProperty(
1402 : OUString( "BaseURI" ),
1403 : uno::makeAny( getBaseURI( xResAccess ) ),
1404 0 : true );
1405 : }
1406 0 : else if ( rName == "CreatableContentsInfo" )
1407 : {
1408 : // Add CreatableContentsInfo property, if requested.
1409 0 : sal_Bool bFolder = sal_False;
1410 : xProps->getValue(
1411 0 : OUString( "IsFolder" ) )
1412 0 : >>= bFolder;
1413 : xProps->addProperty(
1414 : OUString( "CreatableContentsInfo" ),
1415 : uno::makeAny( bFolder
1416 0 : ? queryCreatableContentsInfo()
1417 : : uno::Sequence< ucb::ContentInfo >() ),
1418 0 : true );
1419 : }
1420 0 : }
1421 :
1422 : uno::Reference< sdbc::XRow > xResultRow
1423 : = getPropertyValues( m_xContext,
1424 : rProperties,
1425 0 : *xProps,
1426 : xProvider,
1427 0 : xIdentifier->getContentIdentifier() );
1428 :
1429 : {
1430 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1431 :
1432 0 : if ( !m_xCachedProps.get() )
1433 0 : m_xCachedProps.reset( new CachableContentProperties( *xProps.get() ) );
1434 : else
1435 0 : m_xCachedProps->addProperties( *xProps.get() );
1436 :
1437 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1438 0 : m_aEscapedTitle = NeonUri::escapeSegment( aUnescapedTitle );
1439 : }
1440 :
1441 0 : return xResultRow;
1442 : }
1443 :
1444 : //=========================================================================
1445 0 : uno::Sequence< uno::Any > Content::setPropertyValues(
1446 : const uno::Sequence< beans::PropertyValue >& rValues,
1447 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1448 : throw ( uno::Exception )
1449 : {
1450 0 : uno::Reference< ucb::XContentIdentifier > xIdentifier;
1451 0 : rtl::Reference< ContentProvider > xProvider;
1452 : sal_Bool bTransient;
1453 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1454 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
1455 : SAL_WNODEPRECATED_DECLARATIONS_POP
1456 :
1457 : {
1458 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1459 :
1460 0 : xProvider.set( m_pProvider );
1461 0 : xIdentifier.set( m_xIdentifier );
1462 0 : bTransient = m_bTransient;
1463 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1464 : }
1465 :
1466 0 : uno::Sequence< uno::Any > aRet( rValues.getLength() );
1467 0 : uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1468 0 : sal_Int32 nChanged = 0;
1469 :
1470 0 : beans::PropertyChangeEvent aEvent;
1471 0 : aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1472 0 : aEvent.Further = sal_False;
1473 : // aEvent.PropertyName =
1474 0 : aEvent.PropertyHandle = -1;
1475 : // aEvent.OldValue =
1476 : // aEvent.NewValue =
1477 :
1478 0 : std::vector< ProppatchValue > aProppatchValues;
1479 0 : std::vector< sal_Int32 > aProppatchPropsPositions;
1480 :
1481 0 : uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1482 0 : sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1483 :
1484 0 : sal_Bool bExchange = sal_False;
1485 0 : OUString aNewTitle;
1486 0 : OUString aOldTitle;
1487 0 : sal_Int32 nTitlePos = -1;
1488 :
1489 0 : uno::Reference< beans::XPropertySetInfo > xInfo;
1490 :
1491 0 : const beans::PropertyValue* pValues = rValues.getConstArray();
1492 0 : sal_Int32 nCount = rValues.getLength();
1493 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1494 : {
1495 0 : const beans::PropertyValue& rValue = pValues[ n ];
1496 0 : const OUString & rName = rValue.Name;
1497 :
1498 0 : beans::Property aTmpProp;
1499 0 : xProvider->getProperty( rName, aTmpProp );
1500 :
1501 0 : if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY )
1502 : {
1503 : // Read-only property!
1504 0 : aRet[ n ] <<= lang::IllegalAccessException(
1505 : OUString( "Property is read-only!" ),
1506 0 : static_cast< cppu::OWeakObject * >( this ) );
1507 0 : continue;
1508 : }
1509 :
1510 : //////////////////////////////////////////////////////////////////
1511 : // Mandatory props.
1512 : //////////////////////////////////////////////////////////////////
1513 :
1514 0 : if ( rName == "ContentType" )
1515 : {
1516 : // Read-only property!
1517 0 : aRet[ n ] <<= lang::IllegalAccessException(
1518 : OUString( "Property is read-only!" ),
1519 0 : static_cast< cppu::OWeakObject * >( this ) );
1520 : }
1521 0 : else if ( rName == "IsDocument" )
1522 : {
1523 : // Read-only property!
1524 0 : aRet[ n ] <<= lang::IllegalAccessException(
1525 : OUString( "Property is read-only!" ),
1526 0 : static_cast< cppu::OWeakObject * >( this ) );
1527 : }
1528 0 : else if ( rName == "IsFolder" )
1529 : {
1530 : // Read-only property!
1531 0 : aRet[ n ] <<= lang::IllegalAccessException(
1532 : OUString( "Property is read-only!" ),
1533 0 : static_cast< cppu::OWeakObject * >( this ) );
1534 : }
1535 0 : else if ( rName == "Title" )
1536 : {
1537 0 : OUString aNewValue;
1538 0 : if ( rValue.Value >>= aNewValue )
1539 : {
1540 : // No empty titles!
1541 0 : if ( !aNewValue.isEmpty() )
1542 : {
1543 : try
1544 : {
1545 0 : NeonUri aURI( xIdentifier->getContentIdentifier() );
1546 0 : aOldTitle = aURI.GetPathBaseNameUnescaped();
1547 :
1548 0 : if ( aNewValue != aOldTitle )
1549 : {
1550 : // modified title -> modified URL -> exchange !
1551 0 : if ( !bTransient )
1552 0 : bExchange = sal_True;
1553 :
1554 : // new value will be set later...
1555 0 : aNewTitle = aNewValue;
1556 :
1557 : // remember position within sequence of values (for
1558 : // error handling).
1559 0 : nTitlePos = n;
1560 0 : }
1561 : }
1562 0 : catch ( DAVException const & )
1563 : {
1564 0 : aRet[ n ] <<= lang::IllegalArgumentException(
1565 : OUString( "Invalid content identifier!" ),
1566 : static_cast< cppu::OWeakObject * >( this ),
1567 0 : -1 );
1568 : }
1569 : }
1570 : else
1571 : {
1572 0 : aRet[ n ] <<= lang::IllegalArgumentException(
1573 : OUString( "Empty title not allowed!" ),
1574 : static_cast< cppu::OWeakObject * >( this ),
1575 0 : -1 );
1576 : }
1577 : }
1578 : else
1579 : {
1580 0 : aRet[ n ] <<= beans::IllegalTypeException(
1581 : OUString( "Property value has wrong type!" ),
1582 0 : static_cast< cppu::OWeakObject * >( this ) );
1583 0 : }
1584 : }
1585 : else
1586 : {
1587 : //////////////////////////////////////////////////////////////
1588 : // Optional props.
1589 : //////////////////////////////////////////////////////////////
1590 :
1591 0 : if ( !xInfo.is() )
1592 0 : xInfo = getPropertySetInfo( xEnv,
1593 0 : sal_False /* don't cache data */ );
1594 :
1595 0 : if ( !xInfo->hasPropertyByName( rName ) )
1596 : {
1597 : // Check, whether property exists. Skip otherwise.
1598 : // PROPPATCH::set would add the property automatically, which
1599 : // is not allowed for "setPropertyValues" command!
1600 0 : aRet[ n ] <<= beans::UnknownPropertyException(
1601 : OUString( "Property is unknown!" ),
1602 0 : static_cast< cppu::OWeakObject * >( this ) );
1603 0 : continue;
1604 : }
1605 :
1606 0 : if ( rName == "Size" )
1607 : {
1608 : // Read-only property!
1609 0 : aRet[ n ] <<= lang::IllegalAccessException(
1610 : OUString( "Property is read-only!" ),
1611 0 : static_cast< cppu::OWeakObject * >( this ) );
1612 : }
1613 0 : else if ( rName == "DateCreated" )
1614 : {
1615 : // Read-only property!
1616 0 : aRet[ n ] <<= lang::IllegalAccessException(
1617 : OUString( "Property is read-only!" ),
1618 0 : static_cast< cppu::OWeakObject * >( this ) );
1619 : }
1620 0 : else if ( rName == "DateModified" )
1621 : {
1622 : // Read-only property!
1623 0 : aRet[ n ] <<= lang::IllegalAccessException(
1624 : OUString( "Property is read-only!" ),
1625 0 : static_cast< cppu::OWeakObject * >( this ) );
1626 : }
1627 0 : else if ( rName == "MediaType" )
1628 : {
1629 : // Read-only property!
1630 : // (but could be writable, if 'getcontenttype' would be)
1631 0 : aRet[ n ] <<= lang::IllegalAccessException(
1632 : OUString( "Property is read-only!" ),
1633 0 : static_cast< cppu::OWeakObject * >( this ) );
1634 : }
1635 0 : if ( rName == "CreatableContentsInfo" )
1636 : {
1637 : // Read-only property!
1638 0 : aRet[ n ] <<= lang::IllegalAccessException(
1639 : OUString( "Property is read-only!" ),
1640 0 : static_cast< cppu::OWeakObject * >( this ) );
1641 : }
1642 : else
1643 : {
1644 0 : if ( getResourceType( xEnv, xResAccess ) == DAV )
1645 : {
1646 : // Property value will be set on server.
1647 0 : ProppatchValue aValue( PROPSET, rName, rValue.Value );
1648 0 : aProppatchValues.push_back( aValue );
1649 :
1650 : // remember position within sequence of values (for
1651 : // error handling).
1652 0 : aProppatchPropsPositions.push_back( n );
1653 : }
1654 : else
1655 : {
1656 : // Property value will be stored in local property store.
1657 0 : if ( !bTriedToGetAdditonalPropSet &&
1658 0 : !xAdditionalPropSet.is() )
1659 : {
1660 : xAdditionalPropSet
1661 0 : = getAdditionalPropertySet( sal_False );
1662 0 : bTriedToGetAdditonalPropSet = sal_True;
1663 : }
1664 :
1665 0 : if ( xAdditionalPropSet.is() )
1666 : {
1667 : try
1668 : {
1669 : uno::Any aOldValue
1670 0 : = xAdditionalPropSet->getPropertyValue( rName );
1671 0 : if ( aOldValue != rValue.Value )
1672 : {
1673 0 : xAdditionalPropSet->setPropertyValue(
1674 0 : rName, rValue.Value );
1675 :
1676 0 : aEvent.PropertyName = rName;
1677 0 : aEvent.OldValue = aOldValue;
1678 0 : aEvent.NewValue = rValue.Value;
1679 :
1680 0 : aChanges.getArray()[ nChanged ] = aEvent;
1681 0 : nChanged++;
1682 0 : }
1683 : }
1684 0 : catch ( beans::UnknownPropertyException const & e )
1685 : {
1686 0 : aRet[ n ] <<= e;
1687 : }
1688 0 : catch ( lang::WrappedTargetException const & e )
1689 : {
1690 0 : aRet[ n ] <<= e;
1691 : }
1692 0 : catch ( beans::PropertyVetoException const & e )
1693 : {
1694 0 : aRet[ n ] <<= e;
1695 : }
1696 0 : catch ( lang::IllegalArgumentException const & e )
1697 : {
1698 0 : aRet[ n ] <<= e;
1699 : }
1700 : }
1701 : else
1702 : {
1703 0 : aRet[ n ] <<= uno::Exception(
1704 : OUString( "No property set for storing the value!" ),
1705 0 : static_cast< cppu::OWeakObject * >( this ) );
1706 : }
1707 : }
1708 : }
1709 : }
1710 0 : } // for
1711 :
1712 0 : if ( !bTransient && !aProppatchValues.empty() )
1713 : {
1714 : try
1715 : {
1716 : // Set property values at server.
1717 0 : xResAccess->PROPPATCH( aProppatchValues, xEnv );
1718 :
1719 : std::vector< ProppatchValue >::const_iterator it
1720 0 : = aProppatchValues.begin();
1721 : std::vector< ProppatchValue >::const_iterator end
1722 0 : = aProppatchValues.end();
1723 :
1724 0 : while ( it != end )
1725 : {
1726 0 : aEvent.PropertyName = (*it).name;
1727 0 : aEvent.OldValue = uno::Any(); // @@@ to expensive to obtain!
1728 0 : aEvent.NewValue = (*it).value;
1729 :
1730 0 : aChanges.getArray()[ nChanged ] = aEvent;
1731 0 : nChanged++;
1732 :
1733 0 : ++it;
1734 : }
1735 : }
1736 0 : catch ( DAVException const & e )
1737 : {
1738 : // OSL_FAIL( // "Content::setPropertyValues - PROPPATCH failed!" );
1739 :
1740 0 : cancelCommandExecution( e, xEnv );
1741 : // unreachable
1742 : }
1743 : }
1744 :
1745 0 : if ( bExchange )
1746 : {
1747 : // Assemble new content identifier...
1748 :
1749 0 : OUString aNewURL = getParentURL();
1750 0 : if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
1751 0 : aNewURL += OUString("/");
1752 :
1753 0 : aNewURL += NeonUri::escapeSegment( aNewTitle );
1754 :
1755 : uno::Reference< ucb::XContentIdentifier > xNewId
1756 0 : = new ::ucbhelper::ContentIdentifier( aNewURL );
1757 0 : uno::Reference< ucb::XContentIdentifier > xOldId = xIdentifier;
1758 :
1759 : try
1760 : {
1761 0 : NeonUri sourceURI( xOldId->getContentIdentifier() );
1762 0 : NeonUri targetURI( xNewId->getContentIdentifier() );
1763 0 : targetURI.SetScheme( sourceURI.GetScheme() );
1764 :
1765 : xResAccess->MOVE(
1766 0 : sourceURI.GetPath(), targetURI.GetURI(), sal_False, xEnv );
1767 : // @@@ Should check for resources that could not be moved
1768 : // (due to source access or target overwrite) and send
1769 : // this information through the interaction handler.
1770 :
1771 : // @@@ Existing content should be checked to see if it needs
1772 : // to be deleted at the source
1773 :
1774 : // @@@ Existing content should be checked to see if it has
1775 : // been overwritten at the target
1776 :
1777 0 : if ( exchangeIdentity( xNewId ) )
1778 : {
1779 0 : xResAccess->setURL( aNewURL );
1780 :
1781 : // DAV resources store all additional props on server!
1782 : // // Adapt Additional Core Properties.
1783 : // renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1784 : // xNewId->getContentIdentifier(),
1785 : // sal_True );
1786 : }
1787 : else
1788 : {
1789 : // Do not set new title!
1790 0 : aNewTitle = OUString();
1791 :
1792 : // Set error .
1793 0 : aRet[ nTitlePos ] <<= uno::Exception(
1794 : OUString("Exchange failed!"),
1795 0 : static_cast< cppu::OWeakObject * >( this ) );
1796 0 : }
1797 : }
1798 0 : catch ( DAVException const & e )
1799 : {
1800 : // Do not set new title!
1801 0 : aNewTitle = OUString();
1802 :
1803 : // Set error .
1804 0 : aRet[ nTitlePos ] <<= MapDAVException( e, sal_True );
1805 0 : }
1806 : }
1807 :
1808 0 : if ( !aNewTitle.isEmpty() )
1809 : {
1810 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1811 :
1812 0 : aEvent.PropertyName = OUString("Title");
1813 0 : aEvent.OldValue = uno::makeAny( aOldTitle );
1814 0 : aEvent.NewValue = uno::makeAny( aNewTitle );
1815 :
1816 0 : m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle );
1817 :
1818 0 : aChanges.getArray()[ nChanged ] = aEvent;
1819 0 : nChanged++;
1820 : }
1821 :
1822 0 : if ( nChanged > 0 )
1823 : {
1824 0 : aChanges.realloc( nChanged );
1825 0 : notifyPropertiesChange( aChanges );
1826 : }
1827 :
1828 : {
1829 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1830 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1831 : }
1832 :
1833 0 : return aRet;
1834 : }
1835 :
1836 : //=========================================================================
1837 0 : uno::Any Content::open(
1838 : const ucb::OpenCommandArgument3 & rArg,
1839 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1840 : throw( uno::Exception )
1841 : {
1842 0 : uno::Any aRet;
1843 :
1844 0 : sal_Bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) ||
1845 0 : ( rArg.Mode == ucb::OpenMode::FOLDERS ) ||
1846 0 : ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) );
1847 0 : if ( bOpenFolder )
1848 : {
1849 0 : if ( isFolder( xEnv ) )
1850 : {
1851 : // Open collection.
1852 :
1853 : uno::Reference< ucb::XDynamicResultSet > xSet
1854 0 : = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1855 0 : aRet <<= xSet;
1856 : }
1857 : else
1858 : {
1859 : // Error: Not a folder!
1860 :
1861 0 : OUStringBuffer aMsg;
1862 0 : if ( getResourceType( xEnv ) == FTP )
1863 : {
1864 : // #114653#
1865 : aMsg.appendAscii( "FTP over HTTP proxy: resource cannot "
1866 0 : "be opened as folder! Wrong Open Mode!" );
1867 : }
1868 : else
1869 : {
1870 : aMsg.appendAscii( "Non-folder resource cannot be "
1871 0 : "opened as folder! Wrong Open Mode!" );
1872 : }
1873 :
1874 : ucbhelper::cancelCommandExecution(
1875 : uno::makeAny(
1876 : lang::IllegalArgumentException(
1877 : aMsg.makeStringAndClear(),
1878 : static_cast< cppu::OWeakObject * >( this ),
1879 : -1 ) ),
1880 0 : xEnv );
1881 : // Unreachable
1882 : }
1883 : }
1884 :
1885 0 : if ( rArg.Sink.is() )
1886 : {
1887 : // Open document.
1888 :
1889 0 : if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1890 0 : ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1891 : {
1892 : // Currently(?) unsupported.
1893 : ucbhelper::cancelCommandExecution(
1894 : uno::makeAny(
1895 : ucb::UnsupportedOpenModeException(
1896 : OUString(),
1897 : static_cast< cppu::OWeakObject * >( this ),
1898 : sal_Int16( rArg.Mode ) ) ),
1899 0 : xEnv );
1900 : // Unreachable
1901 : }
1902 :
1903 : uno::Reference< io::XOutputStream > xOut
1904 0 : = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
1905 0 : if ( xOut.is() )
1906 : {
1907 : // PUSH: write data
1908 : try
1909 : {
1910 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1911 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
1912 : SAL_WNODEPRECATED_DECLARATIONS_POP
1913 :
1914 : {
1915 0 : osl::MutexGuard aGuard( m_aMutex );
1916 :
1917 : xResAccess.reset(
1918 0 : new DAVResourceAccess( *m_xResAccess.get() ) );
1919 : }
1920 :
1921 0 : xResAccess->setFlags( rArg.OpeningFlags );
1922 0 : DAVResource aResource;
1923 0 : std::vector< OUString > aHeaders;
1924 :
1925 0 : xResAccess->GET( xOut, aHeaders, aResource, xEnv );
1926 0 : m_bDidGetOrHead = true;
1927 :
1928 : {
1929 0 : osl::MutexGuard aGuard( m_aMutex );
1930 :
1931 : // cache headers.
1932 0 : if ( !m_xCachedProps.get())
1933 : m_xCachedProps.reset(
1934 0 : new CachableContentProperties( aResource ) );
1935 : else
1936 0 : m_xCachedProps->addProperties( aResource );
1937 :
1938 : m_xResAccess.reset(
1939 0 : new DAVResourceAccess( *xResAccess.get() ) );
1940 0 : }
1941 : }
1942 0 : catch ( DAVException const & e )
1943 : {
1944 0 : cancelCommandExecution( e, xEnv );
1945 : // Unreachable
1946 : }
1947 : }
1948 : else
1949 : {
1950 : uno::Reference< io::XActiveDataSink > xDataSink
1951 : = uno::Reference< io::XActiveDataSink >( rArg.Sink,
1952 0 : uno::UNO_QUERY );
1953 0 : if ( xDataSink.is() )
1954 : {
1955 : // PULL: wait for client read
1956 : try
1957 : {
1958 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1959 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
1960 : SAL_WNODEPRECATED_DECLARATIONS_POP
1961 : {
1962 0 : osl::MutexGuard aGuard( m_aMutex );
1963 :
1964 : xResAccess.reset(
1965 0 : new DAVResourceAccess( *m_xResAccess.get() ) );
1966 : }
1967 :
1968 0 : xResAccess->setFlags( rArg.OpeningFlags );
1969 :
1970 : // fill inputsream sync; return if all data present
1971 0 : DAVResource aResource;
1972 0 : std::vector< OUString > aHeaders;
1973 :
1974 : uno::Reference< io::XInputStream > xIn
1975 0 : = xResAccess->GET( aHeaders, aResource, xEnv );
1976 0 : m_bDidGetOrHead = true;
1977 :
1978 : {
1979 0 : osl::MutexGuard aGuard( m_aMutex );
1980 :
1981 : // cache headers.
1982 0 : if ( !m_xCachedProps.get())
1983 : m_xCachedProps.reset(
1984 0 : new CachableContentProperties( aResource ) );
1985 : else
1986 : m_xCachedProps->addProperties(
1987 0 : aResource.properties );
1988 :
1989 : m_xResAccess.reset(
1990 0 : new DAVResourceAccess( *xResAccess.get() ) );
1991 : }
1992 :
1993 0 : xDataSink->setInputStream( xIn );
1994 : }
1995 0 : catch ( DAVException const & e )
1996 : {
1997 0 : cancelCommandExecution( e, xEnv );
1998 : // Unreachable
1999 : }
2000 : }
2001 : else
2002 : {
2003 : // Note: aOpenCommand.Sink may contain an XStream
2004 : // implementation. Support for this type of
2005 : // sink is optional...
2006 : ucbhelper::cancelCommandExecution(
2007 : uno::makeAny(
2008 : ucb::UnsupportedDataSinkException(
2009 : OUString(),
2010 : static_cast< cppu::OWeakObject * >( this ),
2011 : rArg.Sink ) ),
2012 0 : xEnv );
2013 : // Unreachable
2014 0 : }
2015 0 : }
2016 : }
2017 :
2018 0 : return aRet;
2019 : }
2020 :
2021 : //=========================================================================
2022 0 : void Content::post(
2023 : const ucb::PostCommandArgument2 & rArg,
2024 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2025 : throw( uno::Exception )
2026 : {
2027 0 : uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
2028 0 : if ( xSink.is() )
2029 : {
2030 : try
2031 : {
2032 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2033 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2034 : SAL_WNODEPRECATED_DECLARATIONS_POP
2035 : {
2036 0 : osl::MutexGuard aGuard( m_aMutex );
2037 : xResAccess.reset(
2038 0 : new DAVResourceAccess( *m_xResAccess.get() ) );
2039 : }
2040 :
2041 : uno::Reference< io::XInputStream > xResult
2042 : = xResAccess->POST( rArg.MediaType,
2043 : rArg.Referer,
2044 : rArg.Source,
2045 0 : xEnv );
2046 :
2047 : {
2048 0 : osl::MutexGuard aGuard( m_aMutex );
2049 : m_xResAccess.reset(
2050 0 : new DAVResourceAccess( *xResAccess.get() ) );
2051 : }
2052 :
2053 0 : xSink->setInputStream( xResult );
2054 : }
2055 0 : catch ( DAVException const & e )
2056 : {
2057 0 : cancelCommandExecution( e, xEnv, sal_True );
2058 : // Unreachable
2059 : }
2060 : }
2061 : else
2062 : {
2063 0 : uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
2064 0 : if ( xResult.is() )
2065 : {
2066 : try
2067 : {
2068 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2069 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2070 : SAL_WNODEPRECATED_DECLARATIONS_POP
2071 : {
2072 0 : osl::MutexGuard aGuard( m_aMutex );
2073 : xResAccess.reset(
2074 0 : new DAVResourceAccess( *m_xResAccess.get() ) );
2075 : }
2076 :
2077 : xResAccess->POST( rArg.MediaType,
2078 : rArg.Referer,
2079 : rArg.Source,
2080 : xResult,
2081 0 : xEnv );
2082 :
2083 : {
2084 0 : osl::MutexGuard aGuard( m_aMutex );
2085 : m_xResAccess.reset(
2086 0 : new DAVResourceAccess( *xResAccess.get() ) );
2087 0 : }
2088 : }
2089 0 : catch ( DAVException const & e )
2090 : {
2091 0 : cancelCommandExecution( e, xEnv, sal_True );
2092 : // Unreachable
2093 : }
2094 : }
2095 : else
2096 : {
2097 : ucbhelper::cancelCommandExecution(
2098 : uno::makeAny(
2099 : ucb::UnsupportedDataSinkException(
2100 : OUString(),
2101 : static_cast< cppu::OWeakObject * >( this ),
2102 : rArg.Sink ) ),
2103 0 : xEnv );
2104 : // Unreachable
2105 0 : }
2106 0 : }
2107 0 : }
2108 :
2109 : //=========================================================================
2110 0 : void Content::queryChildren( ContentRefList& rChildren )
2111 : {
2112 : // Obtain a list with a snapshot of all currently instanciated contents
2113 : // from provider and extract the contents which are direct children
2114 : // of this content.
2115 :
2116 0 : ::ucbhelper::ContentRefList aAllContents;
2117 0 : m_xProvider->queryExistingContents( aAllContents );
2118 :
2119 0 : OUString aURL = m_xIdentifier->getContentIdentifier();
2120 0 : sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
2121 :
2122 0 : if ( nURLPos != ( aURL.getLength() - 1 ) )
2123 : {
2124 : // No trailing slash found. Append.
2125 0 : aURL += OUString("/");
2126 : }
2127 :
2128 0 : sal_Int32 nLen = aURL.getLength();
2129 :
2130 0 : ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2131 0 : ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2132 :
2133 0 : while ( it != end )
2134 : {
2135 0 : ::ucbhelper::ContentImplHelperRef xChild = (*it);
2136 : OUString aChildURL
2137 0 : = xChild->getIdentifier()->getContentIdentifier();
2138 :
2139 : // Is aURL a prefix of aChildURL?
2140 0 : if ( ( aChildURL.getLength() > nLen ) &&
2141 0 : ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
2142 : {
2143 0 : sal_Int32 nPos = nLen;
2144 0 : nPos = aChildURL.indexOf( '/', nPos );
2145 :
2146 0 : if ( ( nPos == -1 ) ||
2147 0 : ( nPos == ( aChildURL.getLength() - 1 ) ) )
2148 : {
2149 : // No further slashes / only a final slash. It's a child!
2150 : rChildren.push_back(
2151 : ::webdav_ucp::Content::ContentRef(
2152 : static_cast< ::webdav_ucp::Content * >(
2153 0 : xChild.get() ) ) );
2154 : }
2155 : }
2156 0 : ++it;
2157 0 : }
2158 0 : }
2159 :
2160 : //=========================================================================
2161 0 : void Content::insert(
2162 : const uno::Reference< io::XInputStream > & xInputStream,
2163 : sal_Bool bReplaceExisting,
2164 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
2165 : throw( uno::Exception )
2166 : {
2167 : sal_Bool bTransient, bCollection;
2168 0 : OUString aEscapedTitle;
2169 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2170 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2171 : SAL_WNODEPRECATED_DECLARATIONS_POP
2172 :
2173 : {
2174 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2175 :
2176 0 : bTransient = m_bTransient;
2177 0 : bCollection = m_bCollection;
2178 0 : aEscapedTitle = m_aEscapedTitle;
2179 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2180 : }
2181 :
2182 : // Check, if all required properties are present.
2183 :
2184 0 : if ( aEscapedTitle.isEmpty() )
2185 : {
2186 : OSL_FAIL( "Content::insert - Title missing!" );
2187 :
2188 0 : uno::Sequence< OUString > aProps( 1 );
2189 0 : aProps[ 0 ] = OUString("Title");
2190 : ucbhelper::cancelCommandExecution(
2191 : uno::makeAny( ucb::MissingPropertiesException(
2192 : OUString(),
2193 : static_cast< cppu::OWeakObject * >( this ),
2194 : aProps ) ),
2195 0 : Environment );
2196 : // Unreachable
2197 : }
2198 :
2199 0 : if ( !bReplaceExisting )
2200 : {
2201 : /* [RFC 2616] - HTTP
2202 :
2203 : The PUT method requests that the enclosed entity be stored under the
2204 : supplied Request-URI. If the Request-URI refers to an already
2205 : existing resource, the enclosed entity SHOULD be considered as a
2206 : modified version of the one residing on the origin server.
2207 : */
2208 :
2209 : /* [RFC 2518] - WebDAV
2210 :
2211 : MKCOL creates a new collection resource at the location specified by
2212 : the Request-URI. If the resource identified by the Request-URI is
2213 : non-null then the MKCOL MUST fail.
2214 : */
2215 :
2216 : // ==> Complain on PUT, continue on MKCOL.
2217 0 : if ( !bTransient || ( bTransient && !bCollection ) )
2218 : {
2219 : ucb::UnsupportedNameClashException aEx(
2220 : OUString( "Unable to write without overwrite!" ),
2221 : static_cast< cppu::OWeakObject * >( this ),
2222 0 : ucb::NameClash::ERROR );
2223 :
2224 0 : uno::Reference< task::XInteractionHandler > xIH;
2225 :
2226 0 : if ( Environment.is() )
2227 0 : xIH = Environment->getInteractionHandler();
2228 :
2229 0 : if ( xIH.is() )
2230 : {
2231 0 : uno::Any aExAsAny( uno::makeAny( aEx ) );
2232 :
2233 : rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest
2234 : = new ucbhelper::SimpleInteractionRequest(
2235 : aExAsAny,
2236 : ucbhelper::CONTINUATION_APPROVE
2237 0 : | ucbhelper::CONTINUATION_DISAPPROVE );
2238 0 : xIH->handle( xRequest.get() );
2239 :
2240 0 : const sal_Int32 nResp = xRequest->getResponse();
2241 :
2242 0 : switch ( nResp )
2243 : {
2244 : case ucbhelper::CONTINUATION_UNKNOWN:
2245 : // Not handled; throw.
2246 0 : throw aEx;
2247 : // break;
2248 :
2249 : case ucbhelper::CONTINUATION_APPROVE:
2250 : // Continue -> Overwrite.
2251 0 : bReplaceExisting = sal_True;
2252 0 : break;
2253 :
2254 : case ucbhelper::CONTINUATION_DISAPPROVE:
2255 : // Abort.
2256 : throw ucb::CommandFailedException(
2257 : OUString(),
2258 : uno::Reference< uno::XInterface >(),
2259 0 : aExAsAny );
2260 : // break;
2261 :
2262 : default:
2263 : OSL_FAIL( "Content::insert - "
2264 : "Unknown interaction selection!" );
2265 : throw ucb::CommandFailedException(
2266 : OUString( "Unknown interaction selection!" ),
2267 : uno::Reference< uno::XInterface >(),
2268 0 : aExAsAny );
2269 : // break;
2270 0 : }
2271 : }
2272 : else
2273 : {
2274 : // No IH; throw.
2275 0 : throw aEx;
2276 0 : }
2277 : }
2278 : }
2279 :
2280 0 : if ( bTransient )
2281 : {
2282 : // Assemble new content identifier...
2283 0 : OUString aURL = getParentURL();
2284 0 : if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) )
2285 0 : aURL += OUString("/");
2286 :
2287 0 : aURL += aEscapedTitle;
2288 :
2289 : try
2290 : {
2291 0 : xResAccess->setURL( aURL );
2292 :
2293 0 : if ( bCollection )
2294 0 : xResAccess->MKCOL( Environment );
2295 : else
2296 0 : xResAccess->PUT( xInputStream, Environment );
2297 : }
2298 0 : catch ( DAVException const & except )
2299 : {
2300 0 : if ( bCollection )
2301 : {
2302 0 : if ( except.getStatus() == SC_METHOD_NOT_ALLOWED )
2303 : {
2304 : // [RFC 2518] - WebDAV
2305 : // 405 (Method Not Allowed) - MKCOL can only be
2306 : // executed on a deleted/non-existent resource.
2307 :
2308 0 : if ( bReplaceExisting )
2309 : {
2310 : // Destroy old resource.
2311 : try
2312 : {
2313 0 : xResAccess->DESTROY( Environment );
2314 : }
2315 0 : catch ( DAVException const & e )
2316 : {
2317 0 : cancelCommandExecution( e, Environment, sal_True );
2318 : // Unreachable
2319 : }
2320 :
2321 : // Insert (recursion!).
2322 0 : insert( xInputStream, bReplaceExisting, Environment );
2323 :
2324 : {
2325 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2326 : m_xResAccess.reset(
2327 0 : new DAVResourceAccess( *xResAccess.get() ) );
2328 : }
2329 :
2330 : // Success!
2331 0 : return;
2332 : }
2333 : else
2334 : {
2335 0 : OUString aTitle;
2336 : try
2337 : {
2338 0 : NeonUri aURI( aURL );
2339 0 : aTitle = aURI.GetPathBaseNameUnescaped();
2340 : }
2341 0 : catch ( DAVException const & )
2342 : {
2343 : }
2344 :
2345 : ucbhelper::cancelCommandExecution(
2346 : uno::makeAny(
2347 : ucb::NameClashException(
2348 : OUString(),
2349 : static_cast< cppu::OWeakObject * >( this ),
2350 : task::InteractionClassification_ERROR,
2351 : aTitle ) ),
2352 0 : Environment );
2353 : // Unreachable
2354 : }
2355 : }
2356 : }
2357 :
2358 0 : cancelCommandExecution( except, Environment, sal_True );
2359 : // Unreachable
2360 0 : }
2361 :
2362 : {
2363 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2364 0 : m_xIdentifier = new ::ucbhelper::ContentIdentifier( aURL );
2365 : }
2366 :
2367 0 : inserted();
2368 :
2369 : {
2370 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2371 0 : m_bTransient = sal_False;
2372 0 : }
2373 : }
2374 : else
2375 : {
2376 0 : if ( !xInputStream.is() )
2377 : {
2378 : ucbhelper::cancelCommandExecution(
2379 : uno::makeAny(
2380 : ucb::MissingInputStreamException(
2381 : OUString(),
2382 : static_cast< cppu::OWeakObject * >( this ) ) ),
2383 0 : Environment );
2384 : // Unreachable
2385 : }
2386 :
2387 : try
2388 : {
2389 0 : xResAccess->PUT( xInputStream, Environment );
2390 : }
2391 0 : catch ( DAVException const & e )
2392 : {
2393 0 : cancelCommandExecution( e, Environment, sal_True );
2394 : // Unreachable
2395 : }
2396 : }
2397 :
2398 : {
2399 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2400 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2401 0 : }
2402 : }
2403 :
2404 : //=========================================================================
2405 0 : void Content::transfer(
2406 : const ucb::TransferInfo & rArgs,
2407 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
2408 : throw( uno::Exception )
2409 : {
2410 0 : uno::Reference< ucb::XContentIdentifier > xIdentifier;
2411 0 : uno::Reference< ucb::XContentProvider > xProvider;
2412 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2413 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2414 : SAL_WNODEPRECATED_DECLARATIONS_POP
2415 :
2416 : {
2417 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2418 :
2419 0 : xIdentifier.set( m_xIdentifier );
2420 0 : xProvider.set( m_xProvider.get() );
2421 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2422 : }
2423 :
2424 0 : OUString aTargetURI;
2425 : try
2426 : {
2427 0 : NeonUri sourceURI( rArgs.SourceURL );
2428 0 : NeonUri targetURI( xIdentifier->getContentIdentifier() );
2429 0 : aTargetURI = targetURI.GetPathBaseNameUnescaped();
2430 :
2431 : // Check source's and target's URL scheme
2432 : //
2433 0 : const OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase();
2434 0 : if ( aScheme == WEBDAV_URL_SCHEME )
2435 : {
2436 : sourceURI.SetScheme(
2437 0 : OUString( HTTP_URL_SCHEME ) );
2438 : }
2439 0 : else if ( aScheme == DAV_URL_SCHEME )
2440 : {
2441 : sourceURI.SetScheme(
2442 0 : OUString( HTTP_URL_SCHEME ) );
2443 : }
2444 0 : else if ( aScheme == DAVS_URL_SCHEME )
2445 : {
2446 : sourceURI.SetScheme(
2447 0 : OUString( HTTPS_URL_SCHEME ) );
2448 : }
2449 : else
2450 : {
2451 0 : if ( aScheme != HTTP_URL_SCHEME && aScheme != HTTPS_URL_SCHEME )
2452 : {
2453 : ucbhelper::cancelCommandExecution(
2454 : uno::makeAny(
2455 : ucb::InteractiveBadTransferURLException(
2456 : OUString( "Unsupported URL scheme!" ),
2457 : static_cast< cppu::OWeakObject * >( this ) ) ),
2458 0 : Environment );
2459 : // Unreachable
2460 : }
2461 : }
2462 :
2463 0 : if ( targetURI.GetScheme().toAsciiLowerCase() == WEBDAV_URL_SCHEME )
2464 : targetURI.SetScheme(
2465 0 : OUString( HTTP_URL_SCHEME ) );
2466 0 : else if ( targetURI.GetScheme().toAsciiLowerCase() == DAV_URL_SCHEME )
2467 : targetURI.SetScheme(
2468 0 : OUString( HTTP_URL_SCHEME ) );
2469 :
2470 : // @@@ This implementation of 'transfer' only works
2471 : // if the source and target are located at same host.
2472 : // (Neon does not support cross-server copy/move)
2473 :
2474 : // Check for same host
2475 : //
2476 0 : if ( !sourceURI.GetHost().isEmpty() &&
2477 0 : ( sourceURI.GetHost() != targetURI.GetHost() ) )
2478 : {
2479 : ucbhelper::cancelCommandExecution(
2480 : uno::makeAny( ucb::InteractiveBadTransferURLException(
2481 : OUString( "Different hosts!" ),
2482 : static_cast< cppu::OWeakObject * >( this ) ) ),
2483 0 : Environment );
2484 : // Unreachable
2485 : }
2486 :
2487 0 : OUString aTitle = rArgs.NewTitle;
2488 :
2489 0 : if ( aTitle.isEmpty() )
2490 0 : aTitle = sourceURI.GetPathBaseNameUnescaped();
2491 :
2492 0 : if ( aTitle == "/" )
2493 : {
2494 : // kso: ???
2495 0 : aTitle = OUString();
2496 : }
2497 :
2498 0 : targetURI.AppendPath( aTitle );
2499 :
2500 0 : OUString aTargetURL = xIdentifier->getContentIdentifier();
2501 0 : if ( ( aTargetURL.lastIndexOf( '/' ) + 1 )
2502 0 : != aTargetURL.getLength() )
2503 0 : aTargetURL += OUString("/");
2504 :
2505 0 : aTargetURL += aTitle;
2506 :
2507 : uno::Reference< ucb::XContentIdentifier > xTargetId
2508 0 : = new ::ucbhelper::ContentIdentifier( aTargetURL );
2509 :
2510 : DAVResourceAccess aSourceAccess( m_xContext,
2511 : xResAccess->getSessionFactory(),
2512 0 : sourceURI.GetURI() );
2513 :
2514 0 : if ( rArgs.MoveData == sal_True )
2515 : {
2516 : uno::Reference< ucb::XContentIdentifier > xId
2517 0 : = new ::ucbhelper::ContentIdentifier( rArgs.SourceURL );
2518 :
2519 : // Note: The static cast is okay here, because its sure that
2520 : // xProvider is always the WebDAVContentProvider.
2521 : rtl::Reference< Content > xSource
2522 : = static_cast< Content * >(
2523 0 : xProvider->queryContent( xId ).get() );
2524 :
2525 : // [RFC 2518] - WebDAV
2526 : // If a resource exists at the destination and the Overwrite
2527 : // header is "T" then prior to performing the move the server
2528 : // MUST perform a DELETE with "Depth: infinity" on the
2529 : // destination resource. If the Overwrite header is set to
2530 : // "F" then the operation will fail.
2531 :
2532 0 : aSourceAccess.MOVE( sourceURI.GetPath(),
2533 0 : targetURI.GetURI(),
2534 : rArgs.NameClash
2535 : == ucb::NameClash::OVERWRITE,
2536 0 : Environment );
2537 :
2538 0 : if ( xSource.is() )
2539 : {
2540 : // Propagate destruction to listeners.
2541 0 : xSource->destroy( sal_True );
2542 0 : }
2543 :
2544 : // DAV resources store all additional props on server!
2545 : // // Rename own and all children's Additional Core Properties.
2546 : // renameAdditionalPropertySet( xId->getContentIdentifier(),
2547 : // xTargetId->getContentIdentifier(),
2548 : // sal_True );
2549 : }
2550 : else
2551 : {
2552 : // [RFC 2518] - WebDAV
2553 : // If a resource exists at the destination and the Overwrite
2554 : // header is "T" then prior to performing the copy the server
2555 : // MUST perform a DELETE with "Depth: infinity" on the
2556 : // destination resource. If the Overwrite header is set to
2557 : // "F" then the operation will fail.
2558 :
2559 0 : aSourceAccess.COPY( sourceURI.GetPath(),
2560 0 : targetURI.GetURI(),
2561 : rArgs.NameClash
2562 : == ucb::NameClash::OVERWRITE,
2563 0 : Environment );
2564 :
2565 : // DAV resources store all additional props on server!
2566 : // // Copy own and all children's Additional Core Properties.
2567 : // copyAdditionalPropertySet( xId->getContentIdentifier(),
2568 : // xTargetId->getContentIdentifier(),
2569 : // sal_True );
2570 : }
2571 :
2572 : // Note: The static cast is okay here, because its sure that
2573 : // xProvider is always the WebDAVContentProvider.
2574 : rtl::Reference< Content > xTarget
2575 : = static_cast< Content * >(
2576 0 : xProvider->queryContent( xTargetId ).get() );
2577 :
2578 : // Announce transferred content in its new folder.
2579 0 : xTarget->inserted();
2580 : }
2581 0 : catch ( ucb::IllegalIdentifierException const & )
2582 : {
2583 : // queryContent
2584 : }
2585 0 : catch ( DAVException const & e )
2586 : {
2587 : // [RFC 2518] - WebDAV
2588 : // 412 (Precondition Failed) - The server was unable to maintain
2589 : // the liveness of the properties listed in the propertybehavior
2590 : // XML element or the Overwrite header is "F" and the state of
2591 : // the destination resource is non-null.
2592 :
2593 0 : if ( e.getStatus() == SC_PRECONDITION_FAILED )
2594 : {
2595 0 : switch ( rArgs.NameClash )
2596 : {
2597 : case ucb::NameClash::ERROR:
2598 : {
2599 : ucbhelper::cancelCommandExecution(
2600 : uno::makeAny(
2601 : ucb::NameClashException(
2602 : OUString(),
2603 : static_cast< cppu::OWeakObject * >( this ),
2604 : task::InteractionClassification_ERROR,
2605 : aTargetURI ) ),
2606 0 : Environment );
2607 : // Unreachable
2608 : }
2609 :
2610 : case ucb::NameClash::OVERWRITE:
2611 0 : break;
2612 :
2613 : case ucb::NameClash::KEEP: // deprecated
2614 : case ucb::NameClash::RENAME:
2615 : case ucb::NameClash::ASK:
2616 : default:
2617 : {
2618 : ucbhelper::cancelCommandExecution(
2619 : uno::makeAny(
2620 : ucb::UnsupportedNameClashException(
2621 : OUString(),
2622 : static_cast< cppu::OWeakObject * >( this ),
2623 : rArgs.NameClash ) ),
2624 0 : Environment );
2625 : // Unreachable
2626 : }
2627 : }
2628 : }
2629 :
2630 0 : cancelCommandExecution( e, Environment, sal_True );
2631 : // Unreachable
2632 : }
2633 :
2634 : {
2635 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2636 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2637 0 : }
2638 0 : }
2639 :
2640 : //=========================================================================
2641 0 : void Content::destroy( sal_Bool bDeletePhysical )
2642 : throw( uno::Exception )
2643 : {
2644 : // @@@ take care about bDeletePhysical -> trashcan support
2645 0 : uno::Reference< ucb::XContent > xThis = this;
2646 :
2647 0 : deleted();
2648 :
2649 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2650 :
2651 : // Process instanciated children...
2652 :
2653 0 : ::webdav_ucp::Content::ContentRefList aChildren;
2654 0 : queryChildren( aChildren );
2655 :
2656 0 : ContentRefList::const_iterator it = aChildren.begin();
2657 0 : ContentRefList::const_iterator end = aChildren.end();
2658 :
2659 0 : while ( it != end )
2660 : {
2661 0 : (*it)->destroy( bDeletePhysical );
2662 0 : ++it;
2663 0 : }
2664 0 : }
2665 :
2666 : //=========================================================================
2667 0 : bool Content::supportsExclusiveWriteLock(
2668 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
2669 : {
2670 0 : if ( getResourceType( Environment ) == DAV )
2671 : {
2672 0 : if ( m_xCachedProps.get() )
2673 : {
2674 0 : uno::Sequence< ucb::LockEntry > aSupportedLocks;
2675 0 : if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK )
2676 0 : >>= aSupportedLocks )
2677 : {
2678 0 : for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
2679 : {
2680 0 : if ( aSupportedLocks[ n ].Scope
2681 0 : == ucb::LockScope_EXCLUSIVE &&
2682 0 : aSupportedLocks[ n ].Type
2683 0 : == ucb::LockType_WRITE )
2684 0 : return true;
2685 : }
2686 0 : }
2687 : }
2688 : }
2689 0 : return false;
2690 : }
2691 :
2692 : //=========================================================================
2693 0 : void Content::lock(
2694 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
2695 : throw( uno::Exception )
2696 : {
2697 : try
2698 : {
2699 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2700 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2701 : SAL_WNODEPRECATED_DECLARATIONS_POP
2702 : {
2703 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2704 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2705 : }
2706 :
2707 0 : uno::Any aOwnerAny;
2708 : aOwnerAny
2709 0 : <<= OUString("http://ucb.openoffice.org");
2710 :
2711 : ucb::Lock aLock(
2712 : ucb::LockScope_EXCLUSIVE,
2713 : ucb::LockType_WRITE,
2714 : ucb::LockDepth_ZERO,
2715 : aOwnerAny,
2716 : 180, // lock timeout in secs
2717 : //-1, // infinite lock
2718 0 : uno::Sequence< OUString >() );
2719 :
2720 0 : xResAccess->LOCK( aLock, Environment );
2721 :
2722 : {
2723 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2724 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2725 0 : }
2726 : }
2727 0 : catch ( DAVException const & e )
2728 : {
2729 0 : cancelCommandExecution( e, Environment, sal_False );
2730 : // Unreachable
2731 : }
2732 0 : }
2733 :
2734 : //=========================================================================
2735 0 : void Content::unlock(
2736 : const uno::Reference< ucb::XCommandEnvironment >& Environment )
2737 : throw( uno::Exception )
2738 : {
2739 : try
2740 : {
2741 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2742 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
2743 : SAL_WNODEPRECATED_DECLARATIONS_POP
2744 : {
2745 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2746 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2747 : }
2748 :
2749 0 : xResAccess->UNLOCK( Environment );
2750 :
2751 : {
2752 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2753 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2754 0 : }
2755 : }
2756 0 : catch ( DAVException const & e )
2757 : {
2758 0 : cancelCommandExecution( e, Environment, sal_False );
2759 : // Unreachable
2760 : }
2761 0 : }
2762 :
2763 : //=========================================================================
2764 0 : sal_Bool Content::exchangeIdentity(
2765 : const uno::Reference< ucb::XContentIdentifier >& xNewId )
2766 : {
2767 0 : if ( !xNewId.is() )
2768 0 : return sal_False;
2769 :
2770 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2771 :
2772 0 : uno::Reference< ucb::XContent > xThis = this;
2773 :
2774 : // Already persistent?
2775 0 : if ( m_bTransient )
2776 : {
2777 : OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2778 0 : return sal_False;
2779 : }
2780 :
2781 : // Exchange own identitity.
2782 :
2783 : // Fail, if a content with given id already exists.
2784 : // if ( !hasData( xNewId ) )
2785 : {
2786 0 : OUString aOldURL = m_xIdentifier->getContentIdentifier();
2787 :
2788 0 : aGuard.clear();
2789 0 : if ( exchange( xNewId ) )
2790 : {
2791 : // Process instanciated children...
2792 :
2793 0 : ContentRefList aChildren;
2794 0 : queryChildren( aChildren );
2795 :
2796 0 : ContentRefList::const_iterator it = aChildren.begin();
2797 0 : ContentRefList::const_iterator end = aChildren.end();
2798 :
2799 0 : while ( it != end )
2800 : {
2801 0 : ContentRef xChild = (*it);
2802 :
2803 : // Create new content identifier for the child...
2804 : uno::Reference< ucb::XContentIdentifier >
2805 0 : xOldChildId = xChild->getIdentifier();
2806 : OUString aOldChildURL
2807 0 : = xOldChildId->getContentIdentifier();
2808 : OUString aNewChildURL
2809 : = aOldChildURL.replaceAt(
2810 : 0,
2811 : aOldURL.getLength(),
2812 0 : xNewId->getContentIdentifier() );
2813 : uno::Reference< ucb::XContentIdentifier > xNewChildId
2814 0 : = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2815 :
2816 0 : if ( !xChild->exchangeIdentity( xNewChildId ) )
2817 0 : return sal_False;
2818 :
2819 0 : ++it;
2820 0 : }
2821 0 : return sal_True;
2822 0 : }
2823 : }
2824 :
2825 : OSL_FAIL( "Content::exchangeIdentity - "
2826 : "Panic! Cannot exchange identity!" );
2827 0 : return sal_False;
2828 : }
2829 :
2830 : //=========================================================================
2831 0 : sal_Bool Content::isFolder(
2832 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
2833 : throw( uno::Exception )
2834 : {
2835 : {
2836 0 : osl::MutexGuard aGuard( m_aMutex );
2837 :
2838 0 : if ( m_bTransient )
2839 0 : return m_bCollection;
2840 : }
2841 :
2842 0 : uno::Sequence< beans::Property > aProperties( 1 );
2843 0 : aProperties[ 0 ].Name = OUString("IsFolder");
2844 0 : aProperties[ 0 ].Handle = -1;
2845 0 : uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) );
2846 0 : if ( xRow.is() )
2847 : {
2848 : try
2849 : {
2850 0 : return xRow->getBoolean( 1 );
2851 : }
2852 0 : catch ( sdbc::SQLException const & )
2853 : {
2854 : }
2855 : }
2856 :
2857 0 : return sal_False;
2858 : }
2859 :
2860 : //=========================================================================
2861 0 : uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite )
2862 : {
2863 : // Map DAVException...
2864 0 : uno::Any aException;
2865 :
2866 0 : OUString aURL;
2867 0 : if ( m_bTransient )
2868 : {
2869 0 : aURL = getParentURL();
2870 0 : if ( aURL.lastIndexOf('/') != ( aURL.getLength() - 1 ) )
2871 0 : aURL += OUString(static_cast<sal_Unicode>('/'));
2872 :
2873 0 : aURL += m_aEscapedTitle;
2874 : }
2875 : else
2876 : {
2877 0 : aURL = m_xIdentifier->getContentIdentifier();
2878 : }
2879 :
2880 0 : switch ( e.getStatus() )
2881 : {
2882 : case SC_NOT_FOUND:
2883 : {
2884 0 : uno::Sequence< uno::Any > aArgs( 1 );
2885 0 : aArgs[ 0 ] <<= beans::PropertyValue(
2886 : OUString("Uri"), -1,
2887 : uno::makeAny(aURL),
2888 0 : beans::PropertyState_DIRECT_VALUE);
2889 :
2890 0 : aException <<=
2891 : ucb::InteractiveAugmentedIOException(
2892 : OUString("Not found!"),
2893 : static_cast< cppu::OWeakObject * >( this ),
2894 : task::InteractionClassification_ERROR,
2895 : ucb::IOErrorCode_NOT_EXISTING,
2896 0 : aArgs );
2897 0 : return aException;
2898 : }
2899 : default:
2900 0 : break;
2901 : }
2902 :
2903 0 : switch ( e.getError() )
2904 : {
2905 : case DAVException::DAV_HTTP_ERROR:
2906 : {
2907 0 : if ( bWrite )
2908 0 : aException <<=
2909 : ucb::InteractiveNetworkWriteException(
2910 0 : e.getData(),
2911 : static_cast< cppu::OWeakObject * >( this ),
2912 : task::InteractionClassification_ERROR,
2913 0 : e.getData() );
2914 : else
2915 0 : aException <<=
2916 : ucb::InteractiveNetworkReadException(
2917 0 : e.getData(),
2918 : static_cast< cppu::OWeakObject * >( this ),
2919 : task::InteractionClassification_ERROR,
2920 0 : e.getData() );
2921 0 : break;
2922 : }
2923 :
2924 : case DAVException::DAV_HTTP_LOOKUP:
2925 0 : aException <<=
2926 : ucb::InteractiveNetworkResolveNameException(
2927 : OUString(),
2928 : static_cast< cppu::OWeakObject * >( this ),
2929 : task::InteractionClassification_ERROR,
2930 0 : e.getData() );
2931 0 : break;
2932 :
2933 : // @@@ No matching InteractiveNetwork*Exception
2934 : // case DAVException::DAV_HTTP_AUTH:
2935 : // break;
2936 :
2937 : // @@@ No matching InteractiveNetwork*Exception
2938 : // case DAVException::DAV_HTTP_AUTHPROXY:
2939 : // break;
2940 :
2941 : case DAVException::DAV_HTTP_CONNECT:
2942 0 : aException <<=
2943 : ucb::InteractiveNetworkConnectException(
2944 : OUString(),
2945 : static_cast< cppu::OWeakObject * >( this ),
2946 : task::InteractionClassification_ERROR,
2947 0 : e.getData() );
2948 0 : break;
2949 :
2950 : // @@@ No matching InteractiveNetwork*Exception
2951 : // case DAVException::DAV_HTTP_TIMEOUT:
2952 : // break;
2953 :
2954 : // @@@ No matching InteractiveNetwork*Exception
2955 : // case DAVException::DAV_HTTP_REDIRECT:
2956 : // break;
2957 :
2958 : // @@@ No matching InteractiveNetwork*Exception
2959 : // case DAVException::DAV_SESSION_CREATE:
2960 : // break;
2961 :
2962 : case DAVException::DAV_INVALID_ARG:
2963 0 : aException <<=
2964 : lang::IllegalArgumentException(
2965 : OUString(),
2966 : static_cast< cppu::OWeakObject * >( this ),
2967 0 : -1 );
2968 0 : break;
2969 :
2970 : case DAVException::DAV_LOCKED:
2971 0 : aException <<=
2972 : ucb::InteractiveLockingLockedException(
2973 : OUString("Locked!"),
2974 : static_cast< cppu::OWeakObject * >( this ),
2975 : task::InteractionClassification_ERROR,
2976 : aURL,
2977 0 : sal_False ); // not SelfOwned
2978 0 : break;
2979 :
2980 : case DAVException::DAV_LOCKED_SELF:
2981 0 : aException <<=
2982 : ucb::InteractiveLockingLockedException(
2983 : OUString("Locked (self!)"),
2984 : static_cast< cppu::OWeakObject * >( this ),
2985 : task::InteractionClassification_ERROR,
2986 : aURL,
2987 0 : sal_True ); // SelfOwned
2988 0 : break;
2989 :
2990 : case DAVException::DAV_NOT_LOCKED:
2991 0 : aException <<=
2992 : ucb::InteractiveLockingNotLockedException(
2993 : OUString("Not locked!"),
2994 : static_cast< cppu::OWeakObject * >( this ),
2995 : task::InteractionClassification_ERROR,
2996 0 : aURL );
2997 0 : break;
2998 :
2999 : case DAVException::DAV_LOCK_EXPIRED:
3000 0 : aException <<=
3001 : ucb::InteractiveLockingLockExpiredException(
3002 : OUString("Lock expired!"),
3003 : static_cast< cppu::OWeakObject * >( this ),
3004 : task::InteractionClassification_ERROR,
3005 0 : aURL );
3006 0 : break;
3007 :
3008 : default:
3009 0 : aException <<=
3010 : ucb::InteractiveNetworkGeneralException(
3011 : OUString(),
3012 : static_cast< cppu::OWeakObject * >( this ),
3013 0 : task::InteractionClassification_ERROR );
3014 0 : break;
3015 : }
3016 :
3017 0 : return aException;
3018 : }
3019 :
3020 : //=========================================================================
3021 : // static
3022 0 : bool Content::shouldAccessNetworkAfterException( const DAVException & e )
3023 : {
3024 0 : if ( ( e.getStatus() == SC_NOT_FOUND ) ||
3025 0 : ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) ||
3026 0 : ( e.getError() == DAVException::DAV_HTTP_CONNECT ) ||
3027 0 : ( e.getError() == DAVException::DAV_HTTP_AUTH ) ||
3028 0 : ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY ) )
3029 0 : return false;
3030 :
3031 0 : return true;
3032 : }
3033 :
3034 : //=========================================================================
3035 0 : void Content::cancelCommandExecution(
3036 : const DAVException & e,
3037 : const uno::Reference< ucb::XCommandEnvironment > & xEnv,
3038 : sal_Bool bWrite /* = sal_False */ )
3039 : throw ( uno::Exception )
3040 : {
3041 0 : ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv );
3042 : // Unreachable
3043 0 : }
3044 :
3045 : //=========================================================================
3046 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3047 : const OUString
3048 0 : Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess )
3049 : {
3050 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
3051 :
3052 : // First, try to obtain value of response header "Content-Location".
3053 0 : if ( m_xCachedProps.get() )
3054 : {
3055 0 : OUString aLocation;
3056 0 : m_xCachedProps->getValue( OUString( "Content-Location" ) ) >>= aLocation;
3057 0 : if ( !aLocation.isEmpty() )
3058 : {
3059 : try
3060 : {
3061 : // Do not use m_xIdentifier->getContentIdentifier() because it
3062 : // for example does not reflect redirects applied to requests
3063 : // done using the original URI but m_xResAccess' URI does.
3064 0 : return rtl::Uri::convertRelToAbs( rResAccess->getURL(),
3065 0 : aLocation );
3066 : }
3067 0 : catch ( rtl::MalformedUriException const & )
3068 : {
3069 : }
3070 0 : }
3071 : }
3072 :
3073 0 : return OUString( rResAccess->getURL() );
3074 : }
3075 :
3076 : //=========================================================================
3077 0 : Content::ResourceType Content::getResourceType(
3078 : const uno::Reference< ucb::XCommandEnvironment >& xEnv,
3079 : const std::auto_ptr< DAVResourceAccess > & rResAccess,
3080 : bool * networkAccessAllowed)
3081 : throw ( uno::Exception )
3082 : {
3083 : {
3084 0 : osl::MutexGuard g(m_aMutex);
3085 0 : if (m_eResourceType != UNKNOWN) {
3086 0 : return m_eResourceType;
3087 0 : }
3088 : }
3089 :
3090 0 : ResourceType eResourceType = UNKNOWN;
3091 :
3092 0 : const OUString & rURL = rResAccess->getURL();
3093 : const OUString aScheme(
3094 0 : rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() );
3095 :
3096 0 : if ( aScheme == FTP_URL_SCHEME )
3097 : {
3098 0 : eResourceType = FTP;
3099 : }
3100 : else
3101 : {
3102 : try
3103 : {
3104 : // Try to fetch some frequently used property value, e.g. those
3105 : // used when loading documents... along with identifying whether
3106 : // this is a DAV resource.
3107 0 : std::vector< DAVResource > resources;
3108 0 : std::vector< OUString > aPropNames;
3109 0 : uno::Sequence< beans::Property > aProperties( 5 );
3110 0 : aProperties[ 0 ].Name = OUString("IsFolder");
3111 0 : aProperties[ 1 ].Name = OUString("IsDocument");
3112 0 : aProperties[ 2 ].Name = OUString("IsReadOnly");
3113 0 : aProperties[ 3 ].Name = OUString("MediaType");
3114 0 : aProperties[ 4 ].Name = DAVProperties::SUPPORTEDLOCK;
3115 :
3116 0 : ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames );
3117 :
3118 0 : rResAccess->PROPFIND( DAVZERO, aPropNames, resources, xEnv );
3119 :
3120 0 : if ( resources.size() == 1 )
3121 : {
3122 0 : osl::MutexGuard g(m_aMutex);
3123 : m_xCachedProps.reset(
3124 0 : new CachableContentProperties( resources[ 0 ] ) );
3125 : m_xCachedProps->containsAllNames(
3126 0 : aProperties, m_aFailedPropNames );
3127 : }
3128 :
3129 0 : eResourceType = DAV;
3130 : }
3131 0 : catch ( DAVException const & e )
3132 : {
3133 0 : rResAccess->resetUri();
3134 :
3135 0 : if ( e.getStatus() == SC_METHOD_NOT_ALLOWED )
3136 : {
3137 : // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the
3138 : // resource is NON_DAV
3139 0 : eResourceType = NON_DAV;
3140 : }
3141 0 : else if (networkAccessAllowed != 0)
3142 : {
3143 : *networkAccessAllowed = *networkAccessAllowed
3144 0 : && shouldAccessNetworkAfterException(e);
3145 : }
3146 : }
3147 : }
3148 :
3149 0 : osl::MutexGuard g(m_aMutex);
3150 0 : if (m_eResourceType == UNKNOWN) {
3151 0 : m_eResourceType = eResourceType;
3152 : } else {
3153 : SAL_WARN_IF(
3154 : eResourceType != m_eResourceType, "ucb.ucp.webdav",
3155 : "different resource types for <" << rURL << ">: "
3156 : << +eResourceType << " vs. " << +m_eResourceType);
3157 : }
3158 0 : return m_eResourceType;
3159 : }
3160 : SAL_WNODEPRECATED_DECLARATIONS_POP
3161 :
3162 : //=========================================================================
3163 0 : Content::ResourceType Content::getResourceType(
3164 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
3165 : throw ( uno::Exception )
3166 : {
3167 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
3168 0 : std::auto_ptr< DAVResourceAccess > xResAccess;
3169 : SAL_WNODEPRECATED_DECLARATIONS_POP
3170 : {
3171 0 : osl::MutexGuard aGuard( m_aMutex );
3172 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
3173 : }
3174 0 : Content::ResourceType const ret = getResourceType( xEnv, xResAccess );
3175 : {
3176 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
3177 0 : m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
3178 : }
3179 0 : return ret;
3180 : }
3181 :
3182 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|