| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_ucb.hxx" |
| |
| /************************************************************************** |
| TODO |
| ************************************************************************** |
| |
| *************************************************************************/ |
| |
| #include <osl/diagnose.h> |
| #include <osl/doublecheckedlocking.h> |
| #include <rtl/uri.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <ucbhelper/contentidentifier.hxx> |
| #include <ucbhelper/propertyvalueset.hxx> |
| #include <ucbhelper/simpleinteractionrequest.hxx> |
| #include <ucbhelper/cancelcommandexecution.hxx> |
| |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/beans/PropertySetInfoChange.hpp> |
| #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/io/XActiveDataSink.hpp> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/lang/IllegalAccessException.hpp> |
| #include <com/sun/star/task/PasswordContainerInteractionHandler.hpp> |
| #include <com/sun/star/ucb/CommandEnvironment.hpp> |
| #include <com/sun/star/ucb/CommandFailedException.hpp> |
| #include <com/sun/star/ucb/ContentInfoAttribute.hpp> |
| #include <com/sun/star/ucb/InsertCommandArgument.hpp> |
| #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> |
| #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> |
| #include <com/sun/star/ucb/InteractiveLockingLockedException.hpp> |
| #include <com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp> |
| #include <com/sun/star/ucb/InteractiveLockingNotLockedException.hpp> |
| #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp> |
| #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp> |
| #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp> |
| #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp> |
| #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp> |
| #include <com/sun/star/ucb/MissingInputStreamException.hpp> |
| #include <com/sun/star/ucb/MissingPropertiesException.hpp> |
| #include <com/sun/star/ucb/NameClash.hpp> |
| #include <com/sun/star/ucb/NameClashException.hpp> |
| #include <com/sun/star/ucb/OpenCommandArgument2.hpp> |
| #include <com/sun/star/ucb/OpenMode.hpp> |
| #include <com/sun/star/ucb/PostCommandArgument2.hpp> |
| #include <com/sun/star/ucb/PropertyCommandArgument.hpp> |
| #include <com/sun/star/ucb/TransferInfo.hpp> |
| #include <com/sun/star/ucb/UnsupportedCommandException.hpp> |
| #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> |
| #include <com/sun/star/ucb/UnsupportedNameClashException.hpp> |
| #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> |
| #include <com/sun/star/ucb/XCommandInfo.hpp> |
| #include <com/sun/star/ucb/XPersistentPropertySet.hpp> |
| #include <com/sun/star/uno/XComponentContext.hpp> |
| |
| #include "webdavcontent.hxx" |
| #include "webdavprovider.hxx" |
| #include "webdavresultset.hxx" |
| #include "ContentProperties.hxx" |
| #include "SerfUri.hxx" |
| #include "UCBDeadPropertyValue.hxx" |
| |
| using namespace com::sun::star; |
| using namespace http_dav_ucp; |
| |
| namespace |
| { |
| static void lcl_sendPartialGETRequest( bool &bError, |
| DAVException &aLastException, |
| const std::vector< rtl::OUString > aProps, |
| std::vector< rtl::OUString > &aHeaderNames, |
| const std::auto_ptr< DAVResourceAccess > &xResAccess, |
| std::auto_ptr< ContentProperties > &xProps, |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| { |
| bool bIsRequestSize = false; |
| DAVResource aResource; |
| DAVRequestHeaders aPartialGet; |
| aPartialGet.push_back( |
| DAVRequestHeader( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Range" ) ), |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bytes=0-0" )))); |
| |
| for ( std::vector< rtl::OUString >::const_iterator it = aHeaderNames.begin(); |
| it != aHeaderNames.end(); it++ ) |
| { |
| if ( it->equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Length" ) ) ) |
| { |
| bIsRequestSize = true; |
| break; |
| } |
| } |
| |
| if ( bIsRequestSize ) |
| { |
| // we need to know if the server accepts range requests for a resource |
| // and the range unit it uses |
| aHeaderNames.push_back( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Accept-Ranges" ) ) ); |
| aHeaderNames.push_back( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Content-Range" ) ) ); |
| } |
| try |
| { |
| uno::Reference< io::XInputStream > xIn = xResAccess->GET( aPartialGet, |
| aHeaderNames, |
| aResource, |
| xEnv ); |
| bError = false; |
| |
| if ( bIsRequestSize ) |
| { |
| // the ContentProperties maps "Content-Length" to the UCB "Size" property |
| // This would have an unrealistic value of 1 byte because we did only a partial GET |
| // Solution: if "Content-Range" is present, map it with UCB "Size" property |
| rtl::OUString aAcceptRanges, aContentRange, aContentLength; |
| std::vector< DAVPropertyValue > &aResponseProps = aResource.properties; |
| for ( std::vector< DAVPropertyValue >::const_iterator it = aResponseProps.begin(); |
| it != aResponseProps.end(); it++ ) |
| { |
| if ( it->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Accept-Ranges" ) ) ) |
| it->Value >>= aAcceptRanges; |
| else if ( it->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Range" ) ) ) |
| it->Value >>= aContentRange; |
| else if ( it->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Length" ) ) ) |
| it->Value >>= aContentLength; |
| } |
| |
| sal_Int64 nSize = 1; |
| if ( aContentLength.getLength() ) |
| { |
| nSize = aContentLength.toInt64(); |
| } |
| |
| // according to http://tools.ietf.org/html/rfc2616#section-3.12 |
| // the only range unit defined is "bytes" and implementations |
| // MAY ignore ranges specified using other units. |
| if ( nSize == 1 && |
| aContentRange.getLength() && |
| aAcceptRanges.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "bytes" ) ) ) |
| { |
| // Parse the Content-Range to get the size |
| // vid. http://tools.ietf.org/html/rfc2616#section-14.16 |
| // Content-Range: <range unit> <bytes range>/<size> |
| sal_Int32 nSlash = aContentRange.lastIndexOf( sal_Unicode('/')); |
| if ( nSlash != -1 ) |
| { |
| rtl::OUString aSize = aContentRange.copy( nSlash + 1 ); |
| // "*" means that the instance-length is unknown at the time when the response was generated |
| if ( !aSize.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "*" ))) |
| { |
| for ( std::vector< DAVPropertyValue >::iterator it = aResponseProps.begin(); |
| it != aResponseProps.end(); it++ ) |
| { |
| if ( it->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Length" ) ) ) |
| { |
| it->Value <<= aSize; |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if ( xProps.get() ) |
| xProps->addProperties( |
| aProps, |
| ContentProperties( aResource ) ); |
| else |
| xProps.reset ( new ContentProperties( aResource ) ); |
| } |
| catch ( DAVException const & ex ) |
| { |
| aLastException = ex; |
| } |
| } |
| } |
| |
| //========================================================================= |
| //========================================================================= |
| // |
| // Content Implementation. |
| // |
| //========================================================================= |
| //========================================================================= |
| |
| //========================================================================= |
| // ctr for content on an existing webdav resource |
| Content::Content( |
| const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, |
| ContentProvider* pProvider, |
| const uno::Reference< ucb::XContentIdentifier >& Identifier, |
| rtl::Reference< DAVSessionFactory > const & rSessionFactory ) |
| throw ( ucb::ContentCreationException ) |
| : ContentImplHelper( rxSMgr, pProvider, Identifier ), |
| m_eResourceType( UNKNOWN ), |
| m_pProvider( pProvider ), |
| m_bTransient( false ), |
| m_bCollection( false ), |
| m_bDidGetOrHead( false ) |
| { |
| try |
| { |
| m_xResAccess.reset( new DAVResourceAccess( |
| rxSMgr, |
| rSessionFactory, |
| Identifier->getContentIdentifier() ) ); |
| |
| SerfUri aURI( Identifier->getContentIdentifier() ); |
| m_aEscapedTitle = aURI.GetPathBaseName(); |
| } |
| catch ( DAVException const & ) |
| { |
| throw ucb::ContentCreationException(); |
| } |
| } |
| |
| //========================================================================= |
| // ctr for content on an non-existing webdav resource |
| Content::Content( |
| const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, |
| ContentProvider* pProvider, |
| const uno::Reference< ucb::XContentIdentifier >& Identifier, |
| rtl::Reference< DAVSessionFactory > const & rSessionFactory, |
| sal_Bool isCollection ) |
| throw ( ucb::ContentCreationException ) |
| : ContentImplHelper( rxSMgr, pProvider, Identifier ), |
| m_eResourceType( UNKNOWN ), |
| m_pProvider( pProvider ), |
| m_bTransient( true ), |
| m_bCollection( isCollection ), |
| m_bDidGetOrHead( false ) |
| { |
| try |
| { |
| m_xResAccess.reset( new DAVResourceAccess( |
| rxSMgr, rSessionFactory, Identifier->getContentIdentifier() ) ); |
| } |
| catch ( DAVException const & ) |
| { |
| throw ucb::ContentCreationException(); |
| } |
| |
| // Do not set m_aEscapedTitle here! Content::insert relays on this!!! |
| } |
| |
| //========================================================================= |
| // virtual |
| Content::~Content() |
| { |
| } |
| |
| //========================================================================= |
| // |
| // XInterface methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL Content::acquire() |
| throw( ) |
| { |
| ContentImplHelper::acquire(); |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL Content::release() |
| throw( ) |
| { |
| ContentImplHelper::release(); |
| } |
| |
| //========================================================================= |
| // virtual |
| uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) |
| throw ( uno::RuntimeException ) |
| { |
| // Note: isFolder may require network activities! So call it only |
| // if it is really necessary!!! |
| uno::Any aRet = cppu::queryInterface( |
| rType, |
| static_cast< ucb::XContentCreator * >( this ) ); |
| if ( aRet.hasValue() ) |
| { |
| try |
| { |
| uno::Reference< beans::XPropertySet > const xProps( |
| m_xSMgr, uno::UNO_QUERY_THROW ); |
| uno::Reference< uno::XComponentContext > xCtx; |
| xCtx.set( xProps->getPropertyValue( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), |
| uno::UNO_QUERY_THROW ); |
| |
| uno::Reference< task::XInteractionHandler > xIH( |
| task::PasswordContainerInteractionHandler::create( xCtx ) ); |
| |
| // Supply a command env to isFolder() that contains an interaction |
| // handler that uses the password container service to obtain |
| // credentials without displaying a password gui. |
| |
| uno::Reference< ucb::XCommandEnvironment > xCmdEnv( |
| ucb::CommandEnvironment::create( |
| xCtx, |
| xIH, |
| uno::Reference< ucb::XProgressHandler >() ) ); |
| |
| return isFolder( xCmdEnv ) ? aRet : uno::Any(); |
| } |
| catch ( uno::RuntimeException const & ) |
| { |
| throw; |
| } |
| catch ( uno::Exception const & ) |
| { |
| return uno::Any(); |
| } |
| } |
| return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); |
| } |
| |
| //========================================================================= |
| // |
| // XTypeProvider methods. |
| // |
| //========================================================================= |
| |
| XTYPEPROVIDER_COMMON_IMPL( Content ); |
| |
| //========================================================================= |
| // virtual |
| uno::Sequence< uno::Type > SAL_CALL Content::getTypes() |
| throw( uno::RuntimeException ) |
| { |
| sal_Bool bFolder = sal_False; |
| try |
| { |
| bFolder |
| = isFolder( uno::Reference< ucb::XCommandEnvironment >() ); |
| } |
| catch ( uno::RuntimeException const & ) |
| { |
| throw; |
| } |
| catch ( uno::Exception const & ) |
| { |
| } |
| |
| cppu::OTypeCollection * pCollection = 0; |
| |
| if ( bFolder ) |
| { |
| static cppu::OTypeCollection* pFolderTypes = 0; |
| |
| pCollection = pFolderTypes; |
| if ( !pCollection ) |
| { |
| osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); |
| |
| pCollection = pFolderTypes; |
| if ( !pCollection ) |
| { |
| static cppu::OTypeCollection aCollection( |
| CPPU_TYPE_REF( lang::XTypeProvider ), |
| CPPU_TYPE_REF( lang::XServiceInfo ), |
| CPPU_TYPE_REF( lang::XComponent ), |
| CPPU_TYPE_REF( ucb::XContent ), |
| CPPU_TYPE_REF( ucb::XCommandProcessor ), |
| CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), |
| CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), |
| CPPU_TYPE_REF( beans::XPropertyContainer ), |
| CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), |
| CPPU_TYPE_REF( container::XChild ), |
| CPPU_TYPE_REF( ucb::XContentCreator ) ); // !! |
| pCollection = &aCollection; |
| OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
| pFolderTypes = pCollection; |
| } |
| } |
| else { |
| OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
| } |
| } |
| else |
| { |
| static cppu::OTypeCollection* pDocumentTypes = 0; |
| |
| pCollection = pDocumentTypes; |
| if ( !pCollection ) |
| { |
| osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); |
| |
| pCollection = pDocumentTypes; |
| if ( !pCollection ) |
| { |
| static cppu::OTypeCollection aCollection( |
| CPPU_TYPE_REF( lang::XTypeProvider ), |
| CPPU_TYPE_REF( lang::XServiceInfo ), |
| CPPU_TYPE_REF( lang::XComponent ), |
| CPPU_TYPE_REF( ucb::XContent ), |
| CPPU_TYPE_REF( ucb::XCommandProcessor ), |
| CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), |
| CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), |
| CPPU_TYPE_REF( beans::XPropertyContainer ), |
| CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), |
| CPPU_TYPE_REF( container::XChild ) ); |
| pCollection = &aCollection; |
| OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
| pDocumentTypes = pCollection; |
| } |
| } |
| else { |
| OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
| } |
| } |
| |
| return (*pCollection).getTypes(); |
| } |
| |
| //========================================================================= |
| // |
| // XServiceInfo methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| rtl::OUString SAL_CALL Content::getImplementationName() |
| throw( uno::RuntimeException ) |
| { |
| return rtl::OUString::createFromAscii( |
| "com.sun.star.comp.ucb.WebDAVContent" ); |
| } |
| |
| //========================================================================= |
| // virtual |
| uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() |
| throw( uno::RuntimeException ) |
| { |
| uno::Sequence< rtl::OUString > aSNS( 1 ); |
| aSNS.getArray()[ 0 ] |
| = rtl::OUString::createFromAscii( WEBDAV_CONTENT_SERVICE_NAME ); |
| return aSNS; |
| } |
| |
| //========================================================================= |
| // |
| // XContent methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| rtl::OUString SAL_CALL Content::getContentType() |
| throw( uno::RuntimeException ) |
| { |
| sal_Bool bFolder = sal_False; |
| try |
| { |
| bFolder |
| = isFolder( uno::Reference< ucb::XCommandEnvironment >() ); |
| } |
| catch ( uno::RuntimeException const & ) |
| { |
| throw; |
| } |
| catch ( uno::Exception const & ) |
| { |
| } |
| |
| if ( bFolder ) |
| return rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE ); |
| |
| return rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE ); |
| } |
| |
| //========================================================================= |
| // |
| // XCommandProcessor methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| uno::Any SAL_CALL Content::execute( |
| const ucb::Command& aCommand, |
| sal_Int32 /*CommandId*/, |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception, |
| ucb::CommandAbortedException, |
| uno::RuntimeException ) |
| { |
| OSL_TRACE( ">>>>> Content::execute: start: command: %s, env: %s", |
| rtl::OUStringToOString( aCommand.Name, |
| RTL_TEXTENCODING_UTF8 ).getStr(), |
| Environment.is() ? "present" : "missing" ); |
| |
| uno::Any aRet; |
| |
| if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // getPropertyValues |
| ////////////////////////////////////////////////////////////////// |
| |
| uno::Sequence< beans::Property > Properties; |
| if ( !( aCommand.Argument >>= Properties ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| aRet <<= getPropertyValues( Properties, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // setPropertyValues |
| ////////////////////////////////////////////////////////////////// |
| |
| uno::Sequence< beans::PropertyValue > aProperties; |
| if ( !( aCommand.Argument >>= aProperties ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| if ( !aProperties.getLength() ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "No properties!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| aRet <<= setPropertyValues( aProperties, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // getPropertySetInfo |
| ////////////////////////////////////////////////////////////////// |
| |
| // Note: Implemented by base class. |
| aRet <<= getPropertySetInfo( Environment, |
| sal_False /* don't cache data */ ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // getCommandInfo |
| ////////////////////////////////////////////////////////////////// |
| |
| // Note: Implemented by base class. |
| aRet <<= getCommandInfo( Environment, sal_False ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "open" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // open |
| ////////////////////////////////////////////////////////////////// |
| |
| ucb::OpenCommandArgument2 aOpenCommand; |
| if ( !( aCommand.Argument >>= aOpenCommand ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| aRet = open( aOpenCommand, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // insert |
| ////////////////////////////////////////////////////////////////// |
| |
| ucb::InsertCommandArgument arg; |
| if ( !( aCommand.Argument >>= arg ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| insert( arg.Data, arg.ReplaceExisting, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // delete |
| ////////////////////////////////////////////////////////////////// |
| |
| sal_Bool bDeletePhysical = sal_False; |
| aCommand.Argument >>= bDeletePhysical; |
| |
| // KSO: Ignore parameter and destroy the content, if you don't support |
| // putting objects into trashcan. ( Since we do not have a trash can |
| // service yet (src603), you actually have no other choice. ) |
| // if ( bDeletePhysical ) |
| // { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| xResAccess->DESTROY( Environment ); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, Environment, sal_True ); |
| // Unreachable |
| } |
| // } |
| |
| // Propagate destruction. |
| destroy( bDeletePhysical ); |
| |
| // Remove own and all children's Additional Core Properties. |
| removeAdditionalPropertySet( sal_True ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) |
| && isFolder( Environment ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // transfer |
| // ( Not available at documents ) |
| ////////////////////////////////////////////////////////////////// |
| |
| ucb::TransferInfo transferArgs; |
| if ( !( aCommand.Argument >>= transferArgs ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| transfer( transferArgs, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "post" ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // post |
| ////////////////////////////////////////////////////////////////// |
| |
| ucb::PostCommandArgument2 aArg; |
| if ( !( aCommand.Argument >>= aArg ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| post( aArg, Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "lock" ) ) && |
| supportsExclusiveWriteLock( Environment ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // lock |
| ////////////////////////////////////////////////////////////////// |
| |
| lock( Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) && |
| supportsExclusiveWriteLock( Environment ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // unlock |
| ////////////////////////////////////////////////////////////////// |
| |
| unlock( Environment ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) && |
| isFolder( Environment ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // createNewContent |
| ////////////////////////////////////////////////////////////////// |
| |
| ucb::ContentInfo aArg; |
| if ( !( aCommand.Argument >>= aArg ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| aRet = uno::makeAny( createNewContent( aArg ) ); |
| } |
| else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "addProperty" ))) |
| { |
| ucb::PropertyCommandArgument aPropArg; |
| if ( !( aCommand.Argument >>= aPropArg )) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "Wrong argument type!" )), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| } |
| |
| // TODO when/if XPropertyContainer is removed, |
| // the command execution can be canceled in addProperty |
| try |
| { |
| addProperty( aPropArg, Environment ); |
| } |
| catch ( const beans::PropertyExistException &e ) |
| { |
| ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); |
| } |
| catch ( const beans::IllegalTypeException&e ) |
| { |
| ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); |
| } |
| catch ( const lang::IllegalArgumentException&e ) |
| { |
| ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); |
| } |
| } |
| else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "removeProperty" ))) |
| { |
| rtl::OUString sPropName; |
| if ( !( aCommand.Argument >>= sPropName ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( lang::IllegalArgumentException( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "Wrong argument type!" )), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| } |
| |
| // TODO when/if XPropertyContainer is removed, |
| // the command execution can be canceled in removeProperty |
| try |
| { |
| removeProperty( sPropName, Environment ); |
| } |
| catch( const beans::UnknownPropertyException &e ) |
| { |
| ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); |
| } |
| catch( const beans::NotRemoveableException &e ) |
| { |
| ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); |
| } |
| } |
| else |
| { |
| ////////////////////////////////////////////////////////////////// |
| // Unsupported command |
| ////////////////////////////////////////////////////////////////// |
| |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( ucb::UnsupportedCommandException( |
| aCommand.Name, |
| static_cast< cppu::OWeakObject * >( this ) ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| OSL_TRACE( "<<<<< Content::execute: end: command: %s", |
| rtl::OUStringToOString( aCommand.Name, |
| RTL_TEXTENCODING_UTF8 ).getStr() ); |
| |
| return aRet; |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) |
| throw( uno::RuntimeException ) |
| { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| xResAccess->abort(); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & ) |
| { |
| // abort failed! |
| } |
| } |
| |
| //========================================================================= |
| // |
| // XPropertyContainer methods. |
| // |
| //========================================================================= |
| |
| void Content::addProperty( const com::sun::star::ucb::PropertyCommandArgument &aCmdArg, |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw( beans::PropertyExistException, |
| beans::IllegalTypeException, |
| lang::IllegalArgumentException, |
| uno::RuntimeException ) |
| { |
| // if ( m_bTransient ) |
| // @@@ ??? |
| const beans::Property aProperty = aCmdArg.Property; |
| const uno::Any aDefaultValue = aCmdArg.DefaultValue; |
| |
| // check property Name |
| if ( !aProperty.Name.getLength() ) |
| throw lang::IllegalArgumentException( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "\"addProperty\" with empty Property.Name")), |
| static_cast< ::cppu::OWeakObject * >( this ), |
| -1 ); |
| |
| // Check property type. |
| if ( !UCBDeadPropertyValue::supportsType( aProperty.Type ) ) |
| throw beans::IllegalTypeException( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "\"addProperty\" unsupported Property.Type")), |
| static_cast< ::cppu::OWeakObject * >( this ) ); |
| |
| // check default value |
| if ( aDefaultValue.hasValue() && aDefaultValue.getValueType() != aProperty.Type ) |
| throw beans::IllegalTypeException( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "\"addProperty\" DefaultValue does not match Property.Type")), |
| static_cast< ::cppu::OWeakObject * >( this ) ); |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Make sure a property with the requested name does not already |
| // exist in dynamic and static(!) properties. |
| ////////////////////////////////////////////////////////////////////// |
| |
| // Take into account special properties with custom namespace |
| // using <prop:the_propname xmlns:prop="the_namespace"> |
| rtl::OUString aSpecialName; |
| bool bIsSpecial = DAVProperties::isUCBSpecialProperty( aProperty.Name, aSpecialName ); |
| |
| // Note: This requires network access! |
| if ( getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) |
| ->hasPropertyByName( bIsSpecial ? aSpecialName : aProperty.Name ) ) |
| { |
| // Property does already exist. |
| throw beans::PropertyExistException(); |
| } |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Add a new dynamic property. |
| ////////////////////////////////////////////////////////////////////// |
| |
| ProppatchValue aValue( PROPSET, aProperty.Name, aDefaultValue ); |
| |
| std::vector< ProppatchValue > aProppatchValues; |
| aProppatchValues.push_back( aValue ); |
| |
| try |
| { |
| // Set property value at server. |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| xResAccess->PROPPATCH( aProppatchValues, xEnv ); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| // Notify propertyset info change listeners. |
| beans::PropertySetInfoChangeEvent evt( |
| static_cast< cppu::OWeakObject * >( this ), |
| bIsSpecial ? aSpecialName : aProperty.Name, |
| -1, // No handle available |
| beans::PropertySetInfoChange::PROPERTY_INSERTED ); |
| notifyPropertySetInfoChange( evt ); |
| } |
| catch ( DAVException const & e ) |
| { |
| if ( e.getStatus() == SC_FORBIDDEN ) |
| { |
| // Support for setting arbitrary dead properties is optional! |
| |
| // Store property locally. |
| ContentImplHelper::addProperty( bIsSpecial ? aSpecialName : aProperty.Name, |
| aProperty.Attributes, |
| aDefaultValue ); |
| } |
| else |
| { |
| if ( shouldAccessNetworkAfterException( e ) ) |
| { |
| try |
| { |
| const ResourceType & rType = getResourceType( xEnv ); |
| switch ( rType ) |
| { |
| case UNKNOWN: |
| case DAV: |
| throw lang::IllegalArgumentException(); |
| |
| case NON_DAV: |
| // Store property locally. |
| ContentImplHelper::addProperty( bIsSpecial ? aSpecialName : aProperty.Name, |
| aProperty.Attributes, |
| aDefaultValue ); |
| break; |
| |
| default: |
| OSL_ENSURE( sal_False, |
| "Content::addProperty - " |
| "Unsupported resource type!" ); |
| break; |
| } |
| } |
| catch ( uno::Exception const & ) |
| { |
| OSL_ENSURE( sal_False, |
| "Content::addProperty - " |
| "Unable to determine resource type!" ); |
| } |
| } |
| else |
| { |
| OSL_ENSURE( sal_False, |
| "Content::addProperty - " |
| "Unable to determine resource type!" ); |
| } |
| } |
| } |
| } |
| |
| void Content::removeProperty( const rtl::OUString& Name, |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw( beans::UnknownPropertyException, |
| beans::NotRemoveableException, |
| uno::RuntimeException ) |
| { |
| #if 0 |
| // @@@ REMOVEABLE z.Z. nicht richtig an der PropSetInfo gesetzt!!! |
| try |
| { |
| beans::Property aProp |
| = getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) |
| ->getPropertyByName( Name ); |
| |
| if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) ) |
| { |
| // Not removeable! |
| throw beans::NotRemoveableException(); |
| } |
| } |
| catch ( beans::UnknownPropertyException const & ) |
| { |
| //OSL_ENSURE( sal_False, "removeProperty - Unknown property!" ); |
| throw; |
| } |
| #endif |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Try to remove property from server. |
| ////////////////////////////////////////////////////////////////////// |
| |
| try |
| { |
| std::vector< ProppatchValue > aProppatchValues; |
| ProppatchValue aValue( PROPREMOVE, Name, uno::Any() ); |
| aProppatchValues.push_back( aValue ); |
| |
| // Remove property value from server. |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| xResAccess->PROPPATCH( aProppatchValues, xEnv ); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| // Notify propertyset info change listeners. |
| beans::PropertySetInfoChangeEvent evt( |
| static_cast< cppu::OWeakObject * >( this ), |
| Name, |
| -1, // No handle available |
| beans::PropertySetInfoChange::PROPERTY_REMOVED ); |
| notifyPropertySetInfoChange( evt ); |
| } |
| catch ( DAVException const & e ) |
| { |
| if ( e.getStatus() == SC_FORBIDDEN ) |
| { |
| // Support for setting arbitrary dead properties is optional! |
| |
| // Try to remove property from local store. |
| ContentImplHelper::removeProperty( Name ); |
| } |
| else |
| { |
| if ( shouldAccessNetworkAfterException( e ) ) |
| { |
| try |
| { |
| const ResourceType & rType = getResourceType( xEnv ); |
| switch ( rType ) |
| { |
| case UNKNOWN: |
| case DAV: |
| throw beans::UnknownPropertyException(); |
| |
| case NON_DAV: |
| // Try to remove property from local store. |
| ContentImplHelper::removeProperty( Name ); |
| break; |
| |
| default: |
| OSL_ENSURE( sal_False, |
| "Content::removeProperty - " |
| "Unsupported resource type!" ); |
| break; |
| } |
| } |
| catch ( uno::Exception const & ) |
| { |
| OSL_ENSURE( sal_False, |
| "Content::removeProperty - " |
| "Unable to determine resource type!" ); |
| } |
| } |
| else |
| { |
| OSL_ENSURE( sal_False, |
| "Content::removeProperty - " |
| "Unable to determine resource type!" ); |
| // throw beans::UnknownPropertyException(); |
| } |
| } |
| } |
| } |
| |
| // virtual |
| void SAL_CALL Content::addProperty( const rtl::OUString& Name, |
| sal_Int16 Attributes, |
| const uno::Any& DefaultValue ) |
| throw( beans::PropertyExistException, |
| beans::IllegalTypeException, |
| lang::IllegalArgumentException, |
| uno::RuntimeException ) |
| { |
| beans::Property aProperty; |
| aProperty.Name = Name; |
| aProperty.Type = DefaultValue.getValueType(); |
| aProperty.Attributes = Attributes; |
| aProperty.Handle = -1; |
| |
| addProperty( ucb::PropertyCommandArgument( aProperty, DefaultValue ), |
| uno::Reference< ucb::XCommandEnvironment >()); |
| } |
| |
| // virtual |
| void SAL_CALL Content::removeProperty( const rtl::OUString& Name ) |
| throw( beans::UnknownPropertyException, |
| beans::NotRemoveableException, |
| uno::RuntimeException ) |
| { |
| removeProperty( Name, |
| uno::Reference< ucb::XCommandEnvironment >() ); |
| } |
| |
| //========================================================================= |
| // |
| // XContentCreator methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| uno::Sequence< ucb::ContentInfo > SAL_CALL |
| Content::queryCreatableContentsInfo() |
| throw( uno::RuntimeException ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| uno::Sequence< ucb::ContentInfo > aSeq( 2 ); |
| |
| // document. |
| aSeq.getArray()[ 0 ].Type |
| = rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE ); |
| aSeq.getArray()[ 0 ].Attributes |
| = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
| | ucb::ContentInfoAttribute::KIND_DOCUMENT; |
| |
| beans::Property aProp; |
| m_pProvider->getProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), aProp ); |
| |
| uno::Sequence< beans::Property > aDocProps( 1 ); |
| aDocProps.getArray()[ 0 ] = aProp; |
| aSeq.getArray()[ 0 ].Properties = aDocProps; |
| |
| // folder. |
| aSeq.getArray()[ 1 ].Type |
| = rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE ); |
| aSeq.getArray()[ 1 ].Attributes |
| = ucb::ContentInfoAttribute::KIND_FOLDER; |
| |
| uno::Sequence< beans::Property > aFolderProps( 1 ); |
| aFolderProps.getArray()[ 0 ] = aProp; |
| aSeq.getArray()[ 1 ].Properties = aFolderProps; |
| return aSeq; |
| } |
| |
| //========================================================================= |
| // virtual |
| uno::Reference< ucb::XContent > SAL_CALL |
| Content::createNewContent( const ucb::ContentInfo& Info ) |
| throw( uno::RuntimeException ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| if ( !Info.Type.getLength() ) |
| return uno::Reference< ucb::XContent >(); |
| |
| if ( ( !Info.Type.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) ) |
| && |
| ( !Info.Type.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( WEBDAV_CONTENT_TYPE ) ) ) ) |
| return uno::Reference< ucb::XContent >(); |
| |
| rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); |
| |
| OSL_ENSURE( aURL.getLength() > 0, |
| "WebdavContent::createNewContent - empty identifier!" ); |
| |
| if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() ) |
| aURL += rtl::OUString::createFromAscii( "/" ); |
| |
| sal_Bool isCollection; |
| if ( Info.Type.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( WEBDAV_COLLECTION_TYPE ) ) ) |
| { |
| aURL += rtl::OUString::createFromAscii( "New_Collection" ); |
| isCollection = sal_True; |
| } |
| else |
| { |
| aURL += rtl::OUString::createFromAscii( "New_Content" ); |
| isCollection = sal_False; |
| } |
| |
| uno::Reference< ucb::XContentIdentifier > xId( |
| new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) ); |
| |
| // create the local content |
| try |
| { |
| return new ::http_dav_ucp::Content( m_xSMgr, |
| m_pProvider, |
| xId, |
| m_xResAccess->getSessionFactory(), |
| isCollection ); |
| } |
| catch ( ucb::ContentCreationException & ) |
| { |
| return uno::Reference< ucb::XContent >(); |
| } |
| } |
| |
| //========================================================================= |
| // virtual |
| rtl::OUString Content::getParentURL() |
| { |
| // <scheme>:// -> "" |
| // <scheme>://foo -> "" |
| // <scheme>://foo/ -> "" |
| // <scheme>://foo/bar -> <scheme>://foo/ |
| // <scheme>://foo/bar/ -> <scheme>://foo/ |
| // <scheme>://foo/bar/abc -> <scheme>://foo/bar/ |
| |
| rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); |
| |
| sal_Int32 nPos = aURL.lastIndexOf( '/' ); |
| if ( nPos == ( aURL.getLength() - 1 ) ) |
| { |
| // Trailing slash found. Skip. |
| nPos = aURL.lastIndexOf( '/', nPos ); |
| } |
| |
| sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos ); |
| if ( nPos1 != -1 ) |
| nPos1 = aURL.lastIndexOf( '/', nPos1 ); |
| |
| if ( nPos1 == -1 ) |
| return rtl::OUString(); |
| |
| return rtl::OUString( aURL.copy( 0, nPos + 1 ) ); |
| } |
| |
| //========================================================================= |
| // |
| // Non-interface methods. |
| // |
| //========================================================================= |
| |
| // static |
| uno::Reference< sdbc::XRow > Content::getPropertyValues( |
| const uno::Reference< lang::XMultiServiceFactory >& rSMgr, |
| const uno::Sequence< beans::Property >& rProperties, |
| const ContentProperties& rData, |
| const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, |
| const rtl::OUString& rContentId ) |
| { |
| // Note: Empty sequence means "get values of all supported properties". |
| |
| rtl::Reference< ::ucbhelper::PropertyValueSet > xRow |
| = new ::ucbhelper::PropertyValueSet( rSMgr ); |
| |
| sal_Int32 nCount = rProperties.getLength(); |
| if ( nCount ) |
| { |
| uno::Reference< beans::XPropertySet > xAdditionalPropSet; |
| sal_Bool bTriedToGetAdditonalPropSet = sal_False; |
| |
| const beans::Property* pProps = rProperties.getConstArray(); |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const beans::Property& rProp = pProps[ n ]; |
| |
| // Process standard UCB, DAV and HTTP properties. |
| const uno::Any & rValue = rData.getValue( rProp.Name ); |
| if ( rValue.hasValue() ) |
| { |
| xRow->appendObject( rProp, rValue ); |
| } |
| else |
| { |
| // Process local Additional Properties. |
| if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) |
| { |
| xAdditionalPropSet |
| = uno::Reference< beans::XPropertySet >( |
| rProvider->getAdditionalPropertySet( rContentId, |
| sal_False ), |
| uno::UNO_QUERY ); |
| bTriedToGetAdditonalPropSet = sal_True; |
| } |
| |
| if ( !xAdditionalPropSet.is() || |
| !xRow->appendPropertySetValue( |
| xAdditionalPropSet, rProp ) ) |
| { |
| // Append empty entry. |
| xRow->appendVoid( rProp ); |
| } |
| } |
| } |
| } |
| else |
| { |
| // Append all standard UCB, DAV and HTTP properties. |
| |
| const std::auto_ptr< PropertyValueMap > & xProps = rData.getProperties(); |
| |
| PropertyValueMap::const_iterator it = xProps->begin(); |
| PropertyValueMap::const_iterator end = xProps->end(); |
| |
| ContentProvider * pProvider |
| = static_cast< ContentProvider * >( rProvider.get() ); |
| beans::Property aProp; |
| |
| while ( it != end ) |
| { |
| if ( pProvider->getProperty( (*it).first, aProp ) ) |
| xRow->appendObject( aProp, (*it).second.value() ); |
| |
| ++it; |
| } |
| |
| // Append all local Additional Properties. |
| uno::Reference< beans::XPropertySet > xSet( |
| rProvider->getAdditionalPropertySet( rContentId, sal_False ), |
| uno::UNO_QUERY ); |
| xRow->appendPropertySet( xSet ); |
| } |
| |
| return uno::Reference< sdbc::XRow >( xRow.get() ); |
| } |
| |
| //========================================================================= |
| uno::Reference< sdbc::XRow > Content::getPropertyValues( |
| const uno::Sequence< beans::Property >& rProperties, |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw ( uno::Exception ) |
| { |
| std::auto_ptr< ContentProperties > xProps; |
| std::auto_ptr< ContentProperties > xCachedProps; |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| rtl::OUString aUnescapedTitle; |
| bool bHasAll = false; |
| uno::Reference< lang::XMultiServiceFactory > xSMgr; |
| uno::Reference< ucb::XContentIdentifier > xIdentifier; |
| rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider; |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| aUnescapedTitle = SerfUri::unescape( m_aEscapedTitle ); |
| xSMgr.set( m_xSMgr ); |
| xIdentifier.set( m_xIdentifier ); |
| xProvider.set( m_xProvider.get() ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| |
| // First, ask cache... |
| if ( m_xCachedProps.get() ) |
| { |
| xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) ); |
| |
| std::vector< rtl::OUString > aMissingProps; |
| if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) ) |
| { |
| // All properties are already in cache! No server access needed. |
| bHasAll = true; |
| } |
| |
| // use the cached ContentProperties instance |
| xProps.reset( new ContentProperties( *xCachedProps.get() ) ); |
| } |
| } |
| |
| if ( !m_bTransient && !bHasAll ) |
| { |
| ///////////////////////////////////////////////////////////////////// |
| // Obtain values from server... |
| ///////////////////////////////////////////////////////////////////// |
| |
| // First, identify whether resource is DAV or not |
| const ResourceType & rType = getResourceType( xEnv, xResAccess ); |
| |
| bool bNetworkAccessAllowed = true; |
| |
| if ( DAV == rType ) |
| { |
| // cache lookup... getResourceType may fill the props cache via |
| // PROPFIND! |
| if ( m_xCachedProps.get() ) |
| { |
| xCachedProps.reset( |
| new ContentProperties( *m_xCachedProps.get() ) ); |
| |
| std::vector< rtl::OUString > aMissingProps; |
| if ( xCachedProps->containsAllNames( |
| rProperties, aMissingProps ) ) |
| { |
| // All properties are already in cache! No server access |
| // needed. |
| bHasAll = true; |
| } |
| |
| // use the cached ContentProperties instance |
| xProps.reset( new ContentProperties( *xCachedProps.get() ) ); |
| } |
| |
| if ( !bHasAll ) |
| { |
| // Only DAV resources support PROPFIND |
| std::vector< rtl::OUString > aPropNames; |
| |
| uno::Sequence< beans::Property > aProperties( |
| rProperties.getLength() ); |
| |
| if ( m_aFailedPropNames.size() > 0 ) |
| { |
| sal_Int32 nProps = 0; |
| sal_Int32 nCount = rProperties.getLength(); |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const rtl::OUString & rName = rProperties[ n ].Name; |
| |
| std::vector< rtl::OUString >::const_iterator it |
| = m_aFailedPropNames.begin(); |
| std::vector< rtl::OUString >::const_iterator end |
| = m_aFailedPropNames.end(); |
| |
| while ( it != end ) |
| { |
| if ( *it == rName ) |
| break; |
| |
| ++it; |
| } |
| |
| if ( it == end ) |
| { |
| aProperties[ nProps ] = rProperties[ n ]; |
| nProps++; |
| } |
| } |
| |
| aProperties.realloc( nProps ); |
| } |
| else |
| { |
| aProperties = rProperties; |
| } |
| |
| if ( aProperties.getLength() > 0 ) |
| ContentProperties::UCBNamesToDAVNames( |
| aProperties, aPropNames ); |
| |
| if ( aPropNames.size() > 0 ) |
| { |
| std::vector< DAVResource > resources; |
| try |
| { |
| xResAccess->PROPFIND( |
| DAVZERO, aPropNames, resources, xEnv ); |
| |
| if ( 1 == resources.size() ) |
| { |
| if ( xProps.get()) |
| xProps->addProperties( |
| aPropNames, |
| ContentProperties( resources[ 0 ] )); |
| else |
| xProps.reset( |
| new ContentProperties( resources[ 0 ] ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| bNetworkAccessAllowed |
| = shouldAccessNetworkAfterException( e ); |
| |
| if ( !bNetworkAccessAllowed ) |
| { |
| cancelCommandExecution( e, xEnv ); |
| // unreachable |
| } |
| } |
| } |
| } |
| } |
| |
| if ( bNetworkAccessAllowed ) |
| { |
| // All properties obtained already? |
| std::vector< rtl::OUString > aMissingProps; |
| if ( !( xProps.get() |
| && xProps->containsAllNames( |
| rProperties, aMissingProps ) ) |
| || !m_bDidGetOrHead ) |
| { |
| // Possibly the missing props can be obtained using a HEAD |
| // request. |
| |
| std::vector< rtl::OUString > aHeaderNames; |
| ContentProperties::UCBNamesToHTTPNames( |
| rProperties, |
| aHeaderNames, |
| true /* bIncludeUnmatched */ ); |
| |
| if ( aHeaderNames.size() > 0 ) |
| { |
| try |
| { |
| DAVResource resource; |
| xResAccess->HEAD( aHeaderNames, resource, xEnv ); |
| m_bDidGetOrHead = true; |
| |
| if ( xProps.get() ) |
| xProps->addProperties( |
| aMissingProps, |
| ContentProperties( resource ) ); |
| else |
| xProps.reset ( new ContentProperties( resource ) ); |
| |
| if ( m_eResourceType == NON_DAV ) |
| xProps->addProperties( aMissingProps, |
| ContentProperties( |
| aUnescapedTitle, |
| false ) ); |
| } |
| catch ( DAVException const & e ) |
| { |
| // non "general-purpose servers" may not support HEAD requests |
| // see http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1 |
| // In this case, perform a partial GET only to get the header info |
| // vid. http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 |
| // WARNING if the server does not support partial GETs, |
| // the GET will transfer the whole content |
| bool bError = true; |
| DAVException aLastException = e; |
| |
| // According to the spec. the origin server SHOULD return |
| // * 405 (Method Not Allowed): |
| // the method is known but not allowed for the requested resource |
| // * 501 (Not Implemented): |
| // the method is unrecognized or not implemented |
| // TODO SC_NOT_FOUND is only for google-code server |
| if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || |
| aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || |
| aLastException.getStatus() == SC_NOT_FOUND ) |
| { |
| lcl_sendPartialGETRequest( bError, |
| aLastException, |
| aMissingProps, |
| aHeaderNames, |
| xResAccess, |
| xProps, |
| xEnv ); |
| m_bDidGetOrHead = !bError; |
| } |
| |
| if ( bError ) |
| { |
| if ( !(bNetworkAccessAllowed |
| = shouldAccessNetworkAfterException( aLastException )) ) |
| { |
| cancelCommandExecution( aLastException, xEnv ); |
| // unreachable |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // might trigger HTTP redirect. |
| // Therefore, title must be updated here. |
| SerfUri aUri( xResAccess->getURL() ); |
| aUnescapedTitle = aUri.GetPathBaseNameUnescaped(); |
| |
| if ( rType == UNKNOWN ) |
| { |
| xProps.reset( new ContentProperties( aUnescapedTitle ) ); |
| } |
| |
| // For DAV resources we only know the Title, for non-DAV |
| // resources we additionally know that it is a document. |
| |
| if ( rType == DAV ) |
| { |
| //xProps.reset( |
| // new ContentProperties( aUnescapedTitle ) ); |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), |
| uno::makeAny( aUnescapedTitle ), |
| true ); |
| } |
| else |
| { |
| if ( !xProps.get() ) |
| xProps.reset( new ContentProperties( aUnescapedTitle, false ) ); |
| else |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), |
| uno::makeAny( aUnescapedTitle ), |
| true ); |
| |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ), |
| uno::makeAny( false ), |
| true ); |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ), |
| uno::makeAny( true ), |
| true ); |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ), |
| uno::makeAny( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WEBDAV_CONTENT_TYPE ) ) ), |
| true ); |
| } |
| } |
| else |
| { |
| // No server access for just created (not yet committed) objects. |
| // Only a minimal set of properties supported at this stage. |
| if (m_bTransient) |
| xProps.reset( new ContentProperties( aUnescapedTitle, |
| m_bCollection ) ); |
| } |
| |
| sal_Int32 nCount = rProperties.getLength(); |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const rtl::OUString rName = rProperties[ n ].Name; |
| if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "BaseURI" ) ) ) |
| { |
| // Add BaseURI property, if requested. |
| xProps->addProperty( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ), |
| uno::makeAny( getBaseURI( xResAccess ) ), |
| true ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) |
| { |
| // Add CreatableContentsInfo property, if requested. |
| sal_Bool bFolder = sal_False; |
| xProps->getValue( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ) ) |
| >>= bFolder; |
| xProps->addProperty( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ), |
| uno::makeAny( bFolder |
| ? queryCreatableContentsInfo() |
| : uno::Sequence< ucb::ContentInfo >() ), |
| true ); |
| } |
| } |
| |
| uno::Reference< sdbc::XRow > xResultRow |
| = getPropertyValues( xSMgr, |
| rProperties, |
| *xProps, |
| xProvider, |
| xIdentifier->getContentIdentifier() ); |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| if ( !m_xCachedProps.get() ) |
| m_xCachedProps.reset( new CachableContentProperties( *xProps.get() ) ); |
| else |
| m_xCachedProps->addProperties( *xProps.get() ); |
| |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| m_aEscapedTitle = SerfUri::escapeSegment( aUnescapedTitle ); |
| } |
| |
| return xResultRow; |
| } |
| |
| //========================================================================= |
| uno::Sequence< uno::Any > Content::setPropertyValues( |
| const uno::Sequence< beans::PropertyValue >& rValues, |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw ( uno::Exception ) |
| { |
| uno::Reference< lang::XMultiServiceFactory > xSMgr; |
| uno::Reference< ucb::XContentIdentifier > xIdentifier; |
| rtl::Reference< ContentProvider > xProvider; |
| sal_Bool bTransient; |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| xProvider.set( m_pProvider ); |
| xIdentifier.set( m_xIdentifier ); |
| bTransient = m_bTransient; |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| xSMgr.set( m_xSMgr ); |
| } |
| |
| uno::Sequence< uno::Any > aRet( rValues.getLength() ); |
| uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() ); |
| sal_Int32 nChanged = 0; |
| |
| beans::PropertyChangeEvent aEvent; |
| aEvent.Source = static_cast< cppu::OWeakObject * >( this ); |
| aEvent.Further = sal_False; |
| // aEvent.PropertyName = |
| aEvent.PropertyHandle = -1; |
| // aEvent.OldValue = |
| // aEvent.NewValue = |
| |
| std::vector< ProppatchValue > aProppatchValues; |
| std::vector< sal_Int32 > aProppatchPropsPositions; |
| |
| uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet; |
| sal_Bool bTriedToGetAdditonalPropSet = sal_False; |
| |
| sal_Bool bExchange = sal_False; |
| rtl::OUString aNewTitle; |
| rtl::OUString aOldTitle; |
| sal_Int32 nTitlePos = -1; |
| |
| uno::Reference< beans::XPropertySetInfo > xInfo; |
| |
| const beans::PropertyValue* pValues = rValues.getConstArray(); |
| sal_Int32 nCount = rValues.getLength(); |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const beans::PropertyValue& rValue = pValues[ n ]; |
| const rtl::OUString & rName = rValue.Name; |
| |
| beans::Property aTmpProp; |
| xProvider->getProperty( rName, aTmpProp ); |
| |
| if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| continue; |
| } |
| |
| ////////////////////////////////////////////////////////////////// |
| // Mandatory props. |
| ////////////////////////////////////////////////////////////////// |
| |
| if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) |
| { |
| rtl::OUString aNewValue; |
| if ( rValue.Value >>= aNewValue ) |
| { |
| // No empty titles! |
| if ( aNewValue.getLength() > 0 ) |
| { |
| try |
| { |
| SerfUri aURI( xIdentifier->getContentIdentifier() ); |
| aOldTitle = aURI.GetPathBaseNameUnescaped(); |
| |
| if ( aNewValue != aOldTitle ) |
| { |
| // modified title -> modified URL -> exchange ! |
| if ( !bTransient ) |
| bExchange = sal_True; |
| |
| // new value will be set later... |
| aNewTitle = aNewValue; |
| |
| // remember position within sequence of values (for |
| // error handling). |
| nTitlePos = n; |
| } |
| } |
| catch ( DAVException const & ) |
| { |
| aRet[ n ] <<= lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Invalid content identifier!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ); |
| } |
| } |
| else |
| { |
| aRet[ n ] <<= lang::IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Empty title not allowed!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ); |
| } |
| } |
| else |
| { |
| aRet[ n ] <<= beans::IllegalTypeException( |
| rtl::OUString::createFromAscii( |
| "Property value has wrong type!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| } |
| else |
| { |
| ////////////////////////////////////////////////////////////// |
| // Optional props. |
| ////////////////////////////////////////////////////////////// |
| |
| rtl::OUString aSpecialName; |
| bool bIsSpecial = DAVProperties::isUCBSpecialProperty( rName, aSpecialName ); |
| |
| if ( !xInfo.is() ) |
| xInfo = getPropertySetInfo( xEnv, |
| sal_False /* don't cache data */ ); |
| |
| if ( !xInfo->hasPropertyByName( bIsSpecial ? aSpecialName : rName ) ) |
| { |
| // Check, whether property exists. Skip otherwise. |
| // PROPPATCH::set would add the property automatically, which |
| // is not allowed for "setPropertyValues" command! |
| aRet[ n ] <<= beans::UnknownPropertyException( |
| rtl::OUString::createFromAscii( |
| "Property is unknown!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| continue; |
| } |
| |
| if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) |
| { |
| // Read-only property! |
| // (but could be writable, if 'getcontenttype' would be) |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| if ( rName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) |
| { |
| // Read-only property! |
| aRet[ n ] <<= lang::IllegalAccessException( |
| rtl::OUString::createFromAscii( |
| "Property is read-only!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| else |
| { |
| if ( getResourceType( xEnv, xResAccess ) == DAV ) |
| { |
| // Property value will be set on server. |
| ProppatchValue aValue( PROPSET, rName, rValue.Value ); |
| aProppatchValues.push_back( aValue ); |
| |
| // remember position within sequence of values (for |
| // error handling). |
| aProppatchPropsPositions.push_back( n ); |
| } |
| else |
| { |
| // Property value will be stored in local property store. |
| if ( !bTriedToGetAdditonalPropSet && |
| !xAdditionalPropSet.is() ) |
| { |
| xAdditionalPropSet |
| = getAdditionalPropertySet( sal_False ); |
| bTriedToGetAdditonalPropSet = sal_True; |
| } |
| |
| if ( xAdditionalPropSet.is() ) |
| { |
| try |
| { |
| uno::Any aOldValue |
| = xAdditionalPropSet->getPropertyValue( rName ); |
| if ( aOldValue != rValue.Value ) |
| { |
| xAdditionalPropSet->setPropertyValue( |
| rName, rValue.Value ); |
| |
| aEvent.PropertyName = rName; |
| aEvent.OldValue = aOldValue; |
| aEvent.NewValue = rValue.Value; |
| |
| aChanges.getArray()[ nChanged ] = aEvent; |
| nChanged++; |
| } |
| } |
| catch ( beans::UnknownPropertyException const & e ) |
| { |
| aRet[ n ] <<= e; |
| } |
| catch ( lang::WrappedTargetException const & e ) |
| { |
| aRet[ n ] <<= e; |
| } |
| catch ( beans::PropertyVetoException const & e ) |
| { |
| aRet[ n ] <<= e; |
| } |
| catch ( lang::IllegalArgumentException const & e ) |
| { |
| aRet[ n ] <<= e; |
| } |
| } |
| else |
| { |
| aRet[ n ] <<= uno::Exception( |
| rtl::OUString::createFromAscii( |
| "No property set for storing the value!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| } |
| } |
| } |
| } // for |
| |
| if ( !bTransient && aProppatchValues.size() ) |
| { |
| try |
| { |
| // Set property values at server. |
| xResAccess->PROPPATCH( aProppatchValues, xEnv ); |
| |
| std::vector< ProppatchValue >::const_iterator it |
| = aProppatchValues.begin(); |
| std::vector< ProppatchValue >::const_iterator end |
| = aProppatchValues.end(); |
| |
| while ( it != end ) |
| { |
| aEvent.PropertyName = (*it).name; |
| aEvent.OldValue = uno::Any(); // @@@ to expensive to obtain! |
| aEvent.NewValue = (*it).value; |
| |
| aChanges.getArray()[ nChanged ] = aEvent; |
| nChanged++; |
| |
| ++it; |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| // OSL_ENSURE( sal_False, |
| // "Content::setPropertyValues - PROPPATCH failed!" ); |
| |
| #if 1 |
| cancelCommandExecution( e, xEnv ); |
| // unreachable |
| #else |
| // Note: PROPPATCH either sets ALL property values OR NOTHING. |
| |
| std::vector< sal_Int32 >::const_iterator it |
| = aProppatchPropsPositions.begin(); |
| std::vector< sal_Int32 >::const_iterator end |
| = aProppatchPropsPositions.end(); |
| |
| while ( it != end ) |
| { |
| // Set error. |
| aRet[ (*it) ] <<= MapDAVException( e, sal_True ); |
| ++it; |
| } |
| #endif |
| } |
| } |
| |
| if ( bExchange ) |
| { |
| // Assemble new content identifier... |
| |
| rtl::OUString aNewURL = getParentURL(); |
| if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) ) |
| aNewURL += rtl::OUString::createFromAscii( "/" ); |
| |
| aNewURL += SerfUri::escapeSegment( aNewTitle ); |
| |
| uno::Reference< ucb::XContentIdentifier > xNewId |
| = new ::ucbhelper::ContentIdentifier( xSMgr, aNewURL ); |
| uno::Reference< ucb::XContentIdentifier > xOldId = xIdentifier; |
| |
| try |
| { |
| SerfUri sourceURI( xOldId->getContentIdentifier() ); |
| SerfUri targetURI( xNewId->getContentIdentifier() ); |
| targetURI.SetScheme( sourceURI.GetScheme() ); |
| |
| xResAccess->MOVE( |
| sourceURI.GetPath(), targetURI.GetURI(), sal_False, xEnv ); |
| // @@@ Should check for resources that could not be moved |
| // (due to source access or target overwrite) and send |
| // this information through the interaction handler. |
| |
| // @@@ Existing content should be checked to see if it needs |
| // to be deleted at the source |
| |
| // @@@ Existing content should be checked to see if it has |
| // been overwritten at the target |
| |
| if ( exchangeIdentity( xNewId ) ) |
| { |
| xResAccess->setURL( aNewURL ); |
| |
| // DAV resources store all additional props on server! |
| // // Adapt Additional Core Properties. |
| // renameAdditionalPropertySet( xOldId->getContentIdentifier(), |
| // xNewId->getContentIdentifier(), |
| // sal_True ); |
| } |
| else |
| { |
| // Do not set new title! |
| aNewTitle = rtl::OUString(); |
| |
| // Set error . |
| aRet[ nTitlePos ] <<= uno::Exception( |
| rtl::OUString::createFromAscii( "Exchange failed!" ), |
| static_cast< cppu::OWeakObject * >( this ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| // Do not set new title! |
| aNewTitle = rtl::OUString(); |
| |
| // Set error . |
| aRet[ nTitlePos ] <<= MapDAVException( e, sal_True ); |
| } |
| } |
| |
| if ( aNewTitle.getLength() ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" ); |
| aEvent.OldValue = uno::makeAny( aOldTitle ); |
| aEvent.NewValue = uno::makeAny( aNewTitle ); |
| |
| m_aEscapedTitle = SerfUri::escapeSegment( aNewTitle ); |
| |
| aChanges.getArray()[ nChanged ] = aEvent; |
| nChanged++; |
| } |
| |
| if ( nChanged > 0 ) |
| { |
| aChanges.realloc( nChanged ); |
| notifyPropertiesChange( aChanges ); |
| } |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| return aRet; |
| } |
| |
| //========================================================================= |
| uno::Any Content::open( |
| const ucb::OpenCommandArgument2 & rArg, |
| const uno::Reference< ucb::XCommandEnvironment > & xEnv ) |
| throw( uno::Exception ) |
| { |
| uno::Any aRet; |
| |
| sal_Bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) || |
| ( rArg.Mode == ucb::OpenMode::FOLDERS ) || |
| ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) ); |
| if ( bOpenFolder ) |
| { |
| if ( isFolder( xEnv ) ) |
| { |
| // Open collection. |
| |
| uno::Reference< ucb::XDynamicResultSet > xSet |
| = new DynamicResultSet( m_xSMgr, this, rArg, xEnv ); |
| aRet <<= xSet; |
| } |
| else |
| { |
| // Error: Not a folder! |
| |
| rtl::OUStringBuffer aMsg; |
| aMsg.appendAscii( "Non-folder resource cannot be " |
| "opened as folder! Wrong Open Mode!" ); |
| |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| lang::IllegalArgumentException( |
| aMsg.makeStringAndClear(), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| xEnv ); |
| // Unreachable |
| } |
| } |
| |
| if ( rArg.Sink.is() ) |
| { |
| // Open document. |
| |
| if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || |
| ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) |
| { |
| // Currently(?) unsupported. |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::UnsupportedOpenModeException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| sal_Int16( rArg.Mode ) ) ), |
| xEnv ); |
| // Unreachable |
| } |
| |
| rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); |
| uno::Reference< io::XOutputStream > xOut |
| = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY ); |
| if ( xOut.is() ) |
| { |
| // PUSH: write data |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| xResAccess.reset( |
| new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| DAVResource aResource; |
| std::vector< rtl::OUString > aHeaders; |
| |
| xResAccess->GET( xOut, aHeaders, aResource, xEnv ); |
| m_bDidGetOrHead = true; |
| |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| // cache headers. |
| if ( !m_xCachedProps.get()) |
| m_xCachedProps.reset( |
| new CachableContentProperties( aResource ) ); |
| else |
| m_xCachedProps->addProperties( aResource ); |
| |
| m_xResAccess.reset( |
| new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, xEnv ); |
| // Unreachable |
| } |
| } |
| else |
| { |
| uno::Reference< io::XActiveDataSink > xDataSink |
| = uno::Reference< io::XActiveDataSink >( rArg.Sink, |
| uno::UNO_QUERY ); |
| if ( xDataSink.is() ) |
| { |
| // PULL: wait for client read |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| xResAccess.reset( |
| new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| // fill inputsream sync; return if all data present |
| DAVResource aResource; |
| std::vector< rtl::OUString > aHeaders; |
| |
| uno::Reference< io::XInputStream > xIn |
| = xResAccess->GET( aHeaders, aResource, xEnv ); |
| m_bDidGetOrHead = true; |
| |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| // cache headers. |
| if ( !m_xCachedProps.get()) |
| m_xCachedProps.reset( |
| new CachableContentProperties( aResource ) ); |
| else |
| m_xCachedProps->addProperties( |
| aResource.properties ); |
| |
| m_xResAccess.reset( |
| new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| xDataSink->setInputStream( xIn ); |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, xEnv ); |
| // Unreachable |
| } |
| } |
| else |
| { |
| // Note: aOpenCommand.Sink may contain an XStream |
| // implementation. Support for this type of |
| // sink is optional... |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::UnsupportedDataSinkException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| rArg.Sink ) ), |
| xEnv ); |
| // Unreachable |
| } |
| } |
| } |
| |
| return aRet; |
| } |
| |
| //========================================================================= |
| void Content::post( |
| const ucb::PostCommandArgument2 & rArg, |
| const uno::Reference< ucb::XCommandEnvironment > & xEnv ) |
| throw( uno::Exception ) |
| { |
| uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY ); |
| if ( xSink.is() ) |
| { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| xResAccess.reset( |
| new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| uno::Reference< io::XInputStream > xResult |
| = xResAccess->POST( rArg.MediaType, |
| rArg.Referer, |
| rArg.Source, |
| xEnv ); |
| |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| m_xResAccess.reset( |
| new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| xSink->setInputStream( xResult ); |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, xEnv, sal_True ); |
| // Unreachable |
| } |
| } |
| else |
| { |
| uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY ); |
| if ( xResult.is() ) |
| { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| xResAccess.reset( |
| new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| xResAccess->POST( rArg.MediaType, |
| rArg.Referer, |
| rArg.Source, |
| xResult, |
| xEnv ); |
| |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| m_xResAccess.reset( |
| new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, xEnv, sal_True ); |
| // Unreachable |
| } |
| } |
| else |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::UnsupportedDataSinkException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| rArg.Sink ) ), |
| xEnv ); |
| // Unreachable |
| } |
| } |
| } |
| |
| //========================================================================= |
| void Content::queryChildren( ContentRefList& rChildren ) |
| { |
| // Obtain a list with a snapshot of all currently instanciated contents |
| // from provider and extract the contents which are direct children |
| // of this content. |
| |
| ::ucbhelper::ContentRefList aAllContents; |
| m_xProvider->queryExistingContents( aAllContents ); |
| |
| rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); |
| sal_Int32 nURLPos = aURL.lastIndexOf( '/' ); |
| |
| if ( nURLPos != ( aURL.getLength() - 1 ) ) |
| { |
| // No trailing slash found. Append. |
| aURL += rtl::OUString::createFromAscii( "/" ); |
| } |
| |
| sal_Int32 nLen = aURL.getLength(); |
| |
| ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin(); |
| ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end(); |
| |
| while ( it != end ) |
| { |
| ::ucbhelper::ContentImplHelperRef xChild = (*it); |
| rtl::OUString aChildURL |
| = xChild->getIdentifier()->getContentIdentifier(); |
| |
| // Is aURL a prefix of aChildURL? |
| if ( ( aChildURL.getLength() > nLen ) && |
| ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) |
| { |
| sal_Int32 nPos = nLen; |
| nPos = aChildURL.indexOf( '/', nPos ); |
| |
| if ( ( nPos == -1 ) || |
| ( nPos == ( aChildURL.getLength() - 1 ) ) ) |
| { |
| // No further slashes / only a final slash. It's a child! |
| rChildren.push_back( |
| ::http_dav_ucp::Content::ContentRef( |
| static_cast< ::http_dav_ucp::Content * >( |
| xChild.get() ) ) ); |
| } |
| } |
| ++it; |
| } |
| } |
| |
| //========================================================================= |
| void Content::insert( |
| const uno::Reference< io::XInputStream > & xInputStream, |
| sal_Bool bReplaceExisting, |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception ) |
| { |
| sal_Bool bTransient, bCollection; |
| rtl::OUString aEscapedTitle; |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| bTransient = m_bTransient; |
| bCollection = m_bCollection; |
| aEscapedTitle = m_aEscapedTitle; |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| // Check, if all required properties are present. |
| |
| if ( aEscapedTitle.getLength() == 0 ) |
| { |
| OSL_ENSURE( sal_False, "Content::insert - Title missing!" ); |
| |
| uno::Sequence< rtl::OUString > aProps( 1 ); |
| aProps[ 0 ] = rtl::OUString::createFromAscii( "Title" ); |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( ucb::MissingPropertiesException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| aProps ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| if ( !bReplaceExisting ) |
| { |
| /* [RFC 2616] - HTTP |
| |
| The PUT method requests that the enclosed entity be stored under the |
| supplied Request-URI. If the Request-URI refers to an already |
| existing resource, the enclosed entity SHOULD be considered as a |
| modified version of the one residing on the origin server. |
| */ |
| |
| /* [RFC 2518] - WebDAV |
| |
| MKCOL creates a new collection resource at the location specified by |
| the Request-URI. If the resource identified by the Request-URI is |
| non-null then the MKCOL MUST fail. |
| */ |
| |
| // ==> Complain on PUT, continue on MKCOL. |
| if ( !bTransient || ( bTransient && !bCollection ) ) |
| { |
| #undef ERROR |
| ucb::UnsupportedNameClashException aEx( |
| rtl::OUString::createFromAscii( "Unable to write without overwrite!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| ucb::NameClash::ERROR ); |
| |
| uno::Reference< task::XInteractionHandler > xIH; |
| |
| if ( Environment.is() ) |
| xIH = Environment->getInteractionHandler(); |
| |
| if ( xIH.is() ) |
| { |
| uno::Any aExAsAny( uno::makeAny( aEx ) ); |
| |
| rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest |
| = new ucbhelper::SimpleInteractionRequest( |
| aExAsAny, |
| ucbhelper::CONTINUATION_APPROVE |
| | ucbhelper::CONTINUATION_DISAPPROVE ); |
| xIH->handle( xRequest.get() ); |
| |
| const sal_Int32 nResp = xRequest->getResponse(); |
| |
| switch ( nResp ) |
| { |
| case ucbhelper::CONTINUATION_UNKNOWN: |
| // Not handled; throw. |
| throw aEx; |
| // break; |
| |
| case ucbhelper::CONTINUATION_APPROVE: |
| // Continue -> Overwrite. |
| bReplaceExisting = sal_True; |
| break; |
| |
| case ucbhelper::CONTINUATION_DISAPPROVE: |
| // Abort. |
| throw ucb::CommandFailedException( |
| rtl::OUString(), |
| uno::Reference< uno::XInterface >(), |
| aExAsAny ); |
| // break; |
| |
| default: |
| OSL_ENSURE( sal_False, |
| "Content::insert - " |
| "Unknown interaction selection!" ); |
| throw ucb::CommandFailedException( |
| rtl::OUString::createFromAscii( |
| "Unknown interaction selection!" ), |
| uno::Reference< uno::XInterface >(), |
| aExAsAny ); |
| // break; |
| } |
| } |
| else |
| { |
| // No IH; throw. |
| throw aEx; |
| } |
| } |
| } |
| |
| if ( bTransient ) |
| { |
| // Assemble new content identifier... |
| rtl::OUString aURL = getParentURL(); |
| if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) ) |
| aURL += rtl::OUString::createFromAscii( "/" ); |
| |
| aURL += aEscapedTitle; |
| |
| try |
| { |
| xResAccess->setURL( aURL ); |
| |
| if ( bCollection ) |
| xResAccess->MKCOL( Environment ); |
| else |
| xResAccess->PUT( xInputStream, Environment ); |
| } |
| catch ( DAVException const & except ) |
| { |
| if ( bCollection ) |
| { |
| if ( except.getStatus() == SC_METHOD_NOT_ALLOWED ) |
| { |
| // [RFC 2518] - WebDAV |
| // 405 (Method Not Allowed) - MKCOL can only be |
| // executed on a deleted/non-existent resource. |
| |
| if ( bReplaceExisting ) |
| { |
| // Destroy old resource. |
| try |
| { |
| xResAccess->DESTROY( Environment ); |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, Environment, sal_True ); |
| // Unreachable |
| } |
| |
| // Insert (recursion!). |
| insert( xInputStream, bReplaceExisting, Environment ); |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( |
| new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| |
| // Success! |
| return; |
| } |
| else |
| { |
| rtl::OUString aTitle; |
| try |
| { |
| SerfUri aURI( aURL ); |
| aTitle = aURI.GetPathBaseNameUnescaped(); |
| } |
| catch ( DAVException const & ) |
| { |
| } |
| |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::NameClashException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aTitle ) ), |
| Environment ); |
| // Unreachable |
| } |
| } |
| } |
| |
| cancelCommandExecution( except, Environment, sal_True ); |
| // Unreachable |
| } |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xIdentifier |
| = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ); |
| } |
| |
| inserted(); |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_bTransient = sal_False; |
| } |
| } |
| else |
| { |
| if ( !xInputStream.is() ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::MissingInputStreamException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ) ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| try |
| { |
| xResAccess->PUT( xInputStream, Environment ); |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, Environment, sal_True ); |
| // Unreachable |
| } |
| } |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| |
| //========================================================================= |
| void Content::transfer( |
| const ucb::TransferInfo & rArgs, |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception ) |
| { |
| uno::Reference< lang::XMultiServiceFactory > xSMgr; |
| uno::Reference< ucb::XContentIdentifier > xIdentifier; |
| uno::Reference< ucb::XContentProvider > xProvider; |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| xSMgr.set( m_xSMgr ); |
| xIdentifier.set( m_xIdentifier ); |
| xProvider.set( m_xProvider.get() ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| rtl::OUString aTargetURI; |
| try |
| { |
| SerfUri sourceURI( rArgs.SourceURL ); |
| SerfUri targetURI( xIdentifier->getContentIdentifier() ); |
| aTargetURI = targetURI.GetPathBaseNameUnescaped(); |
| |
| // Check source's and target's URL scheme |
| // |
| const rtl::OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase(); |
| if ( aScheme.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) |
| { |
| sourceURI.SetScheme( |
| rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); |
| } |
| else if ( aScheme.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) |
| { |
| sourceURI.SetScheme( |
| rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); |
| } |
| else if ( aScheme.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ) |
| { |
| sourceURI.SetScheme( |
| rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) ); |
| } |
| else |
| { |
| if ( !aScheme.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) && |
| !aScheme.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::InteractiveBadTransferURLException( |
| rtl::OUString::createFromAscii( |
| "Unsupported URL scheme!" ), |
| static_cast< cppu::OWeakObject * >( this ) ) ), |
| Environment ); |
| // Unreachable |
| } |
| } |
| |
| if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) |
| targetURI.SetScheme( |
| rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); |
| else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) |
| targetURI.SetScheme( |
| rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) ); |
| |
| // @@@ This implementation of 'transfer' only works |
| // if the source and target are located at same host. |
| // (Neon does not support cross-server copy/move) |
| |
| // Check for same host |
| // |
| if ( sourceURI.GetHost().getLength() && |
| ( sourceURI.GetHost() != targetURI.GetHost() ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( ucb::InteractiveBadTransferURLException( |
| rtl::OUString::createFromAscii( |
| "Different hosts!" ), |
| static_cast< cppu::OWeakObject * >( this ) ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| rtl::OUString aTitle = rArgs.NewTitle; |
| |
| if ( !aTitle.getLength() ) |
| aTitle = sourceURI.GetPathBaseNameUnescaped(); |
| |
| if ( aTitle.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "/" ) ) ) |
| { |
| // kso: ??? |
| aTitle = rtl::OUString(); |
| } |
| |
| targetURI.AppendPath( aTitle ); |
| |
| rtl::OUString aTargetURL = xIdentifier->getContentIdentifier(); |
| if ( ( aTargetURL.lastIndexOf( '/' ) + 1 ) |
| != aTargetURL.getLength() ) |
| aTargetURL += rtl::OUString::createFromAscii( "/" ); |
| |
| aTargetURL += aTitle; |
| |
| uno::Reference< ucb::XContentIdentifier > xTargetId |
| = new ::ucbhelper::ContentIdentifier( xSMgr, aTargetURL ); |
| |
| DAVResourceAccess aSourceAccess( xSMgr, |
| xResAccess->getSessionFactory(), |
| sourceURI.GetURI() ); |
| |
| if ( rArgs.MoveData == sal_True ) |
| { |
| uno::Reference< ucb::XContentIdentifier > xId |
| = new ::ucbhelper::ContentIdentifier( xSMgr, rArgs.SourceURL ); |
| |
| // Note: The static cast is okay here, because its sure that |
| // xProvider is always the WebDAVContentProvider. |
| rtl::Reference< Content > xSource |
| = static_cast< Content * >( |
| xProvider->queryContent( xId ).get() ); |
| |
| // [RFC 2518] - WebDAV |
| // If a resource exists at the destination and the Overwrite |
| // header is "T" then prior to performing the move the server |
| // MUST perform a DELETE with "Depth: infinity" on the |
| // destination resource. If the Overwrite header is set to |
| // "F" then the operation will fail. |
| |
| aSourceAccess.MOVE( sourceURI.GetPath(), |
| targetURI.GetURI(), |
| rArgs.NameClash |
| == ucb::NameClash::OVERWRITE, |
| Environment ); |
| |
| if ( xSource.is() ) |
| { |
| // Propagate destruction to listeners. |
| xSource->destroy( sal_True ); |
| } |
| |
| // DAV resources store all additional props on server! |
| // // Rename own and all children's Additional Core Properties. |
| // renameAdditionalPropertySet( xId->getContentIdentifier(), |
| // xTargetId->getContentIdentifier(), |
| // sal_True ); |
| } |
| else |
| { |
| // [RFC 2518] - WebDAV |
| // If a resource exists at the destination and the Overwrite |
| // header is "T" then prior to performing the copy the server |
| // MUST perform a DELETE with "Depth: infinity" on the |
| // destination resource. If the Overwrite header is set to |
| // "F" then the operation will fail. |
| |
| aSourceAccess.COPY( sourceURI.GetPath(), |
| targetURI.GetURI(), |
| rArgs.NameClash |
| == ucb::NameClash::OVERWRITE, |
| Environment ); |
| |
| // DAV resources store all additional props on server! |
| // // Copy own and all children's Additional Core Properties. |
| // copyAdditionalPropertySet( xId->getContentIdentifier(), |
| // xTargetId->getContentIdentifier(), |
| // sal_True ); |
| } |
| |
| // Note: The static cast is okay here, because its sure that |
| // xProvider is always the WebDAVContentProvider. |
| rtl::Reference< Content > xTarget |
| = static_cast< Content * >( |
| xProvider->queryContent( xTargetId ).get() ); |
| |
| // Announce transfered content in its new folder. |
| xTarget->inserted(); |
| } |
| catch ( ucb::IllegalIdentifierException const & ) |
| { |
| // queryContent |
| } |
| catch ( DAVException const & e ) |
| { |
| // [RFC 2518] - WebDAV |
| // 412 (Precondition Failed) - The server was unable to maintain |
| // the liveness of the properties listed in the propertybehavior |
| // XML element or the Overwrite header is "F" and the state of |
| // the destination resource is non-null. |
| |
| if ( e.getStatus() == SC_PRECONDITION_FAILED ) |
| { |
| switch ( rArgs.NameClash ) |
| { |
| case 0/*ucb::NameClash::ERROR*/: |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::NameClashException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aTargetURI ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| case ucb::NameClash::OVERWRITE: |
| break; |
| |
| case ucb::NameClash::KEEP: // deprecated |
| case ucb::NameClash::RENAME: |
| case ucb::NameClash::ASK: |
| default: |
| { |
| ucbhelper::cancelCommandExecution( |
| uno::makeAny( |
| ucb::UnsupportedNameClashException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| rArgs.NameClash ) ), |
| Environment ); |
| // Unreachable |
| } |
| } |
| } |
| |
| cancelCommandExecution( e, Environment, sal_True ); |
| // Unreachable |
| } |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| |
| //========================================================================= |
| void Content::destroy( sal_Bool bDeletePhysical ) |
| throw( uno::Exception ) |
| { |
| // @@@ take care about bDeletePhysical -> trashcan support |
| rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); |
| |
| uno::Reference< ucb::XContent > xThis = this; |
| |
| deleted(); |
| |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| // Process instanciated children... |
| |
| ::http_dav_ucp::Content::ContentRefList aChildren; |
| queryChildren( aChildren ); |
| |
| ContentRefList::const_iterator it = aChildren.begin(); |
| ContentRefList::const_iterator end = aChildren.end(); |
| |
| while ( it != end ) |
| { |
| (*it)->destroy( bDeletePhysical ); |
| ++it; |
| } |
| } |
| |
| //========================================================================= |
| bool Content::supportsExclusiveWriteLock( |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| { |
| if ( getResourceType( Environment ) == DAV ) |
| { |
| if ( m_xCachedProps.get() ) |
| { |
| uno::Sequence< ucb::LockEntry > aSupportedLocks; |
| if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK ) |
| >>= aSupportedLocks ) |
| { |
| for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n ) |
| { |
| if ( aSupportedLocks[ n ].Scope |
| == ucb::LockScope_EXCLUSIVE && |
| aSupportedLocks[ n ].Type |
| == ucb::LockType_WRITE ) |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| //========================================================================= |
| void Content::lock( |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception ) |
| { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| uno::Any aOwnerAny; |
| aOwnerAny |
| <<= rtl::OUString::createFromAscii( "http://ucb.openoffice.org" ); |
| |
| ucb::Lock aLock( |
| ucb::LockScope_EXCLUSIVE, |
| ucb::LockType_WRITE, |
| ucb::LockDepth_ZERO, |
| aOwnerAny, |
| 180, // lock timeout in secs |
| //-1, // infinite lock |
| uno::Sequence< ::rtl::OUString >() ); |
| |
| xResAccess->LOCK( aLock, Environment ); |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, Environment, sal_False ); |
| // Unreachable |
| } |
| } |
| |
| //========================================================================= |
| void Content::unlock( |
| const uno::Reference< ucb::XCommandEnvironment >& Environment ) |
| throw( uno::Exception ) |
| { |
| try |
| { |
| std::auto_ptr< DAVResourceAccess > xResAccess; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); |
| } |
| |
| xResAccess->UNLOCK( Environment ); |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); |
| } |
| } |
| catch ( DAVException const & e ) |
| { |
| cancelCommandExecution( e, Environment, sal_False ); |
| // Unreachable |
| } |
| } |
| |
| //========================================================================= |
| sal_Bool Content::exchangeIdentity( |
| const uno::Reference< ucb::XContentIdentifier >& xNewId ) |
| { |
| if ( !xNewId.is() ) |
| return sal_False; |
| |
| osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); |
| |
| uno::Reference< ucb::XContent > xThis = this; |
| |
| // Already persistent? |
| if ( m_bTransient ) |
| { |
| OSL_ENSURE( sal_False, "Content::exchangeIdentity - Not persistent!" ); |
| return sal_False; |
| } |
| |
| // Exchange own identitity. |
| |
| // Fail, if a content with given id already exists. |
| // if ( !hasData( xNewId ) ) |
| { |
| rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier(); |
| |
| aGuard.clear(); |
| if ( exchange( xNewId ) ) |
| { |
| // Process instanciated children... |
| |
| ContentRefList aChildren; |
| queryChildren( aChildren ); |
| |
| ContentRefList::const_iterator it = aChildren.begin(); |
| ContentRefList::const_iterator end = aChildren.end(); |
| |
| while ( it != end ) |
| { |
| ContentRef xChild = (*it); |
| |
| // Create new content identifier for the child... |
| uno::Reference< ucb::XContentIdentifier > |
| xOldChildId = xChild->getIdentifier(); |
| rtl::OUString aOldChildURL |
| = xOldChildId->getContentIdentifier(); |
| rtl::OUString aNewChildURL |
| = aOldChildURL.replaceAt( |
| 0, |
| aOldURL.getLength(), |
| xNewId->getContentIdentifier() ); |
| uno::Reference< ucb::XContentIdentifier > xNewChildId |
| = new ::ucbhelper::ContentIdentifier( |
| m_xSMgr, aNewChildURL ); |
| |
| if ( !xChild->exchangeIdentity( xNewChildId ) ) |
| return sal_False; |
| |
| ++it; |
| } |
| return sal_True; |
| } |
| } |
| |
| OSL_ENSURE( sal_False, |
| "Content::exchangeIdentity - " |
| "Panic! Cannot exchange identity!" ); |
| return sal_False; |
| } |
| |
| //========================================================================= |
| sal_Bool Content::isFolder( |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw( uno::Exception ) |
| { |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| if ( m_bTransient ) |
| return m_bCollection; |
| } |
| |
| uno::Sequence< beans::Property > aProperties( 1 ); |
| aProperties[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); |
| aProperties[ 0 ].Handle = -1; |
| uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) ); |
| if ( xRow.is() ) |
| { |
| try |
| { |
| return xRow->getBoolean( 1 ); |
| } |
| catch ( sdbc::SQLException const & ) |
| { |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| //========================================================================= |
| uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) |
| { |
| // Map DAVException... |
| uno::Any aException; |
| |
| rtl::OUString aURL; |
| if ( m_bTransient ) |
| { |
| aURL = getParentURL(); |
| if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) ) |
| aURL += rtl::OUString::createFromAscii( "/" ); |
| |
| aURL += m_aEscapedTitle; |
| } |
| else |
| { |
| aURL = m_xIdentifier->getContentIdentifier(); |
| } |
| |
| switch ( e.getStatus() ) |
| { |
| case SC_NOT_FOUND: |
| { |
| uno::Sequence< uno::Any > aArgs( 1 ); |
| aArgs[ 0 ] <<= beans::PropertyValue( |
| rtl::OUString::createFromAscii("Uri"), -1, |
| uno::makeAny(aURL), |
| beans::PropertyState_DIRECT_VALUE); |
| |
| aException <<= |
| ucb::InteractiveAugmentedIOException( |
| rtl::OUString::createFromAscii( "Not found!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| ucb::IOErrorCode_NOT_EXISTING, |
| aArgs ); |
| return aException; |
| } |
| default: |
| break; |
| } |
| |
| switch ( e.getError() ) |
| { |
| case DAVException::DAV_HTTP_ERROR: |
| { |
| if ( bWrite ) |
| aException <<= |
| ucb::InteractiveNetworkWriteException( |
| e.getData(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| e.getData() ); |
| else |
| aException <<= |
| ucb::InteractiveNetworkReadException( |
| e.getData(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| e.getData() ); |
| break; |
| } |
| |
| case DAVException::DAV_HTTP_LOOKUP: |
| aException <<= |
| ucb::InteractiveNetworkResolveNameException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| e.getData() ); |
| break; |
| |
| // @@@ No matching InteractiveNetwork*Exception |
| // case DAVException::DAV_HTTP_AUTH: |
| // break; |
| |
| // @@@ No matching InteractiveNetwork*Exception |
| // case DAVException::DAV_HTTP_AUTHPROXY: |
| // break; |
| |
| case DAVException::DAV_HTTP_CONNECT: |
| aException <<= |
| ucb::InteractiveNetworkConnectException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| e.getData() ); |
| break; |
| |
| // @@@ No matching InteractiveNetwork*Exception |
| // case DAVException::DAV_HTTP_TIMEOUT: |
| // break; |
| |
| // @@@ No matching InteractiveNetwork*Exception |
| // case DAVException::DAV_HTTP_REDIRECT: |
| // break; |
| |
| // @@@ No matching InteractiveNetwork*Exception |
| // case DAVException::DAV_SESSION_CREATE: |
| // break; |
| |
| case DAVException::DAV_INVALID_ARG: |
| aException <<= |
| lang::IllegalArgumentException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ); |
| break; |
| |
| case DAVException::DAV_LOCKED: |
| #if 1 |
| aException <<= |
| ucb::InteractiveLockingLockedException( |
| rtl::OUString::createFromAscii( "Locked!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aURL, |
| sal_False ); // not SelfOwned |
| #else |
| { |
| uno::Sequence< uno::Any > aArgs( 1 ); |
| aArgs[ 0 ] <<= beans::PropertyValue( |
| rtl::OUString::createFromAscii("Uri"), -1, |
| uno::makeAny(aURL), |
| beans::PropertyState_DIRECT_VALUE); |
| |
| aException <<= |
| ucb::InteractiveAugmentedIOException( |
| rtl::OUString::createFromAscii( "Locked!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| ucb::IOErrorCode_LOCKING_VIOLATION, |
| aArgs ); |
| } |
| #endif |
| break; |
| |
| case DAVException::DAV_LOCKED_SELF: |
| aException <<= |
| ucb::InteractiveLockingLockedException( |
| rtl::OUString::createFromAscii( "Locked (self)!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aURL, |
| sal_True ); // SelfOwned |
| break; |
| |
| case DAVException::DAV_NOT_LOCKED: |
| aException <<= |
| ucb::InteractiveLockingNotLockedException( |
| rtl::OUString::createFromAscii( "Not locked!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aURL ); |
| break; |
| |
| case DAVException::DAV_LOCK_EXPIRED: |
| aException <<= |
| ucb::InteractiveLockingLockExpiredException( |
| rtl::OUString::createFromAscii( "Lock expired!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR, |
| aURL ); |
| break; |
| |
| default: |
| aException <<= |
| ucb::InteractiveNetworkGeneralException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ), |
| task::InteractionClassification_ERROR ); |
| break; |
| } |
| |
| return aException; |
| } |
| |
| // #i124421# force the availability of type_info symbols for exceptions |
| // that used to be passed around in uno::Any variables and thrown later |
| void ucb_dummyThrower( int i) { |
| switch( i) { |
| case 10: throw ucb::InteractiveNetworkGeneralException(); |
| case 11: throw ucb::InteractiveAugmentedIOException(); |
| case 12: throw ucb::InteractiveNetworkGeneralException(); |
| case 13: throw ucb::InteractiveNetworkWriteException(); |
| case 14: throw ucb::InteractiveNetworkReadException(); |
| case 15: throw ucb::InteractiveNetworkConnectException(); |
| case 16: throw ucb::InteractiveLockingLockedException(); |
| case 17: throw ucb::InteractiveLockingNotLockedException(); |
| case 18: throw ucb::InteractiveNetworkGeneralException(); |
| case 19: throw ucb::InteractiveLockingLockExpiredException(); |
| } |
| } |
| |
| //========================================================================= |
| // static |
| bool Content::shouldAccessNetworkAfterException( const DAVException & e ) |
| { |
| if ( ( e.getStatus() == SC_NOT_FOUND ) || |
| ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) || |
| ( e.getError() == DAVException::DAV_HTTP_CONNECT ) || |
| ( e.getError() == DAVException::DAV_HTTP_AUTH ) || |
| ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY ) ) |
| return false; |
| |
| return true; |
| } |
| |
| //========================================================================= |
| void Content::cancelCommandExecution( |
| const DAVException & e, |
| const uno::Reference< ucb::XCommandEnvironment > & xEnv, |
| sal_Bool bWrite /* = sal_False */ ) |
| throw ( uno::Exception ) |
| { |
| ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv ); |
| // Unreachable |
| } |
| |
| //========================================================================= |
| const rtl::OUString |
| Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| // First, try to obtain value of response header "Content-Location". |
| if ( m_xCachedProps.get() ) |
| { |
| rtl::OUString aLocation; |
| m_xCachedProps->getValue( rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "Content-Location" ) ) ) >>= aLocation; |
| if ( aLocation.getLength() ) |
| { |
| try |
| { |
| // Do not use m_xIdentifier->getContentIdentifier() because it |
| // for example does not reflect redirects applied to requests |
| // done using the original URI but m_xResAccess' URI does. |
| return rtl::Uri::convertRelToAbs( rResAccess->getURL(), |
| aLocation ); |
| } |
| catch ( rtl::MalformedUriException const & ) |
| { |
| } |
| } |
| } |
| |
| return rtl::OUString( rResAccess->getURL() ); |
| } |
| |
| //========================================================================= |
| const Content::ResourceType & Content::getResourceType( |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv, |
| const std::auto_ptr< DAVResourceAccess > & rResAccess ) |
| throw ( uno::Exception ) |
| { |
| if ( m_eResourceType == UNKNOWN ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| ResourceType eResourceType; |
| eResourceType = m_eResourceType; |
| |
| const rtl::OUString & rURL = rResAccess->getURL(); |
| const rtl::OUString aScheme( |
| rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() ); |
| |
| try |
| { |
| // Try to fetch some frequently used property value, e.g. those |
| // used when loading documents... along with identifying whether |
| // this is a DAV resource. |
| std::vector< DAVResource > resources; |
| std::vector< rtl::OUString > aPropNames; |
| uno::Sequence< beans::Property > aProperties( 5 ); |
| aProperties[ 0 ].Name |
| = rtl::OUString::createFromAscii( "IsFolder" ); |
| aProperties[ 1 ].Name |
| = rtl::OUString::createFromAscii( "IsDocument" ); |
| aProperties[ 2 ].Name |
| = rtl::OUString::createFromAscii( "IsReadOnly" ); |
| aProperties[ 3 ].Name |
| = rtl::OUString::createFromAscii( "MediaType" ); |
| aProperties[ 4 ].Name |
| = DAVProperties::SUPPORTEDLOCK; |
| |
| ContentProperties::UCBNamesToDAVNames( |
| aProperties, aPropNames ); |
| |
| rResAccess->PROPFIND( |
| DAVZERO, aPropNames, resources, xEnv ); |
| |
| // TODO - is this really only one? |
| if ( resources.size() == 1 ) |
| { |
| m_xCachedProps.reset( |
| new CachableContentProperties( resources[ 0 ] ) ); |
| m_xCachedProps->containsAllNames( |
| aProperties, m_aFailedPropNames ); |
| } |
| |
| eResourceType = DAV; |
| } |
| catch ( DAVException const & e ) |
| { |
| rResAccess->resetUri(); |
| |
| if ( e.getStatus() == SC_METHOD_NOT_ALLOWED ) |
| { |
| // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the |
| // resource is NON_DAV |
| eResourceType = NON_DAV; |
| } |
| // cancel command execution is case that no user authentication data has been provided. |
| if ( e.getError() == DAVException::DAV_HTTP_NOAUTH ) |
| { |
| cancelCommandExecution( e, uno::Reference< ucb::XCommandEnvironment >() ); |
| } |
| } |
| m_eResourceType = eResourceType; |
| } |
| return m_eResourceType; |
| } |
| |
| //========================================================================= |
| const Content::ResourceType & Content::getResourceType( |
| const uno::Reference< ucb::XCommandEnvironment >& xEnv ) |
| throw ( uno::Exception ) |
| { |
| return getResourceType( xEnv, m_xResAccess ); |
| } |