Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / webdavcontent.cxx
blobff1b86c563b39fb03d507829507ce6bae2ffaaed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 /**************************************************************************
31 TODO
32 **************************************************************************
34 *************************************************************************/
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>
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/PropertyCommandArgument.hpp>
76 #include <com/sun/star/ucb/TransferInfo.hpp>
77 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
78 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
79 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
80 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
81 #include <com/sun/star/ucb/XCommandInfo.hpp>
82 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
83 #include <com/sun/star/uno/XComponentContext.hpp>
85 #include "webdavcontent.hxx"
86 #include "webdavprovider.hxx"
87 #include "webdavresultset.hxx"
88 #include "ContentProperties.hxx"
89 #include "NeonUri.hxx"
90 #include "UCBDeadPropertyValue.hxx"
92 using namespace com::sun::star;
93 using namespace webdav_ucp;
98 // Content Implementation.
104 // ctr for content on an existing webdav resource
105 Content::Content(
106 const uno::Reference< uno::XComponentContext >& rxContext,
107 ContentProvider* pProvider,
108 const uno::Reference< ucb::XContentIdentifier >& Identifier,
109 rtl::Reference< DAVSessionFactory > const & rSessionFactory )
110 throw ( ucb::ContentCreationException )
111 : ContentImplHelper( rxContext, pProvider, Identifier ),
112 m_eResourceType( UNKNOWN ),
113 m_pProvider( pProvider ),
114 m_bTransient( false ),
115 m_bCollection( false ),
116 m_bDidGetOrHead( false )
120 m_xResAccess.reset( new DAVResourceAccess(
121 rxContext,
122 rSessionFactory,
123 Identifier->getContentIdentifier() ) );
125 NeonUri aURI( Identifier->getContentIdentifier() );
126 m_aEscapedTitle = aURI.GetPathBaseName();
128 catch ( DAVException const & )
130 throw ucb::ContentCreationException();
135 // ctr for content on an non-existing webdav resource
136 Content::Content(
137 const uno::Reference< uno::XComponentContext >& rxContext,
138 ContentProvider* pProvider,
139 const uno::Reference< ucb::XContentIdentifier >& Identifier,
140 rtl::Reference< DAVSessionFactory > const & rSessionFactory,
141 bool isCollection )
142 throw ( ucb::ContentCreationException )
143 : ContentImplHelper( rxContext, pProvider, Identifier ),
144 m_eResourceType( UNKNOWN ),
145 m_pProvider( pProvider ),
146 m_bTransient( true ),
147 m_bCollection( isCollection ),
148 m_bDidGetOrHead( false )
152 m_xResAccess.reset( new DAVResourceAccess(
153 rxContext, rSessionFactory, Identifier->getContentIdentifier() ) );
155 catch ( DAVException const & )
157 throw ucb::ContentCreationException();
160 // Do not set m_aEscapedTitle here! Content::insert relays on this!!!
164 // virtual
165 Content::~Content()
171 // XInterface methods.
175 // virtual
176 void SAL_CALL Content::acquire()
177 throw( )
179 ContentImplHelper::acquire();
183 // virtual
184 void SAL_CALL Content::release()
185 throw( )
187 ContentImplHelper::release();
191 // virtual
192 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
193 throw ( uno::RuntimeException, std::exception )
195 // Note: isFolder may require network activities! So call it only
196 // if it is really necessary!!!
197 uno::Any aRet = cppu::queryInterface(
198 rType,
199 static_cast< ucb::XContentCreator * >( this ) );
200 if ( aRet.hasValue() )
204 uno::Reference< task::XInteractionHandler > xIH(
205 task::PasswordContainerInteractionHandler::create( m_xContext ) );
207 // Supply a command env to isFolder() that contains an interaction
208 // handler that uses the password container service to obtain
209 // credentials without displaying a password gui.
211 uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
212 ucb::CommandEnvironment::create(
213 m_xContext,
214 xIH,
215 uno::Reference< ucb::XProgressHandler >() ) );
217 return isFolder( xCmdEnv ) ? aRet : uno::Any();
219 catch ( uno::RuntimeException const & )
221 throw;
223 catch ( uno::Exception const & )
225 return uno::Any();
228 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
233 // XTypeProvider methods.
237 XTYPEPROVIDER_COMMON_IMPL( Content );
240 // virtual
241 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
242 throw( uno::RuntimeException, std::exception )
244 bool bFolder = false;
247 bFolder
248 = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
250 catch ( uno::RuntimeException const & )
252 throw;
254 catch ( uno::Exception const & )
258 cppu::OTypeCollection * pCollection = 0;
260 if ( bFolder )
262 static cppu::OTypeCollection* pFolderTypes = 0;
264 pCollection = pFolderTypes;
265 if ( !pCollection )
267 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
269 pCollection = pFolderTypes;
270 if ( !pCollection )
272 static cppu::OTypeCollection aCollection(
273 CPPU_TYPE_REF( lang::XTypeProvider ),
274 CPPU_TYPE_REF( lang::XServiceInfo ),
275 CPPU_TYPE_REF( lang::XComponent ),
276 CPPU_TYPE_REF( ucb::XContent ),
277 CPPU_TYPE_REF( ucb::XCommandProcessor ),
278 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
279 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
280 CPPU_TYPE_REF( beans::XPropertyContainer ),
281 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
282 CPPU_TYPE_REF( container::XChild ),
283 CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
284 pCollection = &aCollection;
285 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
286 pFolderTypes = pCollection;
289 else {
290 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
293 else
295 static cppu::OTypeCollection* pDocumentTypes = 0;
297 pCollection = pDocumentTypes;
298 if ( !pCollection )
300 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
302 pCollection = pDocumentTypes;
303 if ( !pCollection )
305 static cppu::OTypeCollection aCollection(
306 CPPU_TYPE_REF( lang::XTypeProvider ),
307 CPPU_TYPE_REF( lang::XServiceInfo ),
308 CPPU_TYPE_REF( lang::XComponent ),
309 CPPU_TYPE_REF( ucb::XContent ),
310 CPPU_TYPE_REF( ucb::XCommandProcessor ),
311 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
312 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
313 CPPU_TYPE_REF( beans::XPropertyContainer ),
314 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
315 CPPU_TYPE_REF( container::XChild ) );
316 pCollection = &aCollection;
317 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
318 pDocumentTypes = pCollection;
321 else {
322 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
326 return (*pCollection).getTypes();
331 // XServiceInfo methods.
335 // virtual
336 OUString SAL_CALL Content::getImplementationName()
337 throw( uno::RuntimeException, std::exception )
339 return OUString( "com.sun.star.comp.ucb.WebDAVContent" );
343 // virtual
344 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
345 throw( uno::RuntimeException, std::exception )
347 uno::Sequence< OUString > aSNS( 1 );
348 aSNS[ 0 ] = WEBDAV_CONTENT_SERVICE_NAME;
349 return aSNS;
354 // XContent methods.
358 // virtual
359 OUString SAL_CALL Content::getContentType()
360 throw( uno::RuntimeException, std::exception )
362 bool bFolder = false;
365 bFolder
366 = isFolder( uno::Reference< ucb::XCommandEnvironment >() );
368 catch ( uno::RuntimeException const & )
370 throw;
372 catch ( uno::Exception const & )
376 if ( bFolder )
377 return OUString( WEBDAV_COLLECTION_TYPE );
379 return OUString( WEBDAV_CONTENT_TYPE );
384 // XCommandProcessor methods.
388 // virtual
389 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, std::exception )
397 SAL_INFO( "ucb.ucp.webdav", "Content::execute: start: command: " <<
398 aCommand.Name << ", env: " <<
399 (Environment.is() ? "present" : "missing") );
401 uno::Any aRet;
403 if ( aCommand.Name == "getPropertyValues" )
406 // getPropertyValues
409 uno::Sequence< beans::Property > Properties;
410 if ( !( aCommand.Argument >>= Properties ) )
412 ucbhelper::cancelCommandExecution(
413 uno::makeAny( lang::IllegalArgumentException(
414 OUString( "Wrong argument type!" ),
415 static_cast< cppu::OWeakObject * >( this ),
416 -1 ) ),
417 Environment );
418 // Unreachable
421 aRet <<= getPropertyValues( Properties, Environment );
423 else if ( aCommand.Name == "setPropertyValues" )
426 // setPropertyValues
429 uno::Sequence< beans::PropertyValue > aProperties;
430 if ( !( aCommand.Argument >>= aProperties ) )
432 ucbhelper::cancelCommandExecution(
433 uno::makeAny( lang::IllegalArgumentException(
434 OUString( "Wrong argument type!" ),
435 static_cast< cppu::OWeakObject * >( this ),
436 -1 ) ),
437 Environment );
438 // Unreachable
441 if ( !aProperties.getLength() )
443 ucbhelper::cancelCommandExecution(
444 uno::makeAny( lang::IllegalArgumentException(
445 OUString( "No properties!" ),
446 static_cast< cppu::OWeakObject * >( this ),
447 -1 ) ),
448 Environment );
449 // Unreachable
452 aRet <<= setPropertyValues( aProperties, Environment );
454 else if ( aCommand.Name == "getPropertySetInfo" )
457 // getPropertySetInfo
460 // Note: Implemented by base class.
461 aRet <<= getPropertySetInfo( Environment,
462 false /* don't cache data */ );
464 else if ( aCommand.Name == "getCommandInfo" )
467 // getCommandInfo
470 // Note: Implemented by base class.
471 aRet <<= getCommandInfo( Environment, false );
473 else if ( aCommand.Name == "open" )
476 // open
479 ucb::OpenCommandArgument3 aOpenCommand;
480 ucb::OpenCommandArgument2 aTmp;
481 if ( !( aCommand.Argument >>= aTmp ) )
483 ucbhelper::cancelCommandExecution(
484 uno::makeAny( lang::IllegalArgumentException(
485 OUString( "Wrong argument type!" ),
486 static_cast< cppu::OWeakObject * >( this ),
487 -1 ) ),
488 Environment );
489 // Unreachable
491 if ( !( aCommand.Argument >>= aOpenCommand ) )
493 // compat mode, extract Arg2 info into newer structure
494 aOpenCommand.Mode = aTmp.Mode;
495 aOpenCommand.Priority = aTmp.Priority;
496 aOpenCommand.Sink = aTmp.Sink;
497 aOpenCommand.Properties = aTmp.Properties;
498 aOpenCommand.SortingInfo = aTmp.SortingInfo;
501 aRet = open( aOpenCommand, Environment );
503 if ( (aOpenCommand.Mode == ucb::OpenMode::DOCUMENT ||
504 aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE) &&
505 supportsExclusiveWriteLock( Environment ) )
506 lock( Environment );
508 else if ( aCommand.Name == "insert" )
511 // insert
514 ucb::InsertCommandArgument arg;
515 if ( !( aCommand.Argument >>= arg ) )
517 ucbhelper::cancelCommandExecution(
518 uno::makeAny( lang::IllegalArgumentException(
519 OUString( "Wrong argument type!" ),
520 static_cast< cppu::OWeakObject * >( this ),
521 -1 ) ),
522 Environment );
523 // Unreachable
526 insert( arg.Data, arg.ReplaceExisting, Environment );
528 else if ( aCommand.Name == "delete" )
531 // delete
534 bool bDeletePhysical = false;
535 aCommand.Argument >>= bDeletePhysical;
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 // {
544 SAL_WNODEPRECATED_DECLARATIONS_PUSH
545 std::auto_ptr< DAVResourceAccess > xResAccess;
546 SAL_WNODEPRECATED_DECLARATIONS_POP
548 osl::Guard< osl::Mutex > aGuard( m_aMutex );
549 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
551 xResAccess->DESTROY( Environment );
553 osl::Guard< osl::Mutex > aGuard( m_aMutex );
554 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
557 catch ( DAVException const & e )
559 cancelCommandExecution( e, Environment, true );
560 // Unreachable
562 // }
564 // Propagate destruction.
565 destroy( bDeletePhysical );
567 // Remove own and all children's Additional Core Properties.
568 removeAdditionalPropertySet( true );
570 else if ( aCommand.Name == "transfer" && isFolder( Environment ) )
573 // transfer
574 // ( Not available at documents )
577 ucb::TransferInfo transferArgs;
578 if ( !( aCommand.Argument >>= transferArgs ) )
580 ucbhelper::cancelCommandExecution(
581 uno::makeAny( lang::IllegalArgumentException(
582 OUString( "Wrong argument type!" ),
583 static_cast< cppu::OWeakObject * >( this ),
584 -1 ) ),
585 Environment );
586 // Unreachable
589 transfer( transferArgs, Environment );
591 else if ( aCommand.Name == "post" )
594 // post
597 ucb::PostCommandArgument2 aArg;
598 if ( !( aCommand.Argument >>= aArg ) )
600 ucbhelper::cancelCommandExecution(
601 uno::makeAny( lang::IllegalArgumentException(
602 OUString( "Wrong argument type!" ),
603 static_cast< cppu::OWeakObject * >( this ),
604 -1 ) ),
605 Environment );
606 // Unreachable
609 post( aArg, Environment );
611 else if ( aCommand.Name == "lock" && supportsExclusiveWriteLock( Environment ) )
614 // lock
617 lock( Environment );
619 else if ( aCommand.Name == "unlock" && supportsExclusiveWriteLock( Environment ) )
622 // unlock
625 unlock( Environment );
627 else if ( aCommand.Name == "createNewContent" && isFolder( Environment ) )
630 // createNewContent
633 ucb::ContentInfo aArg;
634 if ( !( aCommand.Argument >>= aArg ) )
636 ucbhelper::cancelCommandExecution(
637 uno::makeAny( lang::IllegalArgumentException(
638 OUString( "Wrong argument type!" ),
639 static_cast< cppu::OWeakObject * >( this ),
640 -1 ) ),
641 Environment );
642 // Unreachable
645 aRet = uno::makeAny( createNewContent( aArg ) );
647 else if ( aCommand.Name == "addProperty" )
649 ucb::PropertyCommandArgument aPropArg;
650 if ( !( aCommand.Argument >>= aPropArg ))
652 ucbhelper::cancelCommandExecution(
653 uno::makeAny( lang::IllegalArgumentException(
654 "Wrong argument type!",
655 static_cast< cppu::OWeakObject * >( this ),
656 -1 ) ),
657 Environment );
660 // TODO when/if XPropertyContainer is removed,
661 // the command execution can be canceled in addProperty
664 addProperty( aPropArg, Environment );
666 catch ( const beans::PropertyExistException &e )
668 ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment );
670 catch ( const beans::IllegalTypeException&e )
672 ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment );
674 catch ( const lang::IllegalArgumentException&e )
676 ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment );
679 else if ( aCommand.Name == "removeProperty" )
681 OUString sPropName;
682 if ( !( aCommand.Argument >>= sPropName ) )
684 ucbhelper::cancelCommandExecution(
685 uno::makeAny( lang::IllegalArgumentException(
686 "Wrong argument type!",
687 static_cast< cppu::OWeakObject * >( this ),
688 -1 ) ),
689 Environment );
692 // TODO when/if XPropertyContainer is removed,
693 // the command execution can be canceled in removeProperty
696 removeProperty( sPropName, Environment );
698 catch( const beans::UnknownPropertyException &e )
700 ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment );
702 catch( const beans::NotRemoveableException &e )
704 ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment );
707 else
710 // Unsupported command
713 ucbhelper::cancelCommandExecution(
714 uno::makeAny( ucb::UnsupportedCommandException(
715 aCommand.Name,
716 static_cast< cppu::OWeakObject * >( this ) ) ),
717 Environment );
718 // Unreachable
721 OSL_TRACE( "<<<<< Content::execute: end: command: %s",
722 OUStringToOString( aCommand.Name,
723 RTL_TEXTENCODING_UTF8 ).getStr() );
725 return aRet;
729 // virtual
730 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
731 throw( uno::RuntimeException, std::exception )
735 SAL_WNODEPRECATED_DECLARATIONS_PUSH
736 std::auto_ptr< DAVResourceAccess > xResAccess;
737 SAL_WNODEPRECATED_DECLARATIONS_POP
739 osl::MutexGuard aGuard( m_aMutex );
740 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
742 xResAccess->abort();
744 osl::Guard< osl::Mutex > aGuard( m_aMutex );
745 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
748 catch ( DAVException const & )
750 // abort failed!
756 // XPropertyContainer methods.
760 void Content::addProperty( const ucb::PropertyCommandArgument& aCmdArg,
761 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
762 throw( beans::PropertyExistException,
763 beans::IllegalTypeException,
764 lang::IllegalArgumentException,
765 uno::RuntimeException )
767 // if ( m_bTransient )
768 // @@@ ???
770 if ( aCmdArg.Property.Name.isEmpty() )
771 throw lang::IllegalArgumentException(
772 "\"addProperty\" with empty Property.Name",
773 static_cast< cppu::OWeakObject * >( this ),
774 -1 );
776 // Check property type.
777 if ( !UCBDeadPropertyValue::supportsType( aCmdArg.Property.Type ) )
779 throw beans::IllegalTypeException(
780 "\"addProperty\" unsupported Property.Type",
781 static_cast< cppu::OWeakObject * >( this ) );
784 if ( aCmdArg.DefaultValue.hasValue()
785 && aCmdArg.DefaultValue.getValueType() != aCmdArg.Property.Type )
787 throw beans::IllegalTypeException(
788 "\"addProperty\" DefaultValue does not match Property.Type",
789 static_cast< ::cppu::OWeakObject * >( this ) );
793 // Make sure a property with the requested name does not already
794 // exist in dynamic and static(!) properties.
797 // Take into account special properties with custom namespace
798 // using <prop:the_propname xmlns:prop="the_namespace">
799 OUString aSpecialName;
800 bool bIsSpecial = DAVProperties::isUCBSpecialProperty(
801 aCmdArg.Property.Name, aSpecialName );
803 // Note: This requires network access!
804 if ( getPropertySetInfo( xEnv, false /* don't cache data */ )
805 ->hasPropertyByName(
806 bIsSpecial ? aSpecialName : aCmdArg.Property.Name ) )
808 // Property does already exist.
809 throw beans::PropertyExistException();
813 // Add a new dynamic property.
816 ProppatchValue aValue(
817 PROPSET, aCmdArg.Property.Name, aCmdArg.DefaultValue );
819 std::vector< ProppatchValue > aProppatchValues;
820 aProppatchValues.push_back( aValue );
824 // Set property value at server.
825 SAL_WNODEPRECATED_DECLARATIONS_PUSH
826 std::auto_ptr< DAVResourceAccess > xResAccess;
827 SAL_WNODEPRECATED_DECLARATIONS_POP
829 osl::Guard< osl::Mutex > aGuard( m_aMutex );
830 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
832 xResAccess->PROPPATCH( aProppatchValues, xEnv );
834 osl::Guard< osl::Mutex > aGuard( m_aMutex );
835 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
838 // Notify propertyset info change listeners.
839 beans::PropertySetInfoChangeEvent evt(
840 static_cast< cppu::OWeakObject * >( this ),
841 bIsSpecial ? aSpecialName : aCmdArg.Property.Name,
842 -1, // No handle available
843 beans::PropertySetInfoChange::PROPERTY_INSERTED );
844 notifyPropertySetInfoChange( evt );
846 catch ( DAVException const & e )
848 if ( e.getStatus() == SC_FORBIDDEN )
850 // Support for setting arbitrary dead properties is optional!
852 // Store property locally.
853 ContentImplHelper::addProperty(
854 bIsSpecial ? aSpecialName : aCmdArg.Property.Name,
855 aCmdArg.Property.Attributes, aCmdArg.DefaultValue );
857 else
859 if ( shouldAccessNetworkAfterException( e ) )
863 ResourceType eType = getResourceType( xEnv );
864 switch ( eType )
866 case UNKNOWN:
867 case DAV:
868 throw lang::IllegalArgumentException();
870 case FTP:
871 case NON_DAV:
872 // Store property locally.
873 ContentImplHelper::addProperty(
874 bIsSpecial ? aSpecialName : aCmdArg.Property.Name,
875 aCmdArg.Property.Attributes, aCmdArg.DefaultValue );
876 break;
878 default:
879 OSL_FAIL( "Content::addProperty - "
880 "Unsupported resource type!" );
881 break;
884 catch ( uno::Exception const & )
886 OSL_FAIL( "Content::addProperty - "
887 "Unable to determine resource type!" );
890 else
892 OSL_FAIL( "Content::addProperty - "
893 "Unable to determine resource type!" );
899 void Content::removeProperty( const OUString& Name,
900 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
901 throw( beans::UnknownPropertyException,
902 beans::NotRemoveableException,
903 uno::RuntimeException )
906 // Try to remove property from server.
911 std::vector< ProppatchValue > aProppatchValues;
912 ProppatchValue aValue( PROPREMOVE, Name, uno::Any() );
913 aProppatchValues.push_back( aValue );
915 // Remove property value from server.
916 SAL_WNODEPRECATED_DECLARATIONS_PUSH
917 std::auto_ptr< DAVResourceAccess > xResAccess;
918 SAL_WNODEPRECATED_DECLARATIONS_POP
920 osl::Guard< osl::Mutex > aGuard( m_aMutex );
921 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
923 xResAccess->PROPPATCH( aProppatchValues, xEnv );
925 osl::Guard< osl::Mutex > aGuard( m_aMutex );
926 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
929 // Notify propertyset info change listeners.
930 beans::PropertySetInfoChangeEvent evt(
931 static_cast< cppu::OWeakObject * >( this ),
932 Name,
933 -1, // No handle available
934 beans::PropertySetInfoChange::PROPERTY_REMOVED );
935 notifyPropertySetInfoChange( evt );
937 catch ( DAVException const & e )
939 if ( e.getStatus() == SC_FORBIDDEN )
941 // Support for setting arbitrary dead properties is optional!
943 // Try to remove property from local store.
944 ContentImplHelper::removeProperty( Name );
946 else
948 if ( shouldAccessNetworkAfterException( e ) )
952 ResourceType eType = getResourceType( xEnv );
953 switch ( eType )
955 case UNKNOWN:
956 case DAV:
957 throw beans::UnknownPropertyException();
959 case FTP:
960 case NON_DAV:
961 // Try to remove property from local store.
962 ContentImplHelper::removeProperty( Name );
963 break;
965 default:
966 OSL_FAIL( "Content::removeProperty - "
967 "Unsupported resource type!" );
968 break;
971 catch ( uno::Exception const & )
973 OSL_FAIL( "Content::removeProperty - "
974 "Unable to determine resource type!" );
977 else
979 OSL_FAIL( "Content::removeProperty - "
980 "Unable to determine resource type!" );
981 // throw beans::UnknownPropertyException();
987 // virtual
988 void SAL_CALL Content::addProperty( const OUString& Name,
989 sal_Int16 Attributes,
990 const uno::Any& DefaultValue )
991 throw( beans::PropertyExistException,
992 beans::IllegalTypeException,
993 lang::IllegalArgumentException,
994 uno::RuntimeException, std::exception )
996 beans::Property aProperty;
997 aProperty.Name = Name;
998 aProperty.Type = DefaultValue.getValueType();
999 aProperty.Attributes = Attributes;
1000 aProperty.Handle = -1;
1002 addProperty( ucb::PropertyCommandArgument( aProperty, DefaultValue ),
1003 uno::Reference< ucb::XCommandEnvironment >());
1006 // virtual
1007 void SAL_CALL Content::removeProperty( const OUString& Name )
1008 throw( beans::UnknownPropertyException,
1009 beans::NotRemoveableException,
1010 uno::RuntimeException, std::exception )
1012 removeProperty( Name,
1013 uno::Reference< ucb::XCommandEnvironment >() );
1018 // XContentCreator methods.
1022 // virtual
1023 uno::Sequence< ucb::ContentInfo > SAL_CALL
1024 Content::queryCreatableContentsInfo()
1025 throw( uno::RuntimeException, std::exception )
1027 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1029 uno::Sequence< ucb::ContentInfo > aSeq( 2 );
1031 // document.
1032 aSeq.getArray()[ 0 ].Type = WEBDAV_CONTENT_TYPE;
1033 aSeq.getArray()[ 0 ].Attributes
1034 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
1035 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
1037 beans::Property aProp;
1038 m_pProvider->getProperty(
1039 OUString( "Title" ), aProp );
1041 uno::Sequence< beans::Property > aDocProps( 1 );
1042 aDocProps.getArray()[ 0 ] = aProp;
1043 aSeq.getArray()[ 0 ].Properties = aDocProps;
1045 // folder.
1046 aSeq.getArray()[ 1 ].Type = WEBDAV_COLLECTION_TYPE;
1047 aSeq.getArray()[ 1 ].Attributes
1048 = ucb::ContentInfoAttribute::KIND_FOLDER;
1050 uno::Sequence< beans::Property > aFolderProps( 1 );
1051 aFolderProps.getArray()[ 0 ] = aProp;
1052 aSeq.getArray()[ 1 ].Properties = aFolderProps;
1053 return aSeq;
1057 // virtual
1058 uno::Reference< ucb::XContent > SAL_CALL
1059 Content::createNewContent( const ucb::ContentInfo& Info )
1060 throw( uno::RuntimeException, std::exception )
1062 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1064 if ( Info.Type.isEmpty() )
1065 return uno::Reference< ucb::XContent >();
1067 if ( ( Info.Type != WEBDAV_COLLECTION_TYPE ) && ( Info.Type != WEBDAV_CONTENT_TYPE ) )
1068 return uno::Reference< ucb::XContent >();
1070 OUString aURL = m_xIdentifier->getContentIdentifier();
1072 OSL_ENSURE( !aURL.isEmpty(),
1073 "WebdavContent::createNewContent - empty identifier!" );
1075 if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
1076 aURL += "/";
1078 bool isCollection;
1079 if ( Info.Type == WEBDAV_COLLECTION_TYPE )
1081 aURL += "New_Collection";
1082 isCollection = true;
1084 else
1086 aURL += "New_Content";
1087 isCollection = false;
1090 uno::Reference< ucb::XContentIdentifier > xId(
1091 new ::ucbhelper::ContentIdentifier( aURL ) );
1093 // create the local content
1096 return new ::webdav_ucp::Content( m_xContext,
1097 m_pProvider,
1098 xId,
1099 m_xResAccess->getSessionFactory(),
1100 isCollection );
1102 catch ( ucb::ContentCreationException & )
1104 return uno::Reference< ucb::XContent >();
1109 // virtual
1110 OUString Content::getParentURL()
1112 // <scheme>:// -> ""
1113 // <scheme>://foo -> ""
1114 // <scheme>://foo/ -> ""
1115 // <scheme>://foo/bar -> <scheme>://foo/
1116 // <scheme>://foo/bar/ -> <scheme>://foo/
1117 // <scheme>://foo/bar/abc -> <scheme>://foo/bar/
1119 OUString aURL = m_xIdentifier->getContentIdentifier();
1121 sal_Int32 nPos = aURL.lastIndexOf( '/' );
1122 if ( nPos == ( aURL.getLength() - 1 ) )
1124 // Trailing slash found. Skip.
1125 nPos = aURL.lastIndexOf( '/', nPos );
1128 sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos );
1129 if ( nPos1 != -1 )
1130 nPos1 = aURL.lastIndexOf( '/', nPos1 );
1132 if ( nPos1 == -1 )
1133 return OUString();
1135 return OUString( aURL.copy( 0, nPos + 1 ) );
1140 // Non-interface methods.
1144 // static
1145 uno::Reference< sdbc::XRow > Content::getPropertyValues(
1146 const uno::Reference< uno::XComponentContext >& rxContext,
1147 const uno::Sequence< beans::Property >& rProperties,
1148 const ContentProperties& rData,
1149 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
1150 const OUString& rContentId )
1152 // Note: Empty sequence means "get values of all supported properties".
1154 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
1155 = new ::ucbhelper::PropertyValueSet( rxContext );
1157 sal_Int32 nCount = rProperties.getLength();
1158 if ( nCount )
1160 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
1161 bool bTriedToGetAdditionalPropSet = false;
1163 const beans::Property* pProps = rProperties.getConstArray();
1164 for ( sal_Int32 n = 0; n < nCount; ++n )
1166 const beans::Property& rProp = pProps[ n ];
1168 // Process standard UCB, DAV and HTTP properties.
1169 const uno::Any & rValue = rData.getValue( rProp.Name );
1170 if ( rValue.hasValue() )
1172 xRow->appendObject( rProp, rValue );
1174 else
1176 // Process local Additional Properties.
1177 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1179 xAdditionalPropSet
1180 = uno::Reference< beans::XPropertySet >(
1181 rProvider->getAdditionalPropertySet( rContentId,
1182 false ),
1183 uno::UNO_QUERY );
1184 bTriedToGetAdditionalPropSet = true;
1187 if ( !xAdditionalPropSet.is() ||
1188 !xRow->appendPropertySetValue(
1189 xAdditionalPropSet, rProp ) )
1191 // Append empty entry.
1192 xRow->appendVoid( rProp );
1197 else
1199 // Append all standard UCB, DAV and HTTP properties.
1200 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1201 const std::auto_ptr< PropertyValueMap > & xProps = rData.getProperties();
1202 SAL_WNODEPRECATED_DECLARATIONS_POP
1204 PropertyValueMap::const_iterator it = xProps->begin();
1205 PropertyValueMap::const_iterator end = xProps->end();
1207 ContentProvider * pProvider
1208 = static_cast< ContentProvider * >( rProvider.get() );
1209 beans::Property aProp;
1211 while ( it != end )
1213 if ( pProvider->getProperty( (*it).first, aProp ) )
1214 xRow->appendObject( aProp, (*it).second.value() );
1216 ++it;
1219 // Append all local Additional Properties.
1220 uno::Reference< beans::XPropertySet > xSet(
1221 rProvider->getAdditionalPropertySet( rContentId, false ),
1222 uno::UNO_QUERY );
1223 xRow->appendPropertySet( xSet );
1226 return uno::Reference< sdbc::XRow >( xRow.get() );
1230 uno::Reference< sdbc::XRow > Content::getPropertyValues(
1231 const uno::Sequence< beans::Property >& rProperties,
1232 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1233 throw ( uno::Exception, std::exception )
1235 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1236 std::auto_ptr< ContentProperties > xProps;
1237 std::auto_ptr< ContentProperties > xCachedProps;
1238 std::auto_ptr< DAVResourceAccess > xResAccess;
1239 SAL_WNODEPRECATED_DECLARATIONS_POP
1240 OUString aUnescapedTitle;
1241 bool bHasAll = false;
1242 uno::Reference< ucb::XContentIdentifier > xIdentifier;
1243 rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
1246 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1248 aUnescapedTitle = NeonUri::unescape( m_aEscapedTitle );
1249 xIdentifier.set( m_xIdentifier );
1250 xProvider.set( m_xProvider.get() );
1251 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1253 // First, ask cache...
1254 if ( m_xCachedProps.get() )
1256 xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
1258 std::vector< OUString > aMissingProps;
1259 if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) )
1261 // All properties are already in cache! No server access needed.
1262 bHasAll = true;
1265 // use the cached ContentProperties instance
1266 xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1270 if ( !m_bTransient && !bHasAll )
1273 // Obtain values from server...
1276 // First, identify whether resource is DAV or not
1277 bool bNetworkAccessAllowed = true;
1278 ResourceType eType = getResourceType(
1279 xEnv, xResAccess, &bNetworkAccessAllowed );
1281 if ( eType == DAV )
1283 // cache lookup... getResourceType may fill the props cache via
1284 // PROPFIND!
1285 if ( m_xCachedProps.get() )
1287 xCachedProps.reset(
1288 new ContentProperties( *m_xCachedProps.get() ) );
1290 std::vector< OUString > aMissingProps;
1291 if ( xCachedProps->containsAllNames(
1292 rProperties, aMissingProps ) )
1294 // All properties are already in cache! No server access
1295 // needed.
1296 bHasAll = true;
1299 // use the cached ContentProperties instance
1300 xProps.reset( new ContentProperties( *xCachedProps.get() ) );
1303 if ( !bHasAll )
1305 // Only DAV resources support PROPFIND
1306 std::vector< OUString > aPropNames;
1308 uno::Sequence< beans::Property > aProperties(
1309 rProperties.getLength() );
1311 if ( !m_aFailedPropNames.empty() )
1313 sal_Int32 nProps = 0;
1314 sal_Int32 nCount = rProperties.getLength();
1315 for ( sal_Int32 n = 0; n < nCount; ++n )
1317 const OUString & rName = rProperties[ n ].Name;
1319 std::vector< OUString >::const_iterator it
1320 = m_aFailedPropNames.begin();
1321 std::vector< OUString >::const_iterator end
1322 = m_aFailedPropNames.end();
1324 while ( it != end )
1326 if ( *it == rName )
1327 break;
1329 ++it;
1332 if ( it == end )
1334 aProperties[ nProps ] = rProperties[ n ];
1335 nProps++;
1339 aProperties.realloc( nProps );
1341 else
1343 aProperties = rProperties;
1346 if ( aProperties.getLength() > 0 )
1347 ContentProperties::UCBNamesToDAVNames(
1348 aProperties, aPropNames );
1350 if ( !aPropNames.empty() )
1352 std::vector< DAVResource > resources;
1355 xResAccess->PROPFIND(
1356 DAVZERO, aPropNames, resources, xEnv );
1358 if ( 1 == resources.size() )
1360 if ( xProps.get())
1361 xProps->addProperties(
1362 aPropNames,
1363 ContentProperties( resources[ 0 ] ));
1364 else
1365 xProps.reset(
1366 new ContentProperties( resources[ 0 ] ) );
1369 catch ( DAVException const & e )
1371 bNetworkAccessAllowed = bNetworkAccessAllowed
1372 && shouldAccessNetworkAfterException( e );
1374 if ( !bNetworkAccessAllowed )
1376 cancelCommandExecution( e, xEnv );
1377 // unreachable
1384 if ( bNetworkAccessAllowed )
1386 // All properties obtained already?
1387 std::vector< OUString > aMissingProps;
1388 if ( !( xProps.get()
1389 && xProps->containsAllNames(
1390 rProperties, aMissingProps ) )
1391 && !m_bDidGetOrHead )
1393 // Possibly the missing props can be obtained using a HEAD
1394 // request.
1396 std::vector< OUString > aHeaderNames;
1397 ContentProperties::UCBNamesToHTTPNames(
1398 rProperties,
1399 aHeaderNames,
1400 true /* bIncludeUnmatched */ );
1402 if ( !aHeaderNames.empty() )
1406 DAVResource resource;
1407 xResAccess->HEAD( aHeaderNames, resource, xEnv );
1408 m_bDidGetOrHead = true;
1410 if ( xProps.get() )
1411 xProps->addProperties(
1412 aMissingProps,
1413 ContentProperties( resource ) );
1414 else
1415 xProps.reset ( new ContentProperties( resource ) );
1417 if ( m_eResourceType == NON_DAV )
1418 xProps->addProperties( aMissingProps,
1419 ContentProperties(
1420 aUnescapedTitle,
1421 false ) );
1423 catch ( DAVException const & e )
1425 bNetworkAccessAllowed
1426 = shouldAccessNetworkAfterException( e );
1428 if ( !bNetworkAccessAllowed )
1430 cancelCommandExecution( e, xEnv );
1431 // unreachable
1438 // might trigger HTTP redirect.
1439 // Therefore, title must be updated here.
1440 NeonUri aUri( xResAccess->getURL() );
1441 aUnescapedTitle = aUri.GetPathBaseNameUnescaped();
1443 if ( eType == UNKNOWN )
1445 xProps.reset( new ContentProperties( aUnescapedTitle ) );
1448 // For DAV resources we only know the Title, for non-DAV
1449 // resources we additionally know that it is a document.
1451 if ( eType == DAV )
1453 //xProps.reset(
1454 // new ContentProperties( aUnescapedTitle ) );
1455 xProps->addProperty(
1456 OUString( "Title" ),
1457 uno::makeAny( aUnescapedTitle ),
1458 true );
1460 else
1462 if ( !xProps.get() )
1463 xProps.reset( new ContentProperties( aUnescapedTitle, false ) );
1464 else
1465 xProps->addProperty(
1466 OUString( "Title" ),
1467 uno::makeAny( aUnescapedTitle ),
1468 true );
1470 xProps->addProperty(
1471 OUString( "IsFolder" ),
1472 uno::makeAny( false ),
1473 true );
1474 xProps->addProperty(
1475 OUString( "IsDocument" ),
1476 uno::makeAny( true ),
1477 true );
1480 else
1482 // No server access for just created (not yet committed) objects.
1483 // Only a minimal set of properties supported at this stage.
1484 if (m_bTransient)
1485 xProps.reset( new ContentProperties( aUnescapedTitle,
1486 m_bCollection ) );
1489 sal_Int32 nCount = rProperties.getLength();
1490 for ( sal_Int32 n = 0; n < nCount; ++n )
1492 const OUString rName = rProperties[ n ].Name;
1493 if ( rName == "BaseURI" )
1495 // Add BaseURI property, if requested.
1496 xProps->addProperty(
1497 OUString( "BaseURI" ),
1498 uno::makeAny( getBaseURI( xResAccess ) ),
1499 true );
1501 else if ( rName == "CreatableContentsInfo" )
1503 // Add CreatableContentsInfo property, if requested.
1504 bool bFolder = false;
1505 xProps->getValue(
1506 OUString( "IsFolder" ) )
1507 >>= bFolder;
1508 xProps->addProperty(
1509 OUString( "CreatableContentsInfo" ),
1510 uno::makeAny( bFolder
1511 ? queryCreatableContentsInfo()
1512 : uno::Sequence< ucb::ContentInfo >() ),
1513 true );
1517 uno::Reference< sdbc::XRow > xResultRow
1518 = getPropertyValues( m_xContext,
1519 rProperties,
1520 *xProps,
1521 xProvider,
1522 xIdentifier->getContentIdentifier() );
1525 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1527 if ( !m_xCachedProps.get() )
1528 m_xCachedProps.reset( new CachableContentProperties( *xProps.get() ) );
1529 else
1530 m_xCachedProps->addProperties( *xProps.get() );
1532 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1533 m_aEscapedTitle = NeonUri::escapeSegment( aUnescapedTitle );
1536 return xResultRow;
1540 uno::Sequence< uno::Any > Content::setPropertyValues(
1541 const uno::Sequence< beans::PropertyValue >& rValues,
1542 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1543 throw ( uno::Exception, std::exception )
1545 uno::Reference< ucb::XContentIdentifier > xIdentifier;
1546 rtl::Reference< ContentProvider > xProvider;
1547 bool bTransient;
1548 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1549 std::auto_ptr< DAVResourceAccess > xResAccess;
1550 SAL_WNODEPRECATED_DECLARATIONS_POP
1553 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1555 xProvider.set( m_pProvider );
1556 xIdentifier.set( m_xIdentifier );
1557 bTransient = m_bTransient;
1558 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
1561 uno::Sequence< uno::Any > aRet( rValues.getLength() );
1562 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1563 sal_Int32 nChanged = 0;
1565 beans::PropertyChangeEvent aEvent;
1566 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1567 aEvent.Further = sal_False;
1568 // aEvent.PropertyName =
1569 aEvent.PropertyHandle = -1;
1570 // aEvent.OldValue =
1571 // aEvent.NewValue =
1573 std::vector< ProppatchValue > aProppatchValues;
1574 std::vector< sal_Int32 > aProppatchPropsPositions;
1576 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1577 bool bTriedToGetAdditionalPropSet = false;
1579 bool bExchange = false;
1580 OUString aNewTitle;
1581 OUString aOldTitle;
1582 sal_Int32 nTitlePos = -1;
1584 uno::Reference< beans::XPropertySetInfo > xInfo;
1586 const beans::PropertyValue* pValues = rValues.getConstArray();
1587 sal_Int32 nCount = rValues.getLength();
1588 for ( sal_Int32 n = 0; n < nCount; ++n )
1590 const beans::PropertyValue& rValue = pValues[ n ];
1591 const OUString & rName = rValue.Name;
1593 beans::Property aTmpProp;
1594 xProvider->getProperty( rName, aTmpProp );
1596 if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY )
1598 // Read-only property!
1599 aRet[ n ] <<= lang::IllegalAccessException(
1600 OUString( "Property is read-only!" ),
1601 static_cast< cppu::OWeakObject * >( this ) );
1602 continue;
1606 // Mandatory props.
1609 if ( rName == "ContentType" )
1611 // Read-only property!
1612 aRet[ n ] <<= lang::IllegalAccessException(
1613 OUString( "Property is read-only!" ),
1614 static_cast< cppu::OWeakObject * >( this ) );
1616 else if ( rName == "IsDocument" )
1618 // Read-only property!
1619 aRet[ n ] <<= lang::IllegalAccessException(
1620 OUString( "Property is read-only!" ),
1621 static_cast< cppu::OWeakObject * >( this ) );
1623 else if ( rName == "IsFolder" )
1625 // Read-only property!
1626 aRet[ n ] <<= lang::IllegalAccessException(
1627 OUString( "Property is read-only!" ),
1628 static_cast< cppu::OWeakObject * >( this ) );
1630 else if ( rName == "Title" )
1632 OUString aNewValue;
1633 if ( rValue.Value >>= aNewValue )
1635 // No empty titles!
1636 if ( !aNewValue.isEmpty() )
1640 NeonUri aURI( xIdentifier->getContentIdentifier() );
1641 aOldTitle = aURI.GetPathBaseNameUnescaped();
1643 if ( aNewValue != aOldTitle )
1645 // modified title -> modified URL -> exchange !
1646 if ( !bTransient )
1647 bExchange = true;
1649 // new value will be set later...
1650 aNewTitle = aNewValue;
1652 // remember position within sequence of values (for
1653 // error handling).
1654 nTitlePos = n;
1657 catch ( DAVException const & )
1659 aRet[ n ] <<= lang::IllegalArgumentException(
1660 OUString( "Invalid content identifier!" ),
1661 static_cast< cppu::OWeakObject * >( this ),
1662 -1 );
1665 else
1667 aRet[ n ] <<= lang::IllegalArgumentException(
1668 OUString( "Empty title not allowed!" ),
1669 static_cast< cppu::OWeakObject * >( this ),
1670 -1 );
1673 else
1675 aRet[ n ] <<= beans::IllegalTypeException(
1676 OUString( "Property value has wrong type!" ),
1677 static_cast< cppu::OWeakObject * >( this ) );
1680 else
1683 // Optional props.
1686 OUString aSpecialName;
1687 bool bIsSpecial = DAVProperties::isUCBSpecialProperty(
1688 rName, aSpecialName );
1690 if ( !xInfo.is() )
1691 xInfo = getPropertySetInfo( xEnv,
1692 false /* don't cache data */ );
1694 if ( !xInfo->hasPropertyByName(
1695 bIsSpecial ? aSpecialName : rName ) )
1697 // Check, whether property exists. Skip otherwise.
1698 // PROPPATCH::set would add the property automatically, which
1699 // is not allowed for "setPropertyValues" command!
1700 aRet[ n ] <<= beans::UnknownPropertyException(
1701 OUString( "Property is unknown!" ),
1702 static_cast< cppu::OWeakObject * >( this ) );
1703 continue;
1706 if ( rName == "Size" )
1708 // Read-only property!
1709 aRet[ n ] <<= lang::IllegalAccessException(
1710 OUString( "Property is read-only!" ),
1711 static_cast< cppu::OWeakObject * >( this ) );
1713 else if ( rName == "DateCreated" )
1715 // Read-only property!
1716 aRet[ n ] <<= lang::IllegalAccessException(
1717 OUString( "Property is read-only!" ),
1718 static_cast< cppu::OWeakObject * >( this ) );
1720 else if ( rName == "DateModified" )
1722 // Read-only property!
1723 aRet[ n ] <<= lang::IllegalAccessException(
1724 OUString( "Property is read-only!" ),
1725 static_cast< cppu::OWeakObject * >( this ) );
1727 else if ( rName == "MediaType" )
1729 // Read-only property!
1730 // (but could be writable, if 'getcontenttype' would be)
1731 aRet[ n ] <<= lang::IllegalAccessException(
1732 OUString( "Property is read-only!" ),
1733 static_cast< cppu::OWeakObject * >( this ) );
1735 if ( rName == "CreatableContentsInfo" )
1737 // Read-only property!
1738 aRet[ n ] <<= lang::IllegalAccessException(
1739 OUString( "Property is read-only!" ),
1740 static_cast< cppu::OWeakObject * >( this ) );
1742 else
1744 if ( getResourceType( xEnv, xResAccess ) == DAV )
1746 // Property value will be set on server.
1747 ProppatchValue aValue( PROPSET, rName, rValue.Value );
1748 aProppatchValues.push_back( aValue );
1750 // remember position within sequence of values (for
1751 // error handling).
1752 aProppatchPropsPositions.push_back( n );
1754 else
1756 // Property value will be stored in local property store.
1757 if ( !bTriedToGetAdditionalPropSet &&
1758 !xAdditionalPropSet.is() )
1760 xAdditionalPropSet
1761 = getAdditionalPropertySet( false );
1762 bTriedToGetAdditionalPropSet = true;
1765 if ( xAdditionalPropSet.is() )
1769 uno::Any aOldValue
1770 = xAdditionalPropSet->getPropertyValue( rName );
1771 if ( aOldValue != rValue.Value )
1773 xAdditionalPropSet->setPropertyValue(
1774 rName, rValue.Value );
1776 aEvent.PropertyName = rName;
1777 aEvent.OldValue = aOldValue;
1778 aEvent.NewValue = rValue.Value;
1780 aChanges.getArray()[ nChanged ] = aEvent;
1781 nChanged++;
1784 catch ( beans::UnknownPropertyException const & e )
1786 aRet[ n ] <<= e;
1788 catch ( lang::WrappedTargetException const & e )
1790 aRet[ n ] <<= e;
1792 catch ( beans::PropertyVetoException const & e )
1794 aRet[ n ] <<= e;
1796 catch ( lang::IllegalArgumentException const & e )
1798 aRet[ n ] <<= e;
1801 else
1803 aRet[ n ] <<= uno::Exception(
1804 OUString( "No property set for storing the value!" ),
1805 static_cast< cppu::OWeakObject * >( this ) );
1810 } // for
1812 if ( !bTransient && !aProppatchValues.empty() )
1816 // Set property values at server.
1817 xResAccess->PROPPATCH( aProppatchValues, xEnv );
1819 std::vector< ProppatchValue >::const_iterator it
1820 = aProppatchValues.begin();
1821 std::vector< ProppatchValue >::const_iterator end
1822 = aProppatchValues.end();
1824 while ( it != end )
1826 aEvent.PropertyName = (*it).name;
1827 aEvent.OldValue = uno::Any(); // @@@ to expensive to obtain!
1828 aEvent.NewValue = (*it).value;
1830 aChanges.getArray()[ nChanged ] = aEvent;
1831 nChanged++;
1833 ++it;
1836 catch ( DAVException const & e )
1838 // OSL_FAIL( // "Content::setPropertyValues - PROPPATCH failed!" );
1840 cancelCommandExecution( e, xEnv );
1841 // unreachable
1845 if ( bExchange )
1847 // Assemble new content identifier...
1849 OUString aNewURL = getParentURL();
1850 if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) )
1851 aNewURL += "/";
1853 aNewURL += NeonUri::escapeSegment( aNewTitle );
1855 uno::Reference< ucb::XContentIdentifier > xNewId
1856 = new ::ucbhelper::ContentIdentifier( aNewURL );
1857 uno::Reference< ucb::XContentIdentifier > xOldId = xIdentifier;
1861 NeonUri sourceURI( xOldId->getContentIdentifier() );
1862 NeonUri targetURI( xNewId->getContentIdentifier() );
1863 targetURI.SetScheme( sourceURI.GetScheme() );
1865 xResAccess->MOVE(
1866 sourceURI.GetPath(), targetURI.GetURI(), false, xEnv );
1867 // @@@ Should check for resources that could not be moved
1868 // (due to source access or target overwrite) and send
1869 // this information through the interaction handler.
1871 // @@@ Existing content should be checked to see if it needs
1872 // to be deleted at the source
1874 // @@@ Existing content should be checked to see if it has
1875 // been overwritten at the target
1877 if ( exchangeIdentity( xNewId ) )
1879 xResAccess->setURL( aNewURL );
1881 // DAV resources store all additional props on server!
1882 // // Adapt Additional Core Properties.
1883 // renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1884 // xNewId->getContentIdentifier(),
1885 // sal_True );
1887 else
1889 // Do not set new title!
1890 aNewTitle = "";
1892 // Set error .
1893 aRet[ nTitlePos ] <<= uno::Exception(
1894 OUString("Exchange failed!"),
1895 static_cast< cppu::OWeakObject * >( this ) );
1898 catch ( DAVException const & e )
1900 // Do not set new title!
1901 aNewTitle = "";
1903 // Set error .
1904 aRet[ nTitlePos ] <<= MapDAVException( e, true );
1908 if ( !aNewTitle.isEmpty() )
1910 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1912 aEvent.PropertyName = "Title";
1913 aEvent.OldValue = uno::makeAny( aOldTitle );
1914 aEvent.NewValue = uno::makeAny( aNewTitle );
1916 m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle );
1918 aChanges.getArray()[ nChanged ] = aEvent;
1919 nChanged++;
1922 if ( nChanged > 0 )
1924 aChanges.realloc( nChanged );
1925 notifyPropertiesChange( aChanges );
1929 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1930 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
1933 return aRet;
1937 uno::Any Content::open(
1938 const ucb::OpenCommandArgument3 & rArg,
1939 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1940 throw( uno::Exception )
1942 uno::Any aRet;
1944 bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) ||
1945 ( rArg.Mode == ucb::OpenMode::FOLDERS ) ||
1946 ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) );
1947 if ( bOpenFolder )
1949 if ( isFolder( xEnv ) )
1951 // Open collection.
1953 uno::Reference< ucb::XDynamicResultSet > xSet
1954 = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1955 aRet <<= xSet;
1957 else
1959 // Error: Not a folder!
1961 OUStringBuffer aMsg;
1962 if ( getResourceType( xEnv ) == FTP )
1964 // #114653#
1965 aMsg.appendAscii( "FTP over HTTP proxy: resource cannot "
1966 "be opened as folder! Wrong Open Mode!" );
1968 else
1970 aMsg.appendAscii( "Non-folder resource cannot be "
1971 "opened as folder! Wrong Open Mode!" );
1974 ucbhelper::cancelCommandExecution(
1975 uno::makeAny(
1976 lang::IllegalArgumentException(
1977 aMsg.makeStringAndClear(),
1978 static_cast< cppu::OWeakObject * >( this ),
1979 -1 ) ),
1980 xEnv );
1981 // Unreachable
1985 if ( rArg.Sink.is() )
1987 // Open document.
1989 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1990 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1992 // Currently(?) unsupported.
1993 ucbhelper::cancelCommandExecution(
1994 uno::makeAny(
1995 ucb::UnsupportedOpenModeException(
1996 OUString(),
1997 static_cast< cppu::OWeakObject * >( this ),
1998 sal_Int16( rArg.Mode ) ) ),
1999 xEnv );
2000 // Unreachable
2003 uno::Reference< io::XOutputStream > xOut
2004 = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
2005 if ( xOut.is() )
2007 // PUSH: write data
2010 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2011 std::auto_ptr< DAVResourceAccess > xResAccess;
2012 SAL_WNODEPRECATED_DECLARATIONS_POP
2015 osl::MutexGuard aGuard( m_aMutex );
2017 xResAccess.reset(
2018 new DAVResourceAccess( *m_xResAccess.get() ) );
2021 xResAccess->setFlags( rArg.OpeningFlags );
2022 DAVResource aResource;
2023 std::vector< OUString > aHeaders;
2025 xResAccess->GET( xOut, aHeaders, aResource, xEnv );
2026 m_bDidGetOrHead = true;
2029 osl::MutexGuard aGuard( m_aMutex );
2031 // cache headers.
2032 if ( !m_xCachedProps.get())
2033 m_xCachedProps.reset(
2034 new CachableContentProperties( aResource ) );
2035 else
2036 m_xCachedProps->addProperties( aResource );
2038 m_xResAccess.reset(
2039 new DAVResourceAccess( *xResAccess.get() ) );
2042 catch ( DAVException const & e )
2044 cancelCommandExecution( e, xEnv );
2045 // Unreachable
2048 else
2050 uno::Reference< io::XActiveDataSink > xDataSink
2051 = uno::Reference< io::XActiveDataSink >( rArg.Sink,
2052 uno::UNO_QUERY );
2053 if ( xDataSink.is() )
2055 // PULL: wait for client read
2058 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2059 std::auto_ptr< DAVResourceAccess > xResAccess;
2060 SAL_WNODEPRECATED_DECLARATIONS_POP
2062 osl::MutexGuard aGuard( m_aMutex );
2064 xResAccess.reset(
2065 new DAVResourceAccess( *m_xResAccess.get() ) );
2068 xResAccess->setFlags( rArg.OpeningFlags );
2070 // fill inputsream sync; return if all data present
2071 DAVResource aResource;
2072 std::vector< OUString > aHeaders;
2074 uno::Reference< io::XInputStream > xIn
2075 = xResAccess->GET( aHeaders, aResource, xEnv );
2076 m_bDidGetOrHead = true;
2079 osl::MutexGuard aGuard( m_aMutex );
2081 // cache headers.
2082 if ( !m_xCachedProps.get())
2083 m_xCachedProps.reset(
2084 new CachableContentProperties( aResource ) );
2085 else
2086 m_xCachedProps->addProperties(
2087 aResource.properties );
2089 m_xResAccess.reset(
2090 new DAVResourceAccess( *xResAccess.get() ) );
2093 xDataSink->setInputStream( xIn );
2095 catch ( DAVException const & e )
2097 cancelCommandExecution( e, xEnv );
2098 // Unreachable
2101 else
2103 // Note: aOpenCommand.Sink may contain an XStream
2104 // implementation. Support for this type of
2105 // sink is optional...
2106 ucbhelper::cancelCommandExecution(
2107 uno::makeAny(
2108 ucb::UnsupportedDataSinkException(
2109 OUString(),
2110 static_cast< cppu::OWeakObject * >( this ),
2111 rArg.Sink ) ),
2112 xEnv );
2113 // Unreachable
2118 return aRet;
2122 void Content::post(
2123 const ucb::PostCommandArgument2 & rArg,
2124 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
2125 throw( uno::Exception )
2127 uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
2128 if ( xSink.is() )
2132 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2133 std::auto_ptr< DAVResourceAccess > xResAccess;
2134 SAL_WNODEPRECATED_DECLARATIONS_POP
2136 osl::MutexGuard aGuard( m_aMutex );
2137 xResAccess.reset(
2138 new DAVResourceAccess( *m_xResAccess.get() ) );
2141 uno::Reference< io::XInputStream > xResult
2142 = xResAccess->POST( rArg.MediaType,
2143 rArg.Referer,
2144 rArg.Source,
2145 xEnv );
2148 osl::MutexGuard aGuard( m_aMutex );
2149 m_xResAccess.reset(
2150 new DAVResourceAccess( *xResAccess.get() ) );
2153 xSink->setInputStream( xResult );
2155 catch ( DAVException const & e )
2157 cancelCommandExecution( e, xEnv, true );
2158 // Unreachable
2161 else
2163 uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
2164 if ( xResult.is() )
2168 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2169 std::auto_ptr< DAVResourceAccess > xResAccess;
2170 SAL_WNODEPRECATED_DECLARATIONS_POP
2172 osl::MutexGuard aGuard( m_aMutex );
2173 xResAccess.reset(
2174 new DAVResourceAccess( *m_xResAccess.get() ) );
2177 xResAccess->POST( rArg.MediaType,
2178 rArg.Referer,
2179 rArg.Source,
2180 xResult,
2181 xEnv );
2184 osl::MutexGuard aGuard( m_aMutex );
2185 m_xResAccess.reset(
2186 new DAVResourceAccess( *xResAccess.get() ) );
2189 catch ( DAVException const & e )
2191 cancelCommandExecution( e, xEnv, true );
2192 // Unreachable
2195 else
2197 ucbhelper::cancelCommandExecution(
2198 uno::makeAny(
2199 ucb::UnsupportedDataSinkException(
2200 OUString(),
2201 static_cast< cppu::OWeakObject * >( this ),
2202 rArg.Sink ) ),
2203 xEnv );
2204 // Unreachable
2210 void Content::queryChildren( ContentRefList& rChildren )
2212 // Obtain a list with a snapshot of all currently instanciated contents
2213 // from provider and extract the contents which are direct children
2214 // of this content.
2216 ::ucbhelper::ContentRefList aAllContents;
2217 m_xProvider->queryExistingContents( aAllContents );
2219 OUString aURL = m_xIdentifier->getContentIdentifier();
2220 sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
2222 if ( nURLPos != ( aURL.getLength() - 1 ) )
2224 // No trailing slash found. Append.
2225 aURL += "/";
2228 sal_Int32 nLen = aURL.getLength();
2230 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2231 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2233 while ( it != end )
2235 ::ucbhelper::ContentImplHelperRef xChild = (*it);
2236 OUString aChildURL
2237 = xChild->getIdentifier()->getContentIdentifier();
2239 // Is aURL a prefix of aChildURL?
2240 if ( ( aChildURL.getLength() > nLen ) &&
2241 ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
2243 sal_Int32 nPos = nLen;
2244 nPos = aChildURL.indexOf( '/', nPos );
2246 if ( ( nPos == -1 ) ||
2247 ( nPos == ( aChildURL.getLength() - 1 ) ) )
2249 // No further slashes / only a final slash. It's a child!
2250 rChildren.push_back(
2251 ::webdav_ucp::Content::ContentRef(
2252 static_cast< ::webdav_ucp::Content * >(
2253 xChild.get() ) ) );
2256 ++it;
2261 void Content::insert(
2262 const uno::Reference< io::XInputStream > & xInputStream,
2263 bool bReplaceExisting,
2264 const uno::Reference< ucb::XCommandEnvironment >& Environment )
2265 throw( uno::Exception )
2267 bool bTransient, bCollection;
2268 OUString aEscapedTitle;
2269 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2270 std::auto_ptr< DAVResourceAccess > xResAccess;
2271 SAL_WNODEPRECATED_DECLARATIONS_POP
2274 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2276 bTransient = m_bTransient;
2277 bCollection = m_bCollection;
2278 aEscapedTitle = m_aEscapedTitle;
2279 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2282 // Check, if all required properties are present.
2284 if ( aEscapedTitle.isEmpty() )
2286 OSL_FAIL( "Content::insert - Title missing!" );
2288 uno::Sequence< OUString > aProps( 1 );
2289 aProps[ 0 ] = "Title";
2290 ucbhelper::cancelCommandExecution(
2291 uno::makeAny( ucb::MissingPropertiesException(
2292 OUString(),
2293 static_cast< cppu::OWeakObject * >( this ),
2294 aProps ) ),
2295 Environment );
2296 // Unreachable
2299 if ( !bReplaceExisting )
2301 /* [RFC 2616] - HTTP
2303 The PUT method requests that the enclosed entity be stored under the
2304 supplied Request-URI. If the Request-URI refers to an already
2305 existing resource, the enclosed entity SHOULD be considered as a
2306 modified version of the one residing on the origin server.
2309 /* [RFC 2518] - WebDAV
2311 MKCOL creates a new collection resource at the location specified by
2312 the Request-URI. If the resource identified by the Request-URI is
2313 non-null then the MKCOL MUST fail.
2316 // ==> Complain on PUT, continue on MKCOL.
2317 if ( !bTransient || ( bTransient && !bCollection ) )
2319 ucb::UnsupportedNameClashException aEx(
2320 OUString( "Unable to write without overwrite!" ),
2321 static_cast< cppu::OWeakObject * >( this ),
2322 ucb::NameClash::ERROR );
2324 uno::Reference< task::XInteractionHandler > xIH;
2326 if ( Environment.is() )
2327 xIH = Environment->getInteractionHandler();
2329 if ( xIH.is() )
2331 uno::Any aExAsAny( uno::makeAny( aEx ) );
2333 rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest
2334 = new ucbhelper::SimpleInteractionRequest(
2335 aExAsAny,
2336 ucbhelper::CONTINUATION_APPROVE
2337 | ucbhelper::CONTINUATION_DISAPPROVE );
2338 xIH->handle( xRequest.get() );
2340 const sal_Int32 nResp = xRequest->getResponse();
2342 switch ( nResp )
2344 case ucbhelper::CONTINUATION_UNKNOWN:
2345 // Not handled; throw.
2346 throw aEx;
2347 // break;
2349 case ucbhelper::CONTINUATION_APPROVE:
2350 // Continue -> Overwrite.
2351 bReplaceExisting = true;
2352 break;
2354 case ucbhelper::CONTINUATION_DISAPPROVE:
2355 // Abort.
2356 throw ucb::CommandFailedException(
2357 OUString(),
2358 uno::Reference< uno::XInterface >(),
2359 aExAsAny );
2360 // break;
2362 default:
2363 OSL_FAIL( "Content::insert - "
2364 "Unknown interaction selection!" );
2365 throw ucb::CommandFailedException(
2366 OUString( "Unknown interaction selection!" ),
2367 uno::Reference< uno::XInterface >(),
2368 aExAsAny );
2369 // break;
2372 else
2374 // No IH; throw.
2375 throw aEx;
2380 if ( bTransient )
2382 // Assemble new content identifier...
2383 OUString aURL = getParentURL();
2384 if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) )
2385 aURL += "/";
2387 aURL += aEscapedTitle;
2391 xResAccess->setURL( aURL );
2393 if ( bCollection )
2394 xResAccess->MKCOL( Environment );
2395 else
2396 xResAccess->PUT( xInputStream, Environment );
2398 catch ( DAVException const & except )
2400 if ( bCollection )
2402 if ( except.getStatus() == SC_METHOD_NOT_ALLOWED )
2404 // [RFC 2518] - WebDAV
2405 // 405 (Method Not Allowed) - MKCOL can only be
2406 // executed on a deleted/non-existent resource.
2408 if ( bReplaceExisting )
2410 // Destroy old resource.
2413 xResAccess->DESTROY( Environment );
2415 catch ( DAVException const & e )
2417 cancelCommandExecution( e, Environment, true );
2418 // Unreachable
2421 // Insert (recursion!).
2422 insert( xInputStream, bReplaceExisting, Environment );
2425 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2426 m_xResAccess.reset(
2427 new DAVResourceAccess( *xResAccess.get() ) );
2430 // Success!
2431 return;
2433 else
2435 OUString aTitle;
2438 NeonUri aURI( aURL );
2439 aTitle = aURI.GetPathBaseNameUnescaped();
2441 catch ( DAVException const & )
2445 ucbhelper::cancelCommandExecution(
2446 uno::makeAny(
2447 ucb::NameClashException(
2448 OUString(),
2449 static_cast< cppu::OWeakObject * >( this ),
2450 task::InteractionClassification_ERROR,
2451 aTitle ) ),
2452 Environment );
2453 // Unreachable
2458 cancelCommandExecution( except, Environment, true );
2459 // Unreachable
2463 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2464 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aURL );
2467 inserted();
2470 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2471 m_bTransient = false;
2474 else
2476 if ( !xInputStream.is() )
2478 ucbhelper::cancelCommandExecution(
2479 uno::makeAny(
2480 ucb::MissingInputStreamException(
2481 OUString(),
2482 static_cast< cppu::OWeakObject * >( this ) ) ),
2483 Environment );
2484 // Unreachable
2489 xResAccess->PUT( xInputStream, Environment );
2491 catch ( DAVException const & e )
2493 cancelCommandExecution( e, Environment, true );
2494 // Unreachable
2499 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2500 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2505 void Content::transfer(
2506 const ucb::TransferInfo & rArgs,
2507 const uno::Reference< ucb::XCommandEnvironment >& Environment )
2508 throw( uno::Exception )
2510 uno::Reference< ucb::XContentIdentifier > xIdentifier;
2511 uno::Reference< ucb::XContentProvider > xProvider;
2512 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2513 std::auto_ptr< DAVResourceAccess > xResAccess;
2514 SAL_WNODEPRECATED_DECLARATIONS_POP
2517 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2519 xIdentifier.set( m_xIdentifier );
2520 xProvider.set( m_xProvider.get() );
2521 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2524 OUString aTargetURI;
2527 NeonUri sourceURI( rArgs.SourceURL );
2528 NeonUri targetURI( xIdentifier->getContentIdentifier() );
2529 aTargetURI = targetURI.GetPathBaseNameUnescaped();
2531 // Check source's and target's URL scheme
2533 const OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase();
2534 if ( aScheme == WEBDAV_URL_SCHEME )
2536 sourceURI.SetScheme(
2537 OUString( HTTP_URL_SCHEME ) );
2539 else if ( aScheme == DAV_URL_SCHEME )
2541 sourceURI.SetScheme(
2542 OUString( HTTP_URL_SCHEME ) );
2544 else if ( aScheme == DAVS_URL_SCHEME )
2546 sourceURI.SetScheme(
2547 OUString( HTTPS_URL_SCHEME ) );
2549 else
2551 if ( aScheme != HTTP_URL_SCHEME && aScheme != HTTPS_URL_SCHEME )
2553 ucbhelper::cancelCommandExecution(
2554 uno::makeAny(
2555 ucb::InteractiveBadTransferURLException(
2556 OUString( "Unsupported URL scheme!" ),
2557 static_cast< cppu::OWeakObject * >( this ) ) ),
2558 Environment );
2559 // Unreachable
2563 if ( targetURI.GetScheme().toAsciiLowerCase() == WEBDAV_URL_SCHEME )
2564 targetURI.SetScheme(
2565 OUString( HTTP_URL_SCHEME ) );
2566 else if ( targetURI.GetScheme().toAsciiLowerCase() == DAV_URL_SCHEME )
2567 targetURI.SetScheme(
2568 OUString( HTTP_URL_SCHEME ) );
2570 // @@@ This implementation of 'transfer' only works
2571 // if the source and target are located at same host.
2572 // (Neon does not support cross-server copy/move)
2574 // Check for same host
2576 if ( !sourceURI.GetHost().isEmpty() &&
2577 ( sourceURI.GetHost() != targetURI.GetHost() ) )
2579 ucbhelper::cancelCommandExecution(
2580 uno::makeAny( ucb::InteractiveBadTransferURLException(
2581 OUString( "Different hosts!" ),
2582 static_cast< cppu::OWeakObject * >( this ) ) ),
2583 Environment );
2584 // Unreachable
2587 OUString aTitle = rArgs.NewTitle;
2589 if ( aTitle.isEmpty() )
2590 aTitle = sourceURI.GetPathBaseNameUnescaped();
2592 if ( aTitle == "/" )
2594 // kso: ???
2595 aTitle = "";
2598 targetURI.AppendPath( aTitle );
2600 OUString aTargetURL = xIdentifier->getContentIdentifier();
2601 if ( ( aTargetURL.lastIndexOf( '/' ) + 1 )
2602 != aTargetURL.getLength() )
2603 aTargetURL += "/";
2605 aTargetURL += aTitle;
2607 uno::Reference< ucb::XContentIdentifier > xTargetId
2608 = new ::ucbhelper::ContentIdentifier( aTargetURL );
2610 DAVResourceAccess aSourceAccess( m_xContext,
2611 xResAccess->getSessionFactory(),
2612 sourceURI.GetURI() );
2614 if ( rArgs.MoveData == sal_True )
2616 uno::Reference< ucb::XContentIdentifier > xId
2617 = new ::ucbhelper::ContentIdentifier( rArgs.SourceURL );
2619 // Note: The static cast is okay here, because its sure that
2620 // xProvider is always the WebDAVContentProvider.
2621 rtl::Reference< Content > xSource
2622 = static_cast< Content * >(
2623 xProvider->queryContent( xId ).get() );
2625 // [RFC 2518] - WebDAV
2626 // If a resource exists at the destination and the Overwrite
2627 // header is "T" then prior to performing the move the server
2628 // MUST perform a DELETE with "Depth: infinity" on the
2629 // destination resource. If the Overwrite header is set to
2630 // "F" then the operation will fail.
2632 aSourceAccess.MOVE( sourceURI.GetPath(),
2633 targetURI.GetURI(),
2634 rArgs.NameClash
2635 == ucb::NameClash::OVERWRITE,
2636 Environment );
2638 if ( xSource.is() )
2640 // Propagate destruction to listeners.
2641 xSource->destroy( true );
2644 // DAV resources store all additional props on server!
2645 // // Rename own and all children's Additional Core Properties.
2646 // renameAdditionalPropertySet( xId->getContentIdentifier(),
2647 // xTargetId->getContentIdentifier(),
2648 // sal_True );
2650 else
2652 // [RFC 2518] - WebDAV
2653 // If a resource exists at the destination and the Overwrite
2654 // header is "T" then prior to performing the copy the server
2655 // MUST perform a DELETE with "Depth: infinity" on the
2656 // destination resource. If the Overwrite header is set to
2657 // "F" then the operation will fail.
2659 aSourceAccess.COPY( sourceURI.GetPath(),
2660 targetURI.GetURI(),
2661 rArgs.NameClash
2662 == ucb::NameClash::OVERWRITE,
2663 Environment );
2665 // DAV resources store all additional props on server!
2666 // // Copy own and all children's Additional Core Properties.
2667 // copyAdditionalPropertySet( xId->getContentIdentifier(),
2668 // xTargetId->getContentIdentifier(),
2669 // sal_True );
2672 // Note: The static cast is okay here, because its sure that
2673 // xProvider is always the WebDAVContentProvider.
2674 rtl::Reference< Content > xTarget
2675 = static_cast< Content * >(
2676 xProvider->queryContent( xTargetId ).get() );
2678 // Announce transferred content in its new folder.
2679 xTarget->inserted();
2681 catch ( ucb::IllegalIdentifierException const & )
2683 // queryContent
2685 catch ( DAVException const & e )
2687 // [RFC 2518] - WebDAV
2688 // 412 (Precondition Failed) - The server was unable to maintain
2689 // the liveness of the properties listed in the propertybehavior
2690 // XML element or the Overwrite header is "F" and the state of
2691 // the destination resource is non-null.
2693 if ( e.getStatus() == SC_PRECONDITION_FAILED )
2695 switch ( rArgs.NameClash )
2697 case ucb::NameClash::ERROR:
2699 ucbhelper::cancelCommandExecution(
2700 uno::makeAny(
2701 ucb::NameClashException(
2702 OUString(),
2703 static_cast< cppu::OWeakObject * >( this ),
2704 task::InteractionClassification_ERROR,
2705 aTargetURI ) ),
2706 Environment );
2707 // Unreachable
2710 case ucb::NameClash::OVERWRITE:
2711 break;
2713 case ucb::NameClash::KEEP: // deprecated
2714 case ucb::NameClash::RENAME:
2715 case ucb::NameClash::ASK:
2716 default:
2718 ucbhelper::cancelCommandExecution(
2719 uno::makeAny(
2720 ucb::UnsupportedNameClashException(
2721 OUString(),
2722 static_cast< cppu::OWeakObject * >( this ),
2723 rArgs.NameClash ) ),
2724 Environment );
2725 // Unreachable
2730 cancelCommandExecution( e, Environment, true );
2731 // Unreachable
2735 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2736 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2741 void Content::destroy( bool bDeletePhysical )
2742 throw( uno::Exception )
2744 // @@@ take care about bDeletePhysical -> trashcan support
2745 uno::Reference< ucb::XContent > xThis = this;
2747 deleted();
2749 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2751 // Process instanciated children...
2753 ::webdav_ucp::Content::ContentRefList aChildren;
2754 queryChildren( aChildren );
2756 ContentRefList::const_iterator it = aChildren.begin();
2757 ContentRefList::const_iterator end = aChildren.end();
2759 while ( it != end )
2761 (*it)->destroy( bDeletePhysical );
2762 ++it;
2767 bool Content::supportsExclusiveWriteLock(
2768 const uno::Reference< ucb::XCommandEnvironment >& Environment )
2770 if ( getResourceType( Environment ) == DAV )
2772 if ( m_xCachedProps.get() )
2774 uno::Sequence< ucb::LockEntry > aSupportedLocks;
2775 if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK )
2776 >>= aSupportedLocks )
2778 for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
2780 if ( aSupportedLocks[ n ].Scope
2781 == ucb::LockScope_EXCLUSIVE &&
2782 aSupportedLocks[ n ].Type
2783 == ucb::LockType_WRITE )
2784 return true;
2789 return false;
2793 void Content::lock(
2794 const uno::Reference< ucb::XCommandEnvironment >& Environment )
2795 throw( uno::Exception )
2799 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2800 std::auto_ptr< DAVResourceAccess > xResAccess;
2801 SAL_WNODEPRECATED_DECLARATIONS_POP
2803 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2804 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2807 uno::Any aOwnerAny;
2808 aOwnerAny
2809 <<= OUString("http://ucb.openoffice.org");
2811 ucb::Lock aLock(
2812 ucb::LockScope_EXCLUSIVE,
2813 ucb::LockType_WRITE,
2814 ucb::LockDepth_ZERO,
2815 aOwnerAny,
2816 180, // lock timeout in secs
2817 //-1, // infinite lock
2818 uno::Sequence< OUString >() );
2820 xResAccess->LOCK( aLock, Environment );
2823 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2824 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2827 catch ( DAVException const & e )
2829 cancelCommandExecution( e, Environment, false );
2830 // Unreachable
2835 void Content::unlock(
2836 const uno::Reference< ucb::XCommandEnvironment >& Environment )
2837 throw( uno::Exception )
2841 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2842 std::auto_ptr< DAVResourceAccess > xResAccess;
2843 SAL_WNODEPRECATED_DECLARATIONS_POP
2845 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2846 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
2849 xResAccess->UNLOCK( Environment );
2852 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2853 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
2856 catch ( DAVException const & e )
2858 cancelCommandExecution( e, Environment, false );
2859 // Unreachable
2864 bool Content::exchangeIdentity(
2865 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2867 if ( !xNewId.is() )
2868 return false;
2870 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2872 uno::Reference< ucb::XContent > xThis = this;
2874 // Already persistent?
2875 if ( m_bTransient )
2877 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2878 return false;
2881 // Exchange own identitity.
2883 // Fail, if a content with given id already exists.
2884 // if ( !hasData( xNewId ) )
2886 OUString aOldURL = m_xIdentifier->getContentIdentifier();
2888 aGuard.clear();
2889 if ( exchange( xNewId ) )
2891 // Process instanciated children...
2893 ContentRefList aChildren;
2894 queryChildren( aChildren );
2896 ContentRefList::const_iterator it = aChildren.begin();
2897 ContentRefList::const_iterator end = aChildren.end();
2899 while ( it != end )
2901 ContentRef xChild = (*it);
2903 // Create new content identifier for the child...
2904 uno::Reference< ucb::XContentIdentifier >
2905 xOldChildId = xChild->getIdentifier();
2906 OUString aOldChildURL
2907 = xOldChildId->getContentIdentifier();
2908 OUString aNewChildURL
2909 = aOldChildURL.replaceAt(
2911 aOldURL.getLength(),
2912 xNewId->getContentIdentifier() );
2913 uno::Reference< ucb::XContentIdentifier > xNewChildId
2914 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2916 if ( !xChild->exchangeIdentity( xNewChildId ) )
2917 return false;
2919 ++it;
2921 return true;
2925 OSL_FAIL( "Content::exchangeIdentity - "
2926 "Panic! Cannot exchange identity!" );
2927 return false;
2931 bool Content::isFolder(
2932 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
2933 throw( uno::Exception, std::exception )
2936 osl::MutexGuard aGuard( m_aMutex );
2938 if ( m_bTransient )
2939 return m_bCollection;
2942 uno::Sequence< beans::Property > aProperties( 1 );
2943 aProperties[ 0 ].Name = "IsFolder";
2944 aProperties[ 0 ].Handle = -1;
2945 uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) );
2946 if ( xRow.is() )
2950 return xRow->getBoolean( 1 );
2952 catch ( sdbc::SQLException const & )
2957 return false;
2961 uno::Any Content::MapDAVException( const DAVException & e, bool bWrite )
2963 // Map DAVException...
2964 uno::Any aException;
2966 OUString aURL;
2967 if ( m_bTransient )
2969 aURL = getParentURL();
2970 if ( aURL.lastIndexOf('/') != ( aURL.getLength() - 1 ) )
2971 aURL += "/";
2973 aURL += m_aEscapedTitle;
2975 else
2977 aURL = m_xIdentifier->getContentIdentifier();
2980 switch ( e.getStatus() )
2982 case SC_NOT_FOUND:
2984 uno::Sequence< uno::Any > aArgs( 1 );
2985 aArgs[ 0 ] <<= beans::PropertyValue(
2986 OUString("Uri"), -1,
2987 uno::makeAny(aURL),
2988 beans::PropertyState_DIRECT_VALUE);
2990 aException <<=
2991 ucb::InteractiveAugmentedIOException(
2992 OUString("Not found!"),
2993 static_cast< cppu::OWeakObject * >( this ),
2994 task::InteractionClassification_ERROR,
2995 ucb::IOErrorCode_NOT_EXISTING,
2996 aArgs );
2997 return aException;
2999 default:
3000 break;
3003 switch ( e.getError() )
3005 case DAVException::DAV_HTTP_ERROR:
3007 if ( bWrite )
3008 aException <<=
3009 ucb::InteractiveNetworkWriteException(
3010 e.getData(),
3011 static_cast< cppu::OWeakObject * >( this ),
3012 task::InteractionClassification_ERROR,
3013 e.getData() );
3014 else
3015 aException <<=
3016 ucb::InteractiveNetworkReadException(
3017 e.getData(),
3018 static_cast< cppu::OWeakObject * >( this ),
3019 task::InteractionClassification_ERROR,
3020 e.getData() );
3021 break;
3024 case DAVException::DAV_HTTP_LOOKUP:
3025 aException <<=
3026 ucb::InteractiveNetworkResolveNameException(
3027 OUString(),
3028 static_cast< cppu::OWeakObject * >( this ),
3029 task::InteractionClassification_ERROR,
3030 e.getData() );
3031 break;
3033 // @@@ No matching InteractiveNetwork*Exception
3034 // case DAVException::DAV_HTTP_AUTH:
3035 // break;
3037 // @@@ No matching InteractiveNetwork*Exception
3038 // case DAVException::DAV_HTTP_AUTHPROXY:
3039 // break;
3041 case DAVException::DAV_HTTP_CONNECT:
3042 aException <<=
3043 ucb::InteractiveNetworkConnectException(
3044 OUString(),
3045 static_cast< cppu::OWeakObject * >( this ),
3046 task::InteractionClassification_ERROR,
3047 e.getData() );
3048 break;
3050 // @@@ No matching InteractiveNetwork*Exception
3051 // case DAVException::DAV_HTTP_TIMEOUT:
3052 // break;
3054 // @@@ No matching InteractiveNetwork*Exception
3055 // case DAVException::DAV_HTTP_REDIRECT:
3056 // break;
3058 // @@@ No matching InteractiveNetwork*Exception
3059 // case DAVException::DAV_SESSION_CREATE:
3060 // break;
3062 case DAVException::DAV_INVALID_ARG:
3063 aException <<=
3064 lang::IllegalArgumentException(
3065 OUString(),
3066 static_cast< cppu::OWeakObject * >( this ),
3067 -1 );
3068 break;
3070 case DAVException::DAV_LOCKED:
3071 aException <<=
3072 ucb::InteractiveLockingLockedException(
3073 OUString("Locked!"),
3074 static_cast< cppu::OWeakObject * >( this ),
3075 task::InteractionClassification_ERROR,
3076 aURL,
3077 sal_False ); // not SelfOwned
3078 break;
3080 case DAVException::DAV_LOCKED_SELF:
3081 aException <<=
3082 ucb::InteractiveLockingLockedException(
3083 OUString("Locked (self!)"),
3084 static_cast< cppu::OWeakObject * >( this ),
3085 task::InteractionClassification_ERROR,
3086 aURL,
3087 sal_True ); // SelfOwned
3088 break;
3090 case DAVException::DAV_NOT_LOCKED:
3091 aException <<=
3092 ucb::InteractiveLockingNotLockedException(
3093 OUString("Not locked!"),
3094 static_cast< cppu::OWeakObject * >( this ),
3095 task::InteractionClassification_ERROR,
3096 aURL );
3097 break;
3099 case DAVException::DAV_LOCK_EXPIRED:
3100 aException <<=
3101 ucb::InteractiveLockingLockExpiredException(
3102 OUString("Lock expired!"),
3103 static_cast< cppu::OWeakObject * >( this ),
3104 task::InteractionClassification_ERROR,
3105 aURL );
3106 break;
3108 default:
3109 aException <<=
3110 ucb::InteractiveNetworkGeneralException(
3111 OUString(),
3112 static_cast< cppu::OWeakObject * >( this ),
3113 task::InteractionClassification_ERROR );
3114 break;
3117 return aException;
3121 // static
3122 bool Content::shouldAccessNetworkAfterException( const DAVException & e )
3124 if ( ( e.getStatus() == SC_NOT_FOUND ) ||
3125 ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) ||
3126 ( e.getError() == DAVException::DAV_HTTP_CONNECT ) ||
3127 ( e.getError() == DAVException::DAV_HTTP_AUTH ) ||
3128 ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY ) )
3129 return false;
3131 return true;
3135 void Content::cancelCommandExecution(
3136 const DAVException & e,
3137 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
3138 bool bWrite /* = sal_False */ )
3139 throw ( uno::Exception )
3141 ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv );
3142 // Unreachable
3146 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3147 const OUString
3148 Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess )
3150 osl::Guard< osl::Mutex > aGuard( m_aMutex );
3152 // First, try to obtain value of response header "Content-Location".
3153 if ( m_xCachedProps.get() )
3155 OUString aLocation;
3156 m_xCachedProps->getValue( OUString( "Content-Location" ) ) >>= aLocation;
3157 if ( !aLocation.isEmpty() )
3161 // Do not use m_xIdentifier->getContentIdentifier() because it
3162 // for example does not reflect redirects applied to requests
3163 // done using the original URI but m_xResAccess' URI does.
3164 return rtl::Uri::convertRelToAbs( rResAccess->getURL(),
3165 aLocation );
3167 catch ( rtl::MalformedUriException const & )
3173 return OUString( rResAccess->getURL() );
3177 Content::ResourceType Content::getResourceType(
3178 const uno::Reference< ucb::XCommandEnvironment >& xEnv,
3179 const std::auto_ptr< DAVResourceAccess > & rResAccess,
3180 bool * networkAccessAllowed)
3181 throw ( uno::Exception, std::exception )
3184 osl::MutexGuard g(m_aMutex);
3185 if (m_eResourceType != UNKNOWN) {
3186 return m_eResourceType;
3190 ResourceType eResourceType = UNKNOWN;
3192 const OUString & rURL = rResAccess->getURL();
3193 const OUString aScheme(
3194 rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() );
3196 if ( aScheme == FTP_URL_SCHEME )
3198 eResourceType = FTP;
3200 else
3204 // Try to fetch some frequently used property value, e.g. those
3205 // used when loading documents... along with identifying whether
3206 // this is a DAV resource.
3207 std::vector< DAVResource > resources;
3208 std::vector< OUString > aPropNames;
3209 uno::Sequence< beans::Property > aProperties( 5 );
3210 aProperties[ 0 ].Name = "IsFolder";
3211 aProperties[ 1 ].Name = "IsDocument";
3212 aProperties[ 2 ].Name = "IsReadOnly";
3213 aProperties[ 3 ].Name = "MediaType";
3214 aProperties[ 4 ].Name = DAVProperties::SUPPORTEDLOCK;
3216 ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames );
3218 rResAccess->PROPFIND( DAVZERO, aPropNames, resources, xEnv );
3220 if ( resources.size() == 1 )
3222 osl::MutexGuard g(m_aMutex);
3223 m_xCachedProps.reset(
3224 new CachableContentProperties( resources[ 0 ] ) );
3225 m_xCachedProps->containsAllNames(
3226 aProperties, m_aFailedPropNames );
3229 eResourceType = DAV;
3231 catch ( DAVException const & e )
3233 rResAccess->resetUri();
3235 if ( e.getStatus() == SC_METHOD_NOT_ALLOWED )
3237 // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the
3238 // resource is NON_DAV
3239 eResourceType = NON_DAV;
3241 else if (networkAccessAllowed != 0)
3243 *networkAccessAllowed = *networkAccessAllowed
3244 && shouldAccessNetworkAfterException(e);
3249 osl::MutexGuard g(m_aMutex);
3250 if (m_eResourceType == UNKNOWN) {
3251 m_eResourceType = eResourceType;
3252 } else {
3253 SAL_WARN_IF(
3254 eResourceType != m_eResourceType, "ucb.ucp.webdav",
3255 "different resource types for <" << rURL << ">: "
3256 << +eResourceType << " vs. " << +m_eResourceType);
3258 return m_eResourceType;
3260 SAL_WNODEPRECATED_DECLARATIONS_POP
3263 Content::ResourceType Content::getResourceType(
3264 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
3265 throw ( uno::Exception, std::exception )
3267 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3268 std::auto_ptr< DAVResourceAccess > xResAccess;
3269 SAL_WNODEPRECATED_DECLARATIONS_POP
3271 osl::MutexGuard aGuard( m_aMutex );
3272 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
3274 Content::ResourceType const ret = getResourceType( xEnv, xResAccess );
3276 osl::Guard< osl::Mutex > aGuard( m_aMutex );
3277 m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
3279 return ret;
3282 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */