diff options
Diffstat (limited to 'ucb/source/ucp/webdav/webdavcontent.cxx')
-rw-r--r-- | ucb/source/ucp/webdav/webdavcontent.cxx | 827 |
1 files changed, 425 insertions, 402 deletions
diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx index afe2f2d3a7a8..def33876eb43 100644 --- a/ucb/source/ucp/webdav/webdavcontent.cxx +++ b/ucb/source/ucp/webdav/webdavcontent.cxx @@ -36,13 +36,16 @@ ************************************************************************** *************************************************************************/ -#include <osl/diagnose.h> +#include <osl/diagnose.h> #include "osl/doublecheckedlocking.h" #include <rtl/uri.hxx> #include <rtl/ustrbuf.hxx> -#include "com/sun/star/task/XPasswordContainer.hpp" -#include "com/sun/star/task/NoMasterException.hpp" +#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> @@ -50,39 +53,37 @@ #include <com/sun/star/io/XActiveDataSink.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/lang/IllegalAccessException.hpp> -#include "com/sun/star/ucb/AuthenticationRequest.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> -#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_ #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> -#endif #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> -#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_ #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp> -#endif #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp> #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp> #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp> +#include <com/sun/star/ucb/MissingInputStreamException.hpp> +#include <com/sun/star/ucb/MissingPropertiesException.hpp> #include <com/sun/star/ucb/NameClash.hpp> #include <com/sun/star/ucb/NameClashException.hpp> #include <com/sun/star/ucb/OpenCommandArgument2.hpp> #include <com/sun/star/ucb/OpenMode.hpp> #include <com/sun/star/ucb/PostCommandArgument2.hpp> #include <com/sun/star/ucb/TransferInfo.hpp> -#include <com/sun/star/ucb/XCommandInfo.hpp> -#include <com/sun/star/ucb/XPersistentPropertySet.hpp> -#include <com/sun/star/ucb/MissingInputStreamException.hpp> -#include <com/sun/star/ucb/MissingPropertiesException.hpp> #include <com/sun/star/ucb/UnsupportedCommandException.hpp> #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> #include <com/sun/star/ucb/UnsupportedNameClashException.hpp> #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> -#include <ucbhelper/contentidentifier.hxx> -#include <ucbhelper/propertyvalueset.hxx> -#include <ucbhelper/simpleinteractionrequest.hxx> -#include <ucbhelper/cancelcommandexecution.hxx> +#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" @@ -96,250 +97,6 @@ using namespace webdav_ucp; //========================================================================= //========================================================================= // -// CommandEnvironment_Impl Implementation. -// -//========================================================================= -//========================================================================= - -class CommandEnvironment_Impl : public cppu::OWeakObject, - public ucb::XCommandEnvironment, - public task::XInteractionHandler -{ -public: - - CommandEnvironment_Impl( - const uno::Reference< lang::XMultiServiceFactory >& xSMgr ) - : m_xSMgr( xSMgr ) - { - } - - // XInterface - XINTERFACE_DECL() - - // XCommandEnvironment - virtual uno::Reference< task::XInteractionHandler > SAL_CALL - getInteractionHandler( ) - throw (uno::RuntimeException) - { - return this; - } - - virtual uno::Reference< ucb::XProgressHandler > SAL_CALL - getProgressHandler( ) - throw (uno::RuntimeException) - { - return 0; - } - - // XInteractionHandler - virtual void SAL_CALL - handle( const uno::Reference< task::XInteractionRequest >& Request ) - throw (uno::RuntimeException); - -private: - - void - handleAuthenticationRequest( - ucb::AuthenticationRequest const&, - uno::Sequence< uno::Reference< task::XInteractionContinuation > > const&) - SAL_THROW((uno::RuntimeException)) - { - } - - uno::Reference< lang::XMultiServiceFactory > m_xSMgr; -}; - -//========================================================================= -void SAL_CALL CommandEnvironment_Impl::acquire() - throw() -{ - OWeakObject::acquire(); -} - -//========================================================================= -void SAL_CALL CommandEnvironment_Impl::release() - throw() -{ - OWeakObject::release(); -} - -//========================================================================= -uno::Any SAL_CALL CommandEnvironment_Impl::queryInterface( - const uno::Type & rType ) - throw( uno::RuntimeException ) -{ - uno::Any aRet = cppu::queryInterface( - rType, - static_cast< ucb::XCommandEnvironment * >( this ), - static_cast< task::XInteractionHandler * >( this ) ); - return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); -} - -//========================================================================= -void SAL_CALL CommandEnvironment_Impl::handle( - const uno::Reference< task::XInteractionRequest >& rIRequest ) - throw (uno::RuntimeException) -{ - if (!rIRequest.is()) - return; - - uno::Any aAnyRequest(rIRequest->getRequest()); - - ucb::AuthenticationRequest rRequest; - if (!(aAnyRequest >>= rRequest)) - return; - - uno::Sequence< uno::Reference< task::XInteractionContinuation > > - rContinuations = rIRequest->getContinuations(); - - // get continuations - uno::Reference< task::XInteractionRetry > xRetry; - uno::Reference< task::XInteractionAbort > xAbort; - uno::Reference< ucb::XInteractionSupplyAuthentication > - xSupplyAuthentication; - - for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i) { - xRetry = uno::Reference< task::XInteractionRetry >( - rContinuations[i], uno::UNO_QUERY ); - if( xRetry.is() ) - continue; - - xAbort = uno::Reference< task::XInteractionAbort >( - rContinuations[i], uno::UNO_QUERY ); - if (xAbort.is()) - continue; - - xSupplyAuthentication - = uno::Reference< ucb::XInteractionSupplyAuthentication >( - rContinuations[i], uno::UNO_QUERY ); - if( xSupplyAuthentication.is() ) - continue; - } - - bool bRemember; - bool bRememberPersistent; - if (xSupplyAuthentication.is()) - { - ucb::RememberAuthentication eDefault; - uno::Sequence< ucb::RememberAuthentication > aModes( - xSupplyAuthentication->getRememberPasswordModes(eDefault)); - bRemember = eDefault != ucb::RememberAuthentication_NO; - bRememberPersistent = false; - for (sal_Int32 i = 0; i < aModes.getLength(); ++i) - if (aModes[i] == ucb::RememberAuthentication_PERSISTENT) - { - bRememberPersistent = true; - break; - } - } - else - { - bRemember = false; - bRememberPersistent = false; - } - - uno::Reference< task::XPasswordContainer > xContainer; - try - { - xContainer - = uno::Reference< task::XPasswordContainer >( - m_xSMgr->createInstance( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( - "com.sun.star.task.PasswordContainer"))), - uno::UNO_QUERY); - } - catch (uno::Exception const &) - { - } - - // xContainer works with userName passwdSequences pairs: - if (xContainer.is() && rRequest.HasUserName && rRequest.HasPassword ) - { - try - { - if (rRequest.UserName.getLength() == 0) - { - task::UrlRecord - aRec(xContainer->find(rRequest.ServerName, this)); - if (aRec.UserList.getLength() != 0) - { - if (xSupplyAuthentication->canSetUserName()) - xSupplyAuthentication-> - setUserName(aRec.UserList[0].UserName.getStr()); - if (xSupplyAuthentication->canSetPassword()) - { - OSL_ENSURE(aRec.UserList[0].Passwords.getLength() != 0, - "empty password list"); - xSupplyAuthentication-> - setPassword(aRec.UserList[0].Passwords[0].getStr()); - } - if (aRec.UserList[0].Passwords.getLength() > 1) - { - if (rRequest.HasRealm) - { - if (xSupplyAuthentication->canSetRealm()) - xSupplyAuthentication-> - setRealm(aRec.UserList[0].Passwords[1]. - getStr()); - } - else if (xSupplyAuthentication->canSetAccount()) - xSupplyAuthentication-> - setAccount(aRec.UserList[0].Passwords[1]. - getStr()); - } - xSupplyAuthentication->select(); - return; - } - } - else - { - task::UrlRecord - aRec(xContainer->findForName(rRequest.ServerName, - rRequest.UserName, - this)); - if (aRec.UserList.getLength() != 0) - { - OSL_ENSURE(aRec.UserList[0].Passwords.getLength() != 0, - "empty password list"); - if (!rRequest.HasPassword - || rRequest.Password != aRec.UserList[0].Passwords[0]) - { - if (xSupplyAuthentication->canSetUserName()) - xSupplyAuthentication-> - setUserName(aRec.UserList[0].UserName.getStr()); - if (xSupplyAuthentication->canSetPassword()) - xSupplyAuthentication-> - setPassword(aRec.UserList[0].Passwords[0]. - getStr()); - if (aRec.UserList[0].Passwords.getLength() > 1) - { - if (rRequest.HasRealm) - { - if (xSupplyAuthentication->canSetRealm()) - xSupplyAuthentication-> - setRealm(aRec.UserList[0].Passwords[1]. - getStr()); - } - else if (xSupplyAuthentication->canSetAccount()) - xSupplyAuthentication-> - setAccount(aRec.UserList[0].Passwords[1]. - getStr()); - } - xSupplyAuthentication->select(); - return; - } - } - } - } - catch (task::NoMasterException const &) - {} // user did not enter master password - } - return; -} - -//========================================================================= -//========================================================================= -// // Content Implementation. // //========================================================================= @@ -446,9 +203,28 @@ uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) { try { - return isFolder( new CommandEnvironment_Impl(m_xSMgr) ) - ? aRet - : uno::Any(); + 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 & ) { @@ -630,17 +406,22 @@ uno::Any SAL_CALL Content::execute( 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 - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + // getPropertyValues + ////////////////////////////////////////////////////////////////// uno::Sequence< beans::Property > Properties; - if ( !( aCommand.Argument >>= Properties ) ) + if ( !( aCommand.Argument >>= Properties ) ) { ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( @@ -652,17 +433,17 @@ uno::Any SAL_CALL Content::execute( // Unreachable } - aRet <<= getPropertyValues( Properties, Environment ); + aRet <<= getPropertyValues( Properties, Environment ); } else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) ) { - ////////////////////////////////////////////////////////////////// - // setPropertyValues - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + // setPropertyValues + ////////////////////////////////////////////////////////////////// uno::Sequence< beans::PropertyValue > aProperties; - if ( !( aCommand.Argument >>= aProperties ) ) + if ( !( aCommand.Argument >>= aProperties ) ) { ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( @@ -674,7 +455,7 @@ uno::Any SAL_CALL Content::execute( // Unreachable } - if ( !aProperties.getLength() ) + if ( !aProperties.getLength() ) { ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( @@ -713,8 +494,8 @@ uno::Any SAL_CALL Content::execute( RTL_CONSTASCII_STRINGPARAM( "open" ) ) ) { ////////////////////////////////////////////////////////////////// - // open - ////////////////////////////////////////////////////////////////// + // open + ////////////////////////////////////////////////////////////////// ucb::OpenCommandArgument2 aOpenCommand; if ( !( aCommand.Argument >>= aOpenCommand ) ) @@ -735,11 +516,11 @@ uno::Any SAL_CALL Content::execute( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) { ////////////////////////////////////////////////////////////////// - // insert - ////////////////////////////////////////////////////////////////// + // insert + ////////////////////////////////////////////////////////////////// ucb::InsertCommandArgument arg; - if ( !( aCommand.Argument >>= arg ) ) + if ( !( aCommand.Argument >>= arg ) ) { ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( @@ -751,23 +532,23 @@ uno::Any SAL_CALL Content::execute( // Unreachable } - insert( arg.Data, arg.ReplaceExisting, Environment ); + insert( arg.Data, arg.ReplaceExisting, Environment ); } else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) { - ////////////////////////////////////////////////////////////////// - // delete - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + // delete + ////////////////////////////////////////////////////////////////// - sal_Bool bDeletePhysical = sal_False; - aCommand.Argument >>= bDeletePhysical; + 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; @@ -823,7 +604,7 @@ uno::Any SAL_CALL Content::execute( { ////////////////////////////////////////////////////////////////// // post - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// ucb::PostCommandArgument2 aArg; if ( !( aCommand.Argument >>= aArg ) ) @@ -840,20 +621,67 @@ uno::Any SAL_CALL Content::execute( post( aArg, Environment ); } + else if ( aCommand.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "lock" ) ) && + supportsExclusiveWriteLock( Environment ) ) + { + ////////////////////////////////////////////////////////////////// + // lock + ////////////////////////////////////////////////////////////////// + + lock( Environment ); + } + else if ( aCommand.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "unlock" ) ) && + supportsExclusiveWriteLock( Environment ) ) + { + ////////////////////////////////////////////////////////////////// + // unlock + ////////////////////////////////////////////////////////////////// + + unlock( Environment ); + } + else if ( aCommand.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) && + isFolder( Environment ) ) + { + ////////////////////////////////////////////////////////////////// + // createNewContent + ////////////////////////////////////////////////////////////////// + + ucb::ContentInfo aArg; + if ( !( aCommand.Argument >>= aArg ) ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( lang::IllegalArgumentException( + rtl::OUString::createFromAscii( + "Wrong argument type!" ), + static_cast< cppu::OWeakObject * >( this ), + -1 ) ), + Environment ); + // Unreachable + } + + aRet = uno::makeAny( createNewContent( aArg ) ); + } else { - ////////////////////////////////////////////////////////////////// - // Unsupported command - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + // Unsupported command + ////////////////////////////////////////////////////////////////// ucbhelper::cancelCommandExecution( uno::makeAny( ucb::UnsupportedCommandException( - rtl::OUString(), - static_cast< cppu::OWeakObject * >( this ) ) ), + 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; } @@ -863,19 +691,22 @@ void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException ) { try + { + std::auto_ptr< DAVResourceAccess > xResAccess; { - std::auto_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset( - new DAVResourceAccess( *m_xResAccess.get() ) ); - } - xResAccess->ABORT(); + osl::MutexGuard aGuard( m_aMutex ); + xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); } - catch ( DAVException const & /*e*/ ) + xResAccess->abort(); { - // ABORT command failed! + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); } + } + catch ( DAVException const & ) + { + // abort failed! + } } //========================================================================= @@ -893,8 +724,8 @@ void SAL_CALL Content::addProperty( const rtl::OUString& Name, lang::IllegalArgumentException, uno::RuntimeException ) { -// if ( m_bTransient ) -// @@@ ??? +// if ( m_bTransient ) +// @@@ ??? if ( !Name.getLength() ) throw lang::IllegalArgumentException(); @@ -902,8 +733,8 @@ void SAL_CALL Content::addProperty( const rtl::OUString& Name, // Check property type. if ( !UCBDeadPropertyValue::supportsType( DefaultValue.getValueType() ) ) { - OSL_ENSURE( sal_False, "Content::addProperty - " - "Unsupported property type!" ); + OSL_ENSURE( sal_False, + "Content::addProperty - Unsupported property type!" ); throw beans::IllegalTypeException(); } @@ -950,10 +781,10 @@ void SAL_CALL Content::addProperty( const rtl::OUString& Name, // Notify propertyset info change listeners. beans::PropertySetInfoChangeEvent evt( - static_cast< cppu::OWeakObject * >( this ), - Name, - -1, // No handle available - beans::PropertySetInfoChange::PROPERTY_INSERTED ); + static_cast< cppu::OWeakObject * >( this ), + Name, + -1, // No handle available + beans::PropertySetInfoChange::PROPERTY_INSERTED ); notifyPropertySetInfoChange( evt ); } catch ( DAVException const & e ) @@ -1029,7 +860,7 @@ void SAL_CALL Content::removeProperty( const rtl::OUString& Name ) { beans::Property aProp = getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) - ->getPropertyByName( Name ); + ->getPropertyByName( Name ); if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) ) { @@ -1039,7 +870,7 @@ void SAL_CALL Content::removeProperty( const rtl::OUString& Name ) } catch ( beans::UnknownPropertyException const & ) { -// OSL_ENSURE( sal_False, "removeProperty - Unknown property!" ); + //OSL_ENSURE( sal_False, "removeProperty - Unknown property!" ); throw; } #endif @@ -1270,7 +1101,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, const rtl::OUString& rContentId ) { - // Note: Empty sequence means "get values of all supported properties". + // Note: Empty sequence means "get values of all supported properties". rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rSMgr ); @@ -1279,10 +1110,10 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( nCount ) { uno::Reference< beans::XPropertySet > xAdditionalPropSet; - sal_Bool bTriedToGetAdditonalPropSet = sal_False; + sal_Bool bTriedToGetAdditonalPropSet = sal_False; const beans::Property* pProps = rProperties.getConstArray(); - for ( sal_Int32 n = 0; n < nCount; ++n ) + for ( sal_Int32 n = 0; n < nCount; ++n ) { const beans::Property& rProp = pProps[ n ]; @@ -1338,9 +1169,9 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( // Append all local Additional Properties. uno::Reference< beans::XPropertySet > xSet( - rProvider->getAdditionalPropertySet( rContentId, sal_False ), - uno::UNO_QUERY ); - xRow->appendPropertySet( xSet ); + rProvider->getAdditionalPropertySet( rContentId, sal_False ), + uno::UNO_QUERY ); + xRow->appendPropertySet( xSet ); } return uno::Reference< sdbc::XRow >( xRow.get() ); @@ -1357,8 +1188,8 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( std::auto_ptr< DAVResourceAccess > xResAccess; rtl::OUString aEscapedTitle; bool bHasAll = false; - uno::Reference< lang::XMultiServiceFactory > xSMgr; - uno::Reference< ucb::XContentIdentifier > xIdentifier; + uno::Reference< lang::XMultiServiceFactory > xSMgr; + uno::Reference< ucb::XContentIdentifier > xIdentifier; rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider; { @@ -1400,15 +1231,19 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( DAV == rType ) { - // cache lookup... getResourceType may fill the props cache via PROPFIND! + // cache lookup... getResourceType may fill the props cache via + // PROPFIND! if ( m_xCachedProps.get() ) { - xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) ); + xCachedProps.reset( + new ContentProperties( *m_xCachedProps.get() ) ); std::vector< rtl::OUString > aMissingProps; - if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) ) + if ( xCachedProps->containsAllNames( + rProperties, aMissingProps ) ) { - // All properties are already in cache! No server access needed. + // All properties are already in cache! No server access + // needed. bHasAll = true; } @@ -1421,7 +1256,8 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( // Only DAV resources support PROPFIND std::vector< rtl::OUString > aPropNames; - uno::Sequence< beans::Property > aProperties( rProperties.getLength() ); + uno::Sequence< beans::Property > aProperties( + rProperties.getLength() ); if ( m_aFailedPropNames.size() > 0 ) { @@ -1474,7 +1310,8 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( { if ( xProps.get()) xProps->addProperties( - aPropNames, ContentProperties( resources[ 0 ] )); + aPropNames, + ContentProperties( resources[ 0 ] )); else xProps.reset( new ContentProperties( resources[ 0 ] ) ); @@ -1483,7 +1320,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( catch ( DAVException const & e ) { bNetworkAccessAllowed - = shouldAccessNetworkAfterException( e ); + = shouldAccessNetworkAfterException( e ); if ( !bNetworkAccessAllowed ) { @@ -1523,16 +1360,16 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( xProps.get() ) xProps->addProperties( - aMissingProps, - ContentProperties( resource ) ); + aMissingProps, + ContentProperties( resource ) ); else xProps.reset ( new ContentProperties( resource ) ); if ( m_eResourceType == NON_DAV ) xProps->addProperties( aMissingProps, ContentProperties( - aEscapedTitle, - false ) ); + aEscapedTitle, + false ) ); } catch ( DAVException const & e ) { @@ -1548,15 +1385,15 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( } } } + // might trigger HTTP redirect. - // Therefore, title must be upadated here. + // Therefore, title must be updated here. NeonUri aUri( xResAccess->getURL() ); aEscapedTitle = aUri.GetPathBaseName(); if ( UNKNOWN == rType ) { - xProps.reset( - new ContentProperties( aEscapedTitle ) ); + xProps.reset( new ContentProperties( aEscapedTitle ) ); } // For DAV resources we only know the Title, for non-DAV @@ -1565,31 +1402,29 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( { //xProps.reset( // new ContentProperties( aEscapedTitle ) ); - xProps->addProperty( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "Title" )), - uno::makeAny( aEscapedTitle), true); + xProps->addProperty( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), + uno::makeAny( aEscapedTitle ), + true ); } else { if ( !xProps.get() ) - xProps.reset( - new ContentProperties( aEscapedTitle, false ) ); + xProps.reset( new ContentProperties( aEscapedTitle, false ) ); else - xProps->addProperty( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "Title" )), - uno::makeAny( aEscapedTitle), true); - - xProps->addProperty( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "IsFolder" )), - uno::makeAny( false), true); - xProps->addProperty( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "IsDocument" )), - uno::makeAny( true), true); + xProps->addProperty( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), + uno::makeAny( aEscapedTitle ), + true ); + xProps->addProperty( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ), + uno::makeAny( false ), + true ); + xProps->addProperty( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ), + uno::makeAny( true ), + true ); } } else @@ -1601,16 +1436,35 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( m_bCollection ) ); } - // Add BaseURI property, if requested. - if ( !xProps->contains( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) ) ) + sal_Int32 nCount = rProperties.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) { - xProps->addProperty( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "BaseURI" ) ), - uno::makeAny( - getBaseURI( xResAccess ) ), - true ); + 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 @@ -1663,7 +1517,7 @@ uno::Sequence< uno::Any > Content::setPropertyValues( beans::PropertyChangeEvent aEvent; aEvent.Source = static_cast< cppu::OWeakObject * >( this ); - aEvent.Further = sal_False; + aEvent.Further = sal_False; // aEvent.PropertyName = aEvent.PropertyHandle = -1; // aEvent.OldValue = @@ -1724,7 +1578,7 @@ uno::Sequence< uno::Any > Content::setPropertyValues( static_cast< cppu::OWeakObject * >( this ) ); } else if ( rName.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) + RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) { // Read-only property! aRet[ n ] <<= lang::IllegalAccessException( @@ -1843,6 +1697,15 @@ uno::Sequence< uno::Any > Content::setPropertyValues( "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 ) @@ -2035,7 +1898,7 @@ uno::Sequence< uno::Any > Content::setPropertyValues( aEvent.OldValue = uno::makeAny( aOldTitle ); aEvent.NewValue = uno::makeAny( aNewTitle ); - m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle ); + m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle ); aChanges.getArray()[ nChanged ] = aEvent; nChanged++; @@ -2043,8 +1906,8 @@ uno::Sequence< uno::Any > Content::setPropertyValues( if ( nChanged > 0 ) { - aChanges.realloc( nChanged ); - notifyPropertiesChange( aChanges ); + aChanges.realloc( nChanged ); + notifyPropertiesChange( aChanges ); } { @@ -2150,7 +2013,8 @@ uno::Any Content::open( // cache headers. if ( !m_xCachedProps.get()) - m_xCachedProps.reset( new ContentProperties( aResource ) ); + m_xCachedProps.reset( + new ContentProperties( aResource ) ); else m_xCachedProps->addProperties( aResource ); @@ -2195,9 +2059,11 @@ uno::Any Content::open( // cache headers. if ( !m_xCachedProps.get()) - m_xCachedProps.reset( new ContentProperties( aResource ) ); + m_xCachedProps.reset( + new ContentProperties( aResource ) ); else - m_xCachedProps->addProperties( aResource.properties ); + m_xCachedProps->addProperties( + aResource.properties ); m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) ); @@ -2407,17 +2273,17 @@ void Content::insert( { /* [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. + 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. + 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. @@ -2887,6 +2753,99 @@ void Content::destroy( sal_Bool bDeletePhysical ) } //========================================================================= +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 ) { @@ -2936,9 +2895,9 @@ sal_Bool Content::exchangeIdentity( 0, aOldURL.getLength(), xNewId->getContentIdentifier() ); - uno::Reference< ucb::XContentIdentifier > - xNewChildId - = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewChildURL ); + uno::Reference< ucb::XContentIdentifier > xNewChildId + = new ::ucbhelper::ContentIdentifier( + m_xSMgr, aNewChildURL ); if ( !xChild->exchangeIdentity( xNewChildId ) ) return sal_False; @@ -3010,7 +2969,6 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) aArgs ); return aException; } - default: break; } @@ -3022,14 +2980,14 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) if ( bWrite ) aException <<= ucb::InteractiveNetworkWriteException( - rtl::OUString(), + e.getData(), static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, e.getData() ); else aException <<= ucb::InteractiveNetworkReadException( - rtl::OUString(), + e.getData(), static_cast< cppu::OWeakObject * >( this ), task::InteractionClassification_ERROR, e.getData() ); @@ -3046,12 +3004,12 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) break; // @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_AUTH: -// break; +// case DAVException::DAV_HTTP_AUTH: +// break; // @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_AUTHPROXY: -// break; +// case DAVException::DAV_HTTP_AUTHPROXY: +// break; case DAVException::DAV_HTTP_CONNECT: aException <<= @@ -3063,16 +3021,16 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) break; // @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_TIMEOUT: -// break; +// case DAVException::DAV_HTTP_TIMEOUT: +// break; // @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_REDIRECT: -// break; +// case DAVException::DAV_HTTP_REDIRECT: +// break; // @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_SESSION_CREATE: -// break; +// case DAVException::DAV_SESSION_CREATE: +// break; case DAVException::DAV_INVALID_ARG: aException <<= @@ -3082,6 +3040,62 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite ) -1 ); break; + case DAVException::DAV_LOCKED: +#if 1 + aException <<= + ucb::InteractiveLockingLockedException( + rtl::OUString::createFromAscii( "Locked!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + m_xIdentifier->getContentIdentifier(), + sal_True ); +#else + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= beans::PropertyValue( + rtl::OUString::createFromAscii("Uri"), -1, + uno::makeAny(m_xIdentifier->getContentIdentifier()), + beans::PropertyState_DIRECT_VALUE); + + aException <<= + ucb::InteractiveAugmentedIOException( + rtl::OUString::createFromAscii( "Locked!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + ucb::IOErrorCode_LOCKING_VIOLATION, + aArgs ); + } +#endif + break; + + case DAVException::DAV_LOCKED_SELF: + aException <<= + ucb::InteractiveLockingLockedException( + rtl::OUString::createFromAscii( "Locked (self)!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + m_xIdentifier->getContentIdentifier(), + sal_True ); + break; + + case DAVException::DAV_NOT_LOCKED: + aException <<= + ucb::InteractiveLockingNotLockedException( + rtl::OUString::createFromAscii( "Not locked!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + m_xIdentifier->getContentIdentifier() ); + break; + + case DAVException::DAV_LOCK_EXPIRED: + aException <<= + ucb::InteractiveLockingLockExpiredException( + rtl::OUString::createFromAscii( "Lock expired!" ), + static_cast< cppu::OWeakObject * >( this ), + task::InteractionClassification_ERROR, + m_xIdentifier->getContentIdentifier() ); + break; + default: aException <<= ucb::InteractiveNetworkGeneralException( @@ -3120,7 +3134,8 @@ void Content::cancelCommandExecution( } //========================================================================= -const rtl::OUString Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess ) +const rtl::OUString +Content::getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess ) { osl::Guard< osl::Mutex > aGuard( m_aMutex ); @@ -3181,11 +3196,17 @@ const Content::ResourceType & Content::getResourceType( // this is a DAV resource. std::vector< DAVResource > resources; std::vector< rtl::OUString > aPropNames; - uno::Sequence< beans::Property > aProperties( 4 ); - 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" ); + 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 ); @@ -3195,16 +3216,19 @@ const Content::ResourceType & Content::getResourceType( if ( resources.size() == 1 ) { - m_xCachedProps.reset( new ContentProperties( resources[ 0 ] ) ); - m_xCachedProps->containsAllNames( aProperties, m_aFailedPropNames ); + m_xCachedProps.reset( + new ContentProperties( resources[ 0 ] ) ); + m_xCachedProps->containsAllNames( + aProperties, m_aFailedPropNames ); } + eResourceType = DAV; } - catch ( DAVException const& e) + catch ( DAVException const & e ) { rResAccess->resetUri(); - if (e.getStatus() == SC_METHOD_NOT_ALLOWED) + if ( e.getStatus() == SC_METHOD_NOT_ALLOWED ) { // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the // resource is NON_DAV @@ -3213,7 +3237,6 @@ const Content::ResourceType & Content::getResourceType( } } m_eResourceType = eResourceType; - } return m_eResourceType; } |