summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kso@openoffice.org>2009-11-12 15:22:00 +0100
committerKai Sommerfeld <kso@openoffice.org>2009-11-12 15:22:00 +0100
commit99bdd887a6141883878978bad9beb35e7b326cd1 (patch)
treed2f30266fdf4fa78a6b1ed49498a8f318019f889
parent19a645e9cd708856500063e741741bbe0da566b0 (diff)
#i106830# WebDAV locking support for UCB
-rw-r--r--ucb/source/ucp/webdav/DAVException.hxx36
-rw-r--r--ucb/source/ucp/webdav/DAVProperties.cxx26
-rw-r--r--ucb/source/ucp/webdav/DAVResourceAccess.cxx170
-rw-r--r--ucb/source/ucp/webdav/DAVResourceAccess.hxx160
-rw-r--r--ucb/source/ucp/webdav/DAVSession.hxx127
-rw-r--r--ucb/source/ucp/webdav/NeonLockStore.cxx251
-rw-r--r--ucb/source/ucp/webdav/NeonLockStore.hxx105
-rw-r--r--ucb/source/ucp/webdav/NeonPropFindRequest.cxx88
-rw-r--r--ucb/source/ucp/webdav/NeonSession.cxx917
-rw-r--r--ucb/source/ucp/webdav/NeonSession.hxx462
-rw-r--r--ucb/source/ucp/webdav/NeonTypes.hxx3
-rw-r--r--ucb/source/ucp/webdav/NeonUri.cxx5
-rw-r--r--ucb/source/ucp/webdav/makefile.mk54
-rw-r--r--ucb/source/ucp/webdav/webdavcontent.cxx525
-rw-r--r--ucb/source/ucp/webdav/webdavcontent.hxx189
-rw-r--r--ucb/source/ucp/webdav/webdavcontentcaps.cxx301
-rw-r--r--uui/source/iahndl.cxx55
-rw-r--r--uui/source/ids.hrc4
-rw-r--r--uui/source/ids.src22
19 files changed, 2245 insertions, 1255 deletions
diff --git a/ucb/source/ucp/webdav/DAVException.hxx b/ucb/source/ucp/webdav/DAVException.hxx
index 8e87ab2f2a36..cbbd64755942 100644
--- a/ucb/source/ucp/webdav/DAVException.hxx
+++ b/ucb/source/ucp/webdav/DAVException.hxx
@@ -108,17 +108,37 @@ class DAVException
{
public:
enum ExceptionCode {
- DAV_HTTP_ERROR = 0, // Generic error, mData = error message
- DAV_HTTP_LOOKUP, // Name lookup failed, mData = server[:port]
- DAV_HTTP_AUTH, // User authentication failed on server
- DAV_HTTP_AUTHPROXY, // User authentication failed on proxy
- DAV_HTTP_CONNECT, // Could not connect to server, mData = server[:port]
+ DAV_HTTP_ERROR = 0, // Generic error,
+ // mData = server error message,
+ // mStatusCode = HTTP status code
+ DAV_HTTP_LOOKUP, // Name lookup failed,
+ // mData = server[:port]
+ DAV_HTTP_AUTH, // User authentication failed on server,
+ // mData = server[:port]
+ DAV_HTTP_AUTHPROXY, // User authentication failed on proxy,
+ // mData = proxy server[:port]
+ DAV_HTTP_CONNECT, // Could not connect to server,
+ // mData = server[:port]
DAV_HTTP_TIMEOUT, // Connection timed out
+ // mData = server[:port]
DAV_HTTP_FAILED, // The precondition failed
+ // mData = server[:port]
DAV_HTTP_RETRY, // Retry request
- DAV_HTTP_REDIRECT, // See http_redirect.h, mData = new URL
- DAV_SESSION_CREATE, // session creation error, mData = server[:port]
- DAV_INVALID_ARG }; // mData = file URL
+ // mData = server[:port]
+ DAV_HTTP_REDIRECT, // Request was redirected,
+ // mData = new URL
+ DAV_SESSION_CREATE, // session creation error,
+ // mData = server[:port]
+ DAV_INVALID_ARG, // invalid argument
+
+ DAV_LOCK_EXPIRED, // DAV lock expired
+
+ DAV_NOT_LOCKED, // not locked
+
+ DAV_LOCKED_SELF, // locked by this OOo session
+
+ DAV_LOCKED // locked by third party
+ };
private:
ExceptionCode mExceptionCode;
diff --git a/ucb/source/ucp/webdav/DAVProperties.cxx b/ucb/source/ucp/webdav/DAVProperties.cxx
index 2f11c2ee02c0..d2d434184ace 100644
--- a/ucb/source/ucp/webdav/DAVProperties.cxx
+++ b/ucb/source/ucp/webdav/DAVProperties.cxx
@@ -137,6 +137,26 @@ void DAVProperties::createUCBPropName( const char * nspace,
rtl::OUString aName
= rtl::OStringToOUString( name, RTL_TEXTENCODING_UTF8 );
+ if ( !aNameSpace.getLength() )
+ {
+ // Some servers send XML without proper namespaces. Assume "DAV:"
+ // in this case, if name is a well-known dav property name.
+ // Although this is not 100% correct, it solves many problems.
+
+ if ( DAVProperties::RESOURCETYPE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::SUPPORTEDLOCK.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::LOCKDISCOVERY.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::CREATIONDATE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::DISPLAYNAME.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTLANGUAGE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTLENGTH.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETCONTENTTYPE.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETETAG.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::GETLASTMODIFIED.matchIgnoreAsciiCase( aName, 4 ) ||
+ DAVProperties::SOURCE.matchIgnoreAsciiCase( aName, 4 ) )
+ aNameSpace = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DAV:" ) );
+ }
+
// Note: Concatenating strings BEFORE comparing against known namespaces
// is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
rFullName = aNameSpace;
@@ -175,6 +195,8 @@ void DAVProperties::createUCBPropName( const char * nspace,
// static
bool DAVProperties::isUCBDeadProperty( const NeonPropName & rName )
{
- return ( rtl_str_compareIgnoreAsciiCase(
- rName.nspace, "http://ucb.openoffice.org/dav/props/" ) == 0 );
+ return ( rName.nspace &&
+ ( rtl_str_compareIgnoreAsciiCase(
+ rName.nspace, "http://ucb.openoffice.org/dav/props/" )
+ == 0 ) );
}
diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.cxx b/ucb/source/ucp/webdav/DAVResourceAccess.cxx
index 67f8e5a386f0..5095950c4c0e 100644
--- a/ucb/source/ucp/webdav/DAVResourceAccess.cxx
+++ b/ucb/source/ucp/webdav/DAVResourceAccess.cxx
@@ -67,6 +67,7 @@ int DAVAuthListener_Impl::authenticate(
{
uno::Reference< task::XInteractionHandler > xIH
= m_xEnv->getInteractionHandler();
+
if ( xIH.is() )
{
// #102871# - Supply username and password from previous try.
@@ -78,14 +79,10 @@ int DAVAuthListener_Impl::authenticate(
outPassWord = m_aPrevPassword;
rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
- = new ucbhelper::SimpleAuthenticationRequest( m_aURL,
- inHostName,
- inRealm,
- inoutUserName,
- outPassWord,
- ::rtl::OUString(),
- bAllowPersistentStoring,
- bCanUseSystemCredentials );
+ = new ucbhelper::SimpleAuthenticationRequest(
+ m_aURL, inHostName, inRealm, inoutUserName,
+ outPassWord, ::rtl::OUString(),
+ bAllowPersistentStoring, bCanUseSystemCredentials );
xIH->handle( xRequest.get() );
rtl::Reference< ucbhelper::InteractionContinuation > xSelection
@@ -105,7 +102,8 @@ int DAVAuthListener_Impl::authenticate(
sal_Bool bUseSystemCredentials = sal_False;
if ( bCanUseSystemCredentials )
- bUseSystemCredentials = xSupp->getUseSystemCredentials();
+ bUseSystemCredentials
+ = xSupp->getUseSystemCredentials();
if ( bUseSystemCredentials )
{
@@ -353,6 +351,7 @@ void DAVResourceAccess::HEAD(
throw( DAVException )
{
initialize();
+
int errorCount = 0;
bool bRetry;
do
@@ -409,7 +408,8 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET(
xStream = m_xSession->GET( getRequestURI(),
DAVRequestEnvironment(
getRequestURI(),
- new DAVAuthListener_Impl( xEnv, m_aURL ),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
aHeaders, xEnv ) );
}
catch ( DAVException & e )
@@ -492,7 +492,8 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET(
rResource,
DAVRequestEnvironment(
getRequestURI(),
- new DAVAuthListener_Impl( xEnv, m_aURL ),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
aHeaders, xEnv ) );
}
catch ( DAVException & e )
@@ -552,12 +553,13 @@ void DAVResourceAccess::GET(
}
//=========================================================================
-void DAVResourceAccess::ABORT()
+void DAVResourceAccess::abort()
throw( DAVException )
{
initialize();
- m_xSession->ABORT();
+ m_xSession->abort();
}
+
//=========================================================================
namespace {
@@ -673,7 +675,8 @@ uno::Reference< io::XInputStream > DAVResourceAccess::POST(
xSeekableStream,
DAVRequestEnvironment(
getRequestURI(),
- new DAVAuthListener_Impl( xEnv, m_aURL ),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
aHeaders, xEnv ) );
}
catch ( DAVException & e )
@@ -696,7 +699,6 @@ uno::Reference< io::XInputStream > DAVResourceAccess::POST(
}
//=========================================================================
-
void DAVResourceAccess::POST(
const rtl::OUString & rContentType,
const rtl::OUString & rReferer,
@@ -764,6 +766,7 @@ void DAVResourceAccess::MKCOL(
throw( DAVException )
{
initialize();
+
int errorCount = 0;
bool bRetry;
do
@@ -803,6 +806,7 @@ void DAVResourceAccess::COPY(
throw( DAVException )
{
initialize();
+
int errorCount = 0;
bool bRetry;
do
@@ -844,6 +848,7 @@ void DAVResourceAccess::MOVE(
throw( DAVException )
{
initialize();
+
int errorCount = 0;
bool bRetry;
do
@@ -915,23 +920,124 @@ void DAVResourceAccess::DESTROY(
}
//=========================================================================
-void DAVResourceAccess::LOCK (
- const ucb::Lock & /*rLock*/,
- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
- throw( DAVException )
+// set new lock.
+void DAVResourceAccess::LOCK(
+ ucb::Lock & inLock,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
{
-// initialize();
- OSL_ENSURE( sal_False, "DAVResourceAccess::LOCK - NYI" );
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "LOCK" ),
+ aHeaders );
+
+ m_xSession->LOCK( getRequestURI(),
+ inLock,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
}
//=========================================================================
-void DAVResourceAccess::UNLOCK (
- const ucb::Lock & /*rLock*/,
- const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
- throw( DAVException )
+// refresh existing lock.
+sal_Int64 DAVResourceAccess::LOCK(
+ sal_Int64 nTimeout,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
+{
+ initialize();
+
+ sal_Int64 nNewTimeout = 0;
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "LOCK" ),
+ aHeaders );
+
+ nNewTimeout = m_xSession->LOCK( getRequestURI(),
+ nTimeout,
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl(
+ xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
+
+ return nNewTimeout;
+}
+
+//=========================================================================
+void DAVResourceAccess::UNLOCK(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException )
{
-// initialize();
- OSL_ENSURE( sal_False, "DAVResourceAccess::UNLOCK - NYI" );
+ initialize();
+
+ int errorCount = 0;
+ bool bRetry;
+ do
+ {
+ bRetry = false;
+ try
+ {
+ DAVRequestHeaders aHeaders;
+ getUserRequestHeaders( xEnv,
+ getRequestURI(),
+ rtl::OUString::createFromAscii( "UNLOCK" ),
+ aHeaders );
+
+ m_xSession->UNLOCK( getRequestURI(),
+ DAVRequestEnvironment(
+ getRequestURI(),
+ new DAVAuthListener_Impl( xEnv, m_aURL ),
+ aHeaders, xEnv ) );
+ }
+ catch ( DAVException & e )
+ {
+ errorCount++;
+ bRetry = handleException( e, errorCount );
+ if ( !bRetry )
+ throw;
+ }
+ }
+ while ( bRetry );
}
//=========================================================================
@@ -1028,9 +1134,8 @@ void DAVResourceAccess::getUserRequestHeaders(
"Value is not a string! Ignoring..." );
}
- rRequestHeaders.push_back( DAVRequestHeader(
- aRequestHeaders[ n ].Name,
- aValue ) );
+ rRequestHeaders.push_back(
+ DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) );
}
}
}
@@ -1074,7 +1179,6 @@ void DAVResourceAccess::resetUri()
}
}
-
//=========================================================================
sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount )
throw ( DAVException )
@@ -1094,7 +1198,9 @@ sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount )
// if we have a bad connection try again. Up to three times.
case DAVException::DAV_HTTP_ERROR:
// retry up to three times, if not a client-side error.
- if ( ( e.getStatus() < 400 || e.getStatus() > 499 ) && errorCount < 3)
+ if ( e.getStatus() > 0 &&
+ ( e.getStatus() < 400 || e.getStatus() > 499 ) &&
+ errorCount < 3 )
{
return sal_True;
}
diff --git a/ucb/source/ucp/webdav/DAVResourceAccess.hxx b/ucb/source/ucp/webdav/DAVResourceAccess.hxx
index 2ab863dc0b24..6d8ea4fad43e 100644
--- a/ucb/source/ucp/webdav/DAVResourceAccess.hxx
+++ b/ucb/source/ucp/webdav/DAVResourceAccess.hxx
@@ -59,22 +59,22 @@ class DAVResourceAccess
rtl::Reference< DAVSession > m_xSession;
rtl::Reference< DAVSessionFactory > m_xSessionFactory;
com::sun::star::uno::Reference<
- com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
std::vector< NeonUri > m_aRedirectURIs;
public:
DAVResourceAccess() : m_xSessionFactory( 0 ) {}
DAVResourceAccess( const com::sun::star::uno::Reference<
- com::sun::star::lang::XMultiServiceFactory > & rSMgr,
+ com::sun::star::lang::XMultiServiceFactory > & rSMgr,
rtl::Reference<
- DAVSessionFactory > const & rSessionFactory,
+ DAVSessionFactory > const & rSessionFactory,
const rtl::OUString & rURL );
DAVResourceAccess( const DAVResourceAccess & rOther );
DAVResourceAccess & operator=( const DAVResourceAccess & rOther );
void setURL( const rtl::OUString & rNewURL )
- throw( DAVException );
+ throw ( DAVException );
void resetUri();
@@ -88,144 +88,152 @@ public:
void
OPTIONS( DAVCapabilities & rCapabilities,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
// allprop & named
void
PROPFIND( const Depth nDepth,
- const std::vector< rtl::OUString > & rPropertyNames,
- std::vector< DAVResource > & rResources,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ const std::vector< rtl::OUString > & rPropertyNames,
+ std::vector< DAVResource > & rResources,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
// propnames
void
PROPFIND( const Depth nDepth,
- std::vector< DAVResourceInfo > & rResInfo,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ std::vector< DAVResourceInfo > & rResInfo,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
PROPPATCH( const std::vector< ProppatchValue > & rValues,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& xEnv )
- throw( DAVException );
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
void
HEAD( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
DAVResource & rResource,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( DAVException );
com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
GET( const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
GET( com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & rStream,
+ com::sun::star::io::XOutputStream > & rStream,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
GET( const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
DAVResource & rResource,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
GET( com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & rStream,
+ com::sun::star::io::XOutputStream > & rStream,
const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all'
DAVResource & rResource,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
PUT( const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & rStream,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::io::XInputStream > & rStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
POST( const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & rInputStream,
- const com::sun::star::uno::Reference<
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & rInputStream,
+ const com::sun::star::uno::Reference<
com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( DAVException );
void
POST( const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & rInputStream,
- com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & rOutputStream,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & rInputStream,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & rOutputStream,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( DAVException );
void
MKCOL( const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
COPY( const ::rtl::OUString & rSourcePath,
- const ::rtl::OUString & rDestinationURI,
- sal_Bool bOverwrite,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
MOVE( const ::rtl::OUString & rSourcePath,
- const ::rtl::OUString & rDestinationURI,
- sal_Bool bOverwrite,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ const ::rtl::OUString & rDestinationURI,
+ sal_Bool bOverwrite,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
DESTROY( const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
+ // set new lock.
void
- LOCK( const com::sun::star::ucb::Lock & rLock,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ LOCK( com::sun::star::ucb::Lock & inLock,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( DAVException );
+
+ // refresh existing lock.
+ sal_Int64
+ LOCK( sal_Int64 nTimeout,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
- UNLOCK( const com::sun::star::ucb::Lock & rLock,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
- throw( DAVException );
+ UNLOCK( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( DAVException );
void
- ABORT()
- throw( DAVException );
+ abort()
+ throw ( DAVException );
// helper
- static void getUserRequestHeaders(
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv,
- const rtl::OUString & rURI,
- const rtl::OUString & rMethod,
- DAVRequestHeaders & rRequestHeaders );
+ static void
+ getUserRequestHeaders(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv,
+ const rtl::OUString & rURI,
+ const rtl::OUString & rMethod,
+ DAVRequestHeaders & rRequestHeaders );
private:
const rtl::OUString & getRequestURI() const;
diff --git a/ucb/source/ucp/webdav/DAVSession.hxx b/ucb/source/ucp/webdav/DAVSession.hxx
index b6de1c5b10ad..040046e13534 100644
--- a/ucb/source/ucp/webdav/DAVSession.hxx
+++ b/ucb/source/ucp/webdav/DAVSession.hxx
@@ -42,7 +42,9 @@
#include "DAVTypes.hxx"
#include "DAVRequestEnvironment.hxx"
-
+namespace com { namespace sun { namespace star { namespace ucb {
+ class Lock;
+} } } }
namespace webdav_ucp
{
@@ -73,28 +75,28 @@ public:
// DAV methods
//
- virtual void OPTIONS( const ::rtl::OUString & inPath,
+ virtual void OPTIONS( const ::rtl::OUString & inPath,
DAVCapabilities & outCapabilities,
const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
// allprop & named
- virtual void PROPFIND( const ::rtl::OUString & inPath,
- const Depth inDepth,
+ virtual void PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
const std::vector< ::rtl::OUString > & inPropertyNames,
- std::vector< DAVResource > & ioResources,
+ std::vector< DAVResource > & ioResources,
const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
// propnames
- virtual void PROPFIND( const ::rtl::OUString & inPath,
- const Depth inDepth,
+ virtual void PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
std::vector< DAVResourceInfo > & ioResInfo,
const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- virtual void PROPPATCH( const ::rtl::OUString & inPath,
- const std::vector< ProppatchValue > & inValues,
+ virtual void PROPPATCH( const ::rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
@@ -105,87 +107,95 @@ public:
throw( DAVException ) = 0;
virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
- GET( const ::rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
+ GET( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- virtual void GET( const ::rtl::OUString & inPath,
- com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& o,
- const DAVRequestEnvironment & rEnv )
+ virtual void GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream >& o,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
- GET( const ::rtl::OUString & inPath,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- virtual void GET( const ::rtl::OUString & inPath,
- com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& o,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& o,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- virtual void PUT( const ::rtl::OUString & inPath,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream >& s,
- const DAVRequestEnvironment & rEnv )
- throw( DAVException ) = 0;
-
- virtual void ABORT()
+ virtual void PUT( const ::rtl::OUString & inPath,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >& s,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
- POST( const rtl::OUString & inPath,
- const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & inInputStream,
- const DAVRequestEnvironment & rEnv )
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException ) = 0;
virtual void POST( const rtl::OUString & inPath,
const rtl::OUString & rContentType,
const rtl::OUString & rReferer,
const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & inInputStream,
+ com::sun::star::io::XInputStream > & inInputStream,
com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & oOutputStream,
+ com::sun::star::io::XOutputStream > & oOutputStream,
const DAVRequestEnvironment & rEnv )
throw ( DAVException ) = 0;
- virtual void MKCOL( const ::rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
+ virtual void MKCOL( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- virtual void COPY( const ::rtl::OUString & inSource,
- const ::rtl::OUString & inDestination,
- const DAVRequestEnvironment & rEnv,
- sal_Bool inOverwrite = false )
+ virtual void COPY( const ::rtl::OUString & inSource,
+ const ::rtl::OUString & inDestination,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverwrite = false )
throw( DAVException ) = 0;
- virtual void MOVE( const ::rtl::OUString & inSource,
- const ::rtl::OUString & inDestination,
- const DAVRequestEnvironment & rEnv,
- sal_Bool inOverwrite = false )
+ virtual void MOVE( const ::rtl::OUString & inSource,
+ const ::rtl::OUString & inDestination,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverwrite = false )
throw( DAVException ) = 0;
- virtual void DESTROY( const ::rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
+ virtual void DESTROY( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
throw( DAVException ) = 0;
- // Note: Uncomment the following if locking support is required
- /*
- virtual void LOCK ( const Lock & inLock,
- const DAVRequestEnvironment & rEnv )
- throw( DAVException ) = 0;
+ // set new lock.
+ virtual void LOCK( const ::rtl::OUString & inPath,
+ com::sun::star::ucb::Lock & inLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
- virtual void UNLOCK ( const Lock & inLock,
- const DAVRequestEnvironment & rEnv )
+ // refresh existing lock.
+ virtual sal_Int64 LOCK( const ::rtl::OUString & inPath,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void UNLOCK( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException ) = 0;
+
+ virtual void abort()
throw( DAVException ) = 0;
- */
+
protected:
rtl::Reference< DAVSessionFactory > m_xFactory;
@@ -210,4 +220,3 @@ private:
} // namespace webdav_ucp
#endif // _DAVSESSION_HXX_
-
diff --git a/ucb/source/ucp/webdav/NeonLockStore.cxx b/ucb/source/ucp/webdav/NeonLockStore.cxx
new file mode 100644
index 000000000000..b6246e8c3485
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonLockStore.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <ne_locks.h>
+#include <ne_uri.h>
+#include "rtl/ustring.hxx"
+#include "osl/time.h"
+#include "osl/thread.hxx"
+#include "NeonSession.hxx"
+#include "NeonLockStore.hxx"
+
+using namespace webdav_ucp;
+
+namespace webdav_ucp {
+
+class TickerThread : public osl::Thread
+{
+ bool m_bFinish;
+ NeonLockStore & m_rLockStore;
+
+public:
+
+ TickerThread( NeonLockStore & rLockStore )
+ : osl::Thread(), m_bFinish( false ), m_rLockStore( rLockStore ) {}
+
+ void finish() { m_bFinish = true; }
+
+protected:
+
+ virtual void SAL_CALL run();
+};
+
+} // namespace webdav_ucp
+
+// -------------------------------------------------------------------
+void TickerThread::run()
+{
+ OSL_TRACE( "TickerThread: start." );
+
+ // we have to go through the loop more often to be able to finish ~quickly
+ const int nNth = 25;
+
+ int nCount = nNth;
+ while ( !m_bFinish )
+ {
+ if ( nCount-- <= 0 )
+ {
+ m_rLockStore.refreshLocks();
+ nCount = nNth;
+ }
+
+ TimeValue aTV;
+ aTV.Seconds = 0;
+ aTV.Nanosec = 1000000000 / nNth;
+ wait( aTV );
+ }
+
+ OSL_TRACE( "TickerThread: stop." );
+}
+
+// -------------------------------------------------------------------
+NeonLockStore::NeonLockStore()
+ : m_pNeonLockStore( ne_lockstore_create() ),
+ m_pTickerThread( 0 )
+{
+ OSL_TRACE( "LockStore ctor." );
+ OSL_ENSURE( m_pNeonLockStore, "Unable to create neon lock store!" );
+}
+
+// -------------------------------------------------------------------
+NeonLockStore::~NeonLockStore()
+{
+ OSL_TRACE( "LockStore dtor." );
+
+ stopTicker();
+
+ // release active locks, if any (just for safety).
+ OSL_ENSURE( m_aLockInfoMap.size() == 0,
+ "NeonLockStore::~NeonLockStore - Releasing active locks!" );
+ LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
+ const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
+ while ( it != end )
+ {
+ NeonLock * pLock = (*it).first;
+ (*it).second.xSession->UNLOCK( pLock );
+
+ ne_lockstore_remove( m_pNeonLockStore, pLock );
+ ne_lock_destroy( pLock );
+
+ ++it;
+ }
+
+ ne_lockstore_destroy( m_pNeonLockStore );
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::startTicker()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !m_pTickerThread )
+ {
+ m_pTickerThread = new TickerThread( *this );
+ m_pTickerThread->create();
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::stopTicker()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_pTickerThread )
+ {
+ m_pTickerThread->finish();
+ m_pTickerThread->join();
+ delete m_pTickerThread;
+ m_pTickerThread = 0;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::registerSession( HttpSession * pHttpSession )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_lockstore_register( m_pNeonLockStore, pHttpSession );
+}
+
+// -------------------------------------------------------------------
+NeonLock * NeonLockStore::findByUri( rtl::OUString const & rUri )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_uri aUri;
+ ne_uri_parse( rtl::OUStringToOString(
+ rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri );
+ return ne_lockstore_findbyuri( m_pNeonLockStore, &aUri );
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::addLock( NeonLock * pLock,
+ rtl::Reference< NeonSession > const & xSession,
+ sal_Int32 nLastChanceToSendRefreshRequest )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ne_lockstore_add( m_pNeonLockStore, pLock );
+ m_aLockInfoMap[ pLock ]
+ = LockInfo( xSession, nLastChanceToSendRefreshRequest );
+
+ startTicker();
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::updateLock( NeonLock * pLock,
+ sal_Int32 nLastChanceToSendRefreshRequest )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
+ OSL_ENSURE( it != m_aLockInfoMap.end(),
+ "NeonLockStore::updateLock: lock not found!" );
+
+ if ( it != m_aLockInfoMap.end() )
+ {
+ (*it).second.nLastChanceToSendRefreshRequest
+ = nLastChanceToSendRefreshRequest;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::removeLock( NeonLock * pLock )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ m_aLockInfoMap.erase( pLock );
+ ne_lockstore_remove( m_pNeonLockStore, pLock );
+
+ if ( m_aLockInfoMap.size() == 0 )
+ stopTicker();
+}
+
+// -------------------------------------------------------------------
+void NeonLockStore::refreshLocks()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ //OSL_TRACE( "NeonLockStore::refreshLocks" );
+
+ LockInfoMap::iterator it( m_aLockInfoMap.begin() );
+ const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
+ while ( it != end )
+ {
+ LockInfo & rInfo = (*it).second;
+ if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
+ {
+ // 30 seconds or less remaining until lock expires?
+ TimeValue t1;
+ osl_getSystemTime( &t1 );
+ if ( rInfo.nLastChanceToSendRefreshRequest - 30
+ <= sal_Int32( t1.Seconds ) )
+ {
+ // refresh the lock.
+ sal_Int32 nlastChanceToSendRefreshRequest = -1;
+ if ( rInfo.xSession->LOCK(
+ (*it).first,
+ /* out param */ nlastChanceToSendRefreshRequest ) )
+ {
+ rInfo.nLastChanceToSendRefreshRequest
+ = nlastChanceToSendRefreshRequest;
+ }
+ else
+ {
+ // refresh failed. stop auto-refresh.
+ rInfo.nLastChanceToSendRefreshRequest = -1;
+ }
+ }
+ }
+ ++it;
+ }
+}
diff --git a/ucb/source/ucp/webdav/NeonLockStore.hxx b/ucb/source/ucp/webdav/NeonLockStore.hxx
new file mode 100644
index 000000000000..b00361d55eff
--- /dev/null
+++ b/ucb/source/ucp/webdav/NeonLockStore.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_NEONLOCKSTORE_HXX
+#define INCLUDED_NEONLOCKSTORE_HXX
+
+#include <map>
+#include "ne_locks.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "NeonTypes.hxx"
+
+namespace webdav_ucp
+{
+
+class TickerThread;
+class NeonSession;
+
+struct ltptr
+{
+ bool operator()( const NeonLock * p1, const NeonLock * p2 ) const
+ {
+ return p1 < p2;
+ }
+};
+
+typedef struct _LockInfo
+{
+ rtl::Reference< NeonSession > xSession;
+ sal_Int32 nLastChanceToSendRefreshRequest;
+
+ _LockInfo()
+ : nLastChanceToSendRefreshRequest( -1 ) {}
+
+ _LockInfo( rtl::Reference< NeonSession > const & _xSession,
+ sal_Int32 _nLastChanceToSendRefreshRequest )
+ : xSession( _xSession ),
+ nLastChanceToSendRefreshRequest( _nLastChanceToSendRefreshRequest ) {}
+
+} LockInfo;
+
+typedef std::map< NeonLock *, LockInfo, ltptr > LockInfoMap;
+
+class NeonLockStore
+{
+ osl::Mutex m_aMutex;
+ ne_lock_store * m_pNeonLockStore;
+ TickerThread * m_pTickerThread;
+ LockInfoMap m_aLockInfoMap;
+
+public:
+ NeonLockStore();
+ ~NeonLockStore();
+
+ void registerSession( HttpSession * pHttpSession );
+
+ NeonLock * findByUri( rtl::OUString const & rUri );
+
+ void addLock( NeonLock * pLock,
+ rtl::Reference< NeonSession > const & xSession,
+ // time in seconds since Jan 1 1970
+ // -1: infinite lock, no refresh
+ sal_Int32 nLastChanceToSendRefreshRequest );
+
+ void updateLock( NeonLock * pLock,
+ sal_Int32 nLastChanceToSendRefreshRequest );
+
+ void removeLock( NeonLock * pLock );
+
+ void refreshLocks();
+
+private:
+ void startTicker();
+ void stopTicker();
+};
+
+} // namespace webdav_ucp
+
+#endif // INCLUDED_NEONLOCKSTORE_HXX
diff --git a/ucb/source/ucp/webdav/NeonPropFindRequest.cxx b/ucb/source/ucp/webdav/NeonPropFindRequest.cxx
index 6171d3fa0bfc..c69ab1d59a3a 100644
--- a/ucb/source/ucp/webdav/NeonPropFindRequest.cxx
+++ b/ucb/source/ucp/webdav/NeonPropFindRequest.cxx
@@ -30,14 +30,14 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"
-#include <osl/diagnose.h>
+
+#include "osl/diagnose.h"
+#include "rtl/strbuf.hxx"
#include "NeonTypes.hxx"
#include "DAVException.hxx"
#include "DAVProperties.hxx"
#include "NeonPropFindRequest.hxx"
-#ifndef _LINKSEQUENCE_HXX_
#include "LinkSequence.hxx"
-#endif
#include "LockSequence.hxx"
#include "LockEntrySequence.hxx"
#include "UCBDeadPropertyValue.hxx"
@@ -49,6 +49,40 @@ using namespace std;
using namespace webdav_ucp;
// -------------------------------------------------------------------
+namespace
+{
+ // strip "DAV:" namespace from XML snippets to avoid
+ // parser error (undeclared namespace) later on.
+ rtl::OString stripDavNamespace( const rtl::OString & in )
+ {
+ const rtl::OString inXML( in.toAsciiLowerCase() );
+
+ rtl::OStringBuffer buf;
+ sal_Int32 start = 0;
+ sal_Int32 end = inXML.indexOf( "dav:" );
+ while ( end != -1 )
+ {
+ if ( inXML[ end - 1 ] == '<' ||
+ inXML[ end - 1 ] == '/' )
+ {
+ // copy from original buffer - preserve case.
+ buf.append( in.copy( start, end - start ) );
+ }
+ else
+ {
+ // copy from original buffer - preserve case.
+ buf.append( in.copy( start, end - start + 4 ) );
+ }
+ start = end + 4;
+ end = inXML.indexOf( "dav:", start );
+ }
+ buf.append( inXML.copy( start ) );
+
+ return rtl::OString( buf.makeStringAndClear() );
+ }
+}
+
+// -------------------------------------------------------------------
extern "C" int NPFR_propfind_iter( void* userdata,
const NeonPropName* pname,
const char* value,
@@ -57,9 +91,9 @@ extern "C" int NPFR_propfind_iter( void* userdata,
/*
HTTP Response Status Classes:
- - 1: Informational - Request received, continuing process
+ - 1: Informational - Request received, continuing process
- - 2: Success - The action was successfully received,
+ - 2: Success - The action was successfully received,
understood, and accepted
- 3: Redirection - Further action must be taken in order to
@@ -79,18 +113,22 @@ extern "C" int NPFR_propfind_iter( void* userdata,
DAVPropertyValue thePropertyValue;
thePropertyValue.IsCaseSensitive = true;
+ OSL_ENSURE( pname->nspace, "NPFR_propfind_iter - No namespace!" );
+
DAVProperties::createUCBPropName( pname->nspace,
- pname->name,
- thePropertyValue.Name );
+ pname->name,
+ thePropertyValue.Name );
bool bHasValue = false;
if ( DAVProperties::isUCBDeadProperty( *pname ) )
{
// DAV dead property added by WebDAV UCP?
if ( UCBDeadPropertyValue::createFromXML(
- value, thePropertyValue.Value ) )
+ value, thePropertyValue.Value ) )
+ {
OSL_ENSURE( thePropertyValue.Value.hasValue(),
- "NeonPropFindRequest::propfind_iter - No value!" );
+ "NPFR_propfind_iter - No value!" );
bHasValue = true;
+ }
}
if ( !bHasValue )
@@ -103,12 +141,11 @@ extern "C" int NPFR_propfind_iter( void* userdata,
if ( aValue.getLength() )
{
aValue = aValue.toAsciiLowerCase();
- if (
- ( aValue.compareTo(
- RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 ) ||
- ( aValue.compareTo(
- RTL_CONSTASCII_STRINGPARAM( "<dav:collection" ) ) == 0 )
- )
+ if ( ( aValue.compareTo(
+ RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 ) ||
+ ( aValue.compareTo(
+ RTL_CONSTASCII_STRINGPARAM( "<dav:collection" ) ) == 0 )
+ )
{
thePropertyValue.Value
<<= OUString::createFromAscii( "collection" );
@@ -125,20 +162,23 @@ extern "C" int NPFR_propfind_iter( void* userdata,
pname->name, "supportedlock" ) == 0 )
{
Sequence< LockEntry > aEntries;
- LockEntrySequence::createFromXML( value, aEntries );
+ LockEntrySequence::createFromXML(
+ stripDavNamespace( value ), aEntries );
thePropertyValue.Value <<= aEntries;
}
else if ( rtl_str_compareIgnoreAsciiCase(
pname->name, "lockdiscovery" ) == 0 )
{
Sequence< Lock > aLocks;
- LockSequence::createFromXML( value, aLocks );
+ LockSequence::createFromXML(
+ stripDavNamespace( value ), aLocks );
thePropertyValue.Value <<= aLocks;
}
else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
{
Sequence< Link > aLinks;
- LinkSequence::createFromXML( value, aLinks );
+ LinkSequence::createFromXML(
+ stripDavNamespace( value ), aLinks );
thePropertyValue.Value <<= aLinks;
}
else
@@ -168,10 +208,10 @@ extern "C" void NPFR_propfind_results( void* userdata,
#if NEON_VERSION >= 0x0260
DAVResource theResource(
- OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
+ OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
#else
DAVResource theResource(
- OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
+ OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
#endif
ne_propset_iterate( set, NPFR_propfind_iter, &theResource );
@@ -210,10 +250,10 @@ extern "C" void NPFR_propnames_results( void* userdata,
// Create entry for the resource.
#if NEON_VERSION >= 0x0260
DAVResourceInfo theResource(
- OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
+ OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
#else
DAVResourceInfo theResource(
- OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
+ OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
#endif
// Fill entry.
@@ -247,7 +287,7 @@ NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
{
// Split fullname into namespace and name!
DAVProperties::createNeonPropName(
- inPropNames[ theIndex ], thePropNames[ theIndex ] );
+ inPropNames[ theIndex ], thePropNames[ theIndex ] );
}
thePropNames[ theIndex ].nspace = NULL;
thePropNames[ theIndex ].name = NULL;
@@ -288,7 +328,7 @@ NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
NeonPropFindRequest::NeonPropFindRequest(
HttpSession* inSession,
const char* inPath,
- const Depth inDepth,
+ const Depth inDepth,
std::vector< DAVResourceInfo > & ioResInfo,
int & nError )
{
diff --git a/ucb/source/ucp/webdav/NeonSession.cxx b/ucb/source/ucp/webdav/NeonSession.cxx
index b455ffebbb9b..c6cb5288099b 100644
--- a/ucb/source/ucp/webdav/NeonSession.cxx
+++ b/ucb/source/ucp/webdav/NeonSession.cxx
@@ -1,5 +1,4 @@
/*************************************************************************
- *
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
@@ -34,11 +33,12 @@
#include <hash_map>
#include <vector>
#include <string.h>
+#include "osl/diagnose.h"
+#include "osl/time.h"
#include <rtl/string.h>
#include <ne_socket.h>
#include <ne_auth.h>
#include <ne_redirect.h>
-#include <ne_locks.h>
#include <ne_ssl.h>
#include "libxml/parser.h"
#include "rtl/ustrbuf.hxx"
@@ -62,6 +62,7 @@
#include <com/sun/star/security/CertificateContainer.hpp>
#include <com/sun/star/security/XCertificateContainer.hpp>
#include <com/sun/star/task/XMasterPasswordHandling.hpp>
+#include <com/sun/star/ucb/Lock.hpp>
#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
using namespace com::sun::star;
@@ -119,10 +120,6 @@ typedef std::hash_map
RequestDataMap;
// -------------------------------------------------------------------
-// static members!
-bool NeonSession::m_bGlobalsInited = false;
-osl::Mutex NeonSession::m_aGlobalMutex;
-// -------------------------------------------------------------------
// Helper fuction
// -------------------------------------------------------------------
static sal_uInt16 makeStatusCode( const rtl::OUString & rStatusText )
@@ -197,14 +194,14 @@ extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
const char * inBuf,
size_t inLen )
{
- // neon calls this function with (inLen == 0)...
+ // neon sometimes calls this function with (inLen == 0)...
if ( inLen > 0 )
{
NeonRequestContext * pCtx
= static_cast< NeonRequestContext * >( inUserData );
rtl::Reference< NeonInputStream > xInputStream(
- pCtx->xInputStream);
+ pCtx->xInputStream );
if ( xInputStream.is() )
xInputStream->AddToStream( inBuf, inLen );
@@ -327,10 +324,11 @@ extern "C" int NeonSession_NeonAuth( void * inUserData,
bool bCanUseSystemCreds = false;
#ifdef NE_FEATURE_SSPI
- bCanUseSystemCreds = (attempt == 0) && // avoid endless loops
- ne_has_support( NE_FEATURE_SSPI ) && // Windows-only feature.
- ( ne_strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
- ( ne_strcasecmp( inAuthProtocol, "Negotiate" ) == 0 );
+ bCanUseSystemCreds
+ = (attempt == 0) && // avoid endless loops
+ ne_has_support( NE_FEATURE_SSPI ) && // Windows-only feature.
+ ( ( ne_strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
+ ( ne_strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
#endif
// #i97003# (tkr): Ask XMasterPasswordHandling if we should store the
@@ -342,7 +340,7 @@ extern "C" int NeonSession_NeonAuth( void * inUserData,
uno::Reference< task::XMasterPasswordHandling >(
theSession->getMSF()->createInstance(
rtl::OUString::createFromAscii(
- "com.sun.star.task.PasswordContainer" )),
+ "com.sun.star.task.PasswordContainer" ) ),
uno::UNO_QUERY );
}
catch ( uno::Exception const & )
@@ -406,7 +404,7 @@ namespace {
}
return sPart;
}
-}
+} // namespace
// -------------------------------------------------------------------
extern "C" int NeonSession_CertificationNotify( void *userdata,
@@ -445,7 +443,7 @@ extern "C" int NeonSession_CertificationNotify( void *userdata,
pSession->getHostName(), cert_subject ) );
if ( certificateContainer != security::CertificateContainerStatus_NOCERT )
- return
+ return
certificateContainer == security::CertificateContainerStatus_TRUSTED
? 0
: 1;
@@ -476,7 +474,7 @@ extern "C" int NeonSession_CertificationNotify( void *userdata,
rtl::OString sEECertB64( eeCertB64 );
- uno::Reference< com::sun::star::security::XCertificate > xEECert(
+ uno::Reference< security::XCertificate > xEECert(
xSecurityEnv->createCertificateFromAscii(
rtl::OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) ) );
@@ -617,36 +615,41 @@ extern "C" void NeonSession_PreSendRequest( ne_request * req,
}
}
- const DAVRequestHeaders & rHeaders
- = pSession->getRequestEnvironment().m_aRequestHeaders;
+ const DAVRequestHeaders & rHeaders
+ = pSession->getRequestEnvironment().m_aRequestHeaders;
- DAVRequestHeaders::const_iterator it1( rHeaders.begin() );
- const DAVRequestHeaders::const_iterator end1( rHeaders.end() );
+ DAVRequestHeaders::const_iterator it1( rHeaders.begin() );
+ const DAVRequestHeaders::const_iterator end1( rHeaders.end() );
- while ( it1 != end1 )
- {
- rtl::OString aHeader
- = rtl::OUStringToOString( (*it1).first,
- RTL_TEXTENCODING_UTF8 );
- rtl::OString aValue
- = rtl::OUStringToOString( (*it1).second,
- RTL_TEXTENCODING_UTF8 );
- ne_buffer_concat( headers, aHeader.getStr(), ": ",
- aValue.getStr(), EOL, NULL );
-
- ++it1;
+ while ( it1 != end1 )
+ {
+ rtl::OString aHeader
+ = rtl::OUStringToOString( (*it1).first,
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OString aValue
+ = rtl::OUStringToOString( (*it1).second,
+ RTL_TEXTENCODING_UTF8 );
+ ne_buffer_concat( headers, aHeader.getStr(), ": ",
+ aValue.getStr(), EOL, NULL );
+
+ ++it1;
+ }
}
}
-} // namespace
+// -------------------------------------------------------------------
+// static members!
+bool NeonSession::m_bGlobalsInited = false;
+osl::Mutex NeonSession::m_aGlobalMutex;
+NeonLockStore NeonSession::m_aNeonLockStore;
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
NeonSession::NeonSession(
- const rtl::Reference< DAVSessionFactory > & rSessionFactory,
- const rtl::OUString& inUri,
- const ucbhelper::InternetProxyDecider & rProxyDecider )
+ const rtl::Reference< DAVSessionFactory > & rSessionFactory,
+ const rtl::OUString& inUri,
+ const ucbhelper::InternetProxyDecider & rProxyDecider )
throw ( DAVException )
: DAVSession( rSessionFactory ),
m_pHttpSession( 0 ),
@@ -657,8 +660,6 @@ NeonSession::NeonSession(
m_aScheme = theUri.GetScheme();
m_aHostName = theUri.GetHost();
m_nPort = theUri.GetPort();
-
-// Init();
}
// -------------------------------------------------------------------
@@ -670,17 +671,17 @@ NeonSession::~NeonSession( )
{
ne_session_destroy( m_pHttpSession );
m_pHttpSession = 0;
- // Note: Uncomment the following if locking support is required
- /*
- if ( mNeonLockSession != NULL )
- {
- ne_lock_unregister( mNeonLockSession );
- mNeonLockSession = NULL;
- }
- */
}
+ delete static_cast< RequestDataMap * >( m_pRequestData );
+}
- delete static_cast<RequestDataMap*>(m_pRequestData);
+// -------------------------------------------------------------------
+void NeonSession::Init( const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+ m_aEnv = rEnv;
+ Init();
}
// -------------------------------------------------------------------
@@ -693,7 +694,7 @@ void NeonSession::Init()
if ( m_pHttpSession == 0 )
{
- // Ensure that Neon sockets are initialize
+ // Ensure that Neon sockets are initialized
// --> tkr #151111# crashed if copy and pasted pictures from the internet
// ne_sock_init() was executed by two threads at the same time.
@@ -705,9 +706,18 @@ void NeonSession::Init()
throw DAVException( DAVException::DAV_SESSION_CREATE,
NeonUri::makeConnectionEndPointString(
m_aHostName, m_nPort ) );
+
// #122205# - libxml2 needs to be initialized once if used by
// multithreaded programs like OOo.
xmlInitParser();
+#if 0
+ // for more debug flags see ne_utils.h; NE_DEBUGGING must be defined
+ // while compiling neon in order to actually activate neon debug
+ // output.
+ ne_debug_init( stderr,
+ /*NE_DBG_HTTP | NE_DBG_XML | NE_DBG_XMLPARSE |*/
+ NE_DBG_LOCKS | NE_DBG_FLUSH );
+#endif
m_bGlobalsInited = true;
}
@@ -747,30 +757,29 @@ void NeonSession::Init()
// to the session
m_pHttpSession = ne_session_create(
- rtl::OUStringToOString( m_aScheme,
- RTL_TEXTENCODING_UTF8 ).getStr(),
- /* theUri.GetUserInfo(),
- @@@ for FTP via HTTP proxy, but not supported by Neon */
- rtl::OUStringToOString( m_aHostName,
- RTL_TEXTENCODING_UTF8 ).getStr(),
- m_nPort );
+ rtl::OUStringToOString( m_aScheme,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ /* theUri.GetUserInfo(),
+ @@@ for FTP via HTTP proxy, but not supported by Neon */
+ rtl::OUStringToOString( m_aHostName,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ m_nPort );
if ( m_pHttpSession == 0 )
throw DAVException( DAVException::DAV_SESSION_CREATE,
NeonUri::makeConnectionEndPointString(
m_aHostName, m_nPort ) );
- if (m_aScheme.equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
- "https" ) ) ) )
- {
-
- // Get all trusted certificates from key store
-
-
+ // Register the session with the lock store
+ m_aNeonLockStore.registerSession( m_pHttpSession );
+ if ( m_aScheme.equalsIgnoreAsciiCase(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ) )
+ {
// Set a failure callback for certificate check
- ne_ssl_set_verify( m_pHttpSession, NeonSession_CertificationNotify, this);
- }
+ ne_ssl_set_verify(
+ m_pHttpSession, NeonSession_CertificationNotify, this);
+ }
// Add hooks (i.e. for adding additional headers to the request)
@@ -815,27 +824,20 @@ void NeonSession::Init()
if ( m_aProxyName.getLength() )
{
ne_session_proxy( m_pHttpSession,
- rtl::OUStringToOString( m_aProxyName,
- RTL_TEXTENCODING_UTF8 )
- .getStr(),
+ rtl::OUStringToOString(
+ m_aProxyName,
+ RTL_TEXTENCODING_UTF8 ).getStr(),
m_nProxyPort );
}
- // Note: Uncomment the following if locking support is required
- /*
- mNeonLockSession = ne_lock_register( m_pHttpSession );
-
- if ( mNeonLockSession == NULL )
- throw DAVException( DAVException::DAV_SESSION_CREATE,
- theUri::makeConnectionEndPointString() );
- */
-
// Register for redirects.
ne_redirect_register( m_pHttpSession );
// authentication callbacks.
- ne_add_server_auth( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
- ne_add_proxy_auth ( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
+ ne_add_server_auth(
+ m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
+ ne_add_proxy_auth(
+ m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
}
}
@@ -870,15 +872,13 @@ sal_Bool NeonSession::UsesProxy()
// OPTIONS
// -------------------------------------------------------------------
void NeonSession::OPTIONS( const rtl::OUString & inPath,
- DAVCapabilities & outCapabilities,
+ DAVCapabilities & outCapabilities,
const DAVRequestEnvironment & rEnv )
throw( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
HttpServerCapabilities servercaps;
memset( &servercaps, 0, sizeof( servercaps ) );
@@ -887,7 +887,8 @@ void NeonSession::OPTIONS( const rtl::OUString & inPath,
rtl::OUStringToOString(
inPath, RTL_TEXTENCODING_UTF8 ),
&servercaps );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
outCapabilities.class1 = !!servercaps.dav_class1;
outCapabilities.class2 = !!servercaps.dav_class2;
@@ -897,60 +898,58 @@ void NeonSession::OPTIONS( const rtl::OUString & inPath,
// -------------------------------------------------------------------
// PROPFIND - allprop & named
// -------------------------------------------------------------------
-void NeonSession::PROPFIND( const rtl::OUString & inPath,
- const Depth inDepth,
+void NeonSession::PROPFIND( const rtl::OUString & inPath,
+ const Depth inDepth,
const std::vector< rtl::OUString > & inPropNames,
- std::vector< DAVResource > & ioResources,
+ std::vector< DAVResource > & ioResources,
const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
int theRetVal = NE_OK;
NeonPropFindRequest theRequest( m_pHttpSession,
rtl::OUStringToOString(
inPath, RTL_TEXTENCODING_UTF8 ),
- inDepth,
- inPropNames,
- ioResources,
- theRetVal );
- HandleError( theRetVal );
+ inDepth,
+ inPropNames,
+ ioResources,
+ theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
// PROPFIND - propnames
// -------------------------------------------------------------------
-void NeonSession::PROPFIND( const rtl::OUString & inPath,
- const Depth inDepth,
- std::vector< DAVResourceInfo >& ioResInfo,
+void NeonSession::PROPFIND( const rtl::OUString & inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo > & ioResInfo,
const DAVRequestEnvironment & rEnv )
throw( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
int theRetVal = NE_OK;
NeonPropFindRequest theRequest( m_pHttpSession,
rtl::OUStringToOString(
inPath, RTL_TEXTENCODING_UTF8 ),
- inDepth,
- ioResInfo,
- theRetVal );
- HandleError( theRetVal );
+ inDepth,
+ ioResInfo,
+ theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
// PROPPATCH
// -------------------------------------------------------------------
-void NeonSession::PROPPATCH( const rtl::OUString & inPath,
- const std::vector< ProppatchValue > & inValues,
+void NeonSession::PROPPATCH( const rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
const DAVRequestEnvironment & rEnv )
throw( DAVException )
{
@@ -974,9 +973,10 @@ void NeonSession::PROPPATCH( const rtl::OUString & inPath,
executable w ( #ifndef WIN32 )
All dead properties are of course writable.
- */
+ */
int theRetVal = NE_OK;
+
int n; // for the "for" loop
// Generate the list of properties we want to set.
@@ -1000,8 +1000,8 @@ void NeonSession::PROPPATCH( const rtl::OUString & inPath,
if ( DAVProperties::isUCBDeadProperty( *pName ) )
{
// DAV dead property added by WebDAV UCP?
- if ( !UCBDeadPropertyValue::toXML(
- rValue.value, aStringValue ) )
+ if ( !UCBDeadPropertyValue::toXML( rValue.value,
+ aStringValue ) )
{
// Error!
pItems[ n ].value = 0;
@@ -1015,7 +1015,7 @@ void NeonSession::PROPPATCH( const rtl::OUString & inPath,
// complex properties...
if ( rValue.name == DAVProperties::SOURCE )
{
- uno::Sequence< ::com::sun::star::ucb::Link > aLinks;
+ uno::Sequence< ucb::Link > aLinks;
if ( rValue.value >>= aLinks )
{
LinkSequence::toXML( aLinks, aStringValue );
@@ -1055,9 +1055,7 @@ void NeonSession::PROPPATCH( const rtl::OUString & inPath,
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
pItems[ n ].name = 0;
@@ -1076,7 +1074,7 @@ void NeonSession::PROPPATCH( const rtl::OUString & inPath,
delete [] pItems;
- HandleError( theRetVal );
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
@@ -1090,9 +1088,7 @@ void NeonSession::HEAD( const ::rtl::OUString & inPath,
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
int theRetVal = NE_OK;
NeonHeadRequest theRequest( m_pHttpSession,
@@ -1100,7 +1096,8 @@ void NeonSession::HEAD( const ::rtl::OUString & inPath,
inHeaderNames,
ioResource,
theRetVal );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
@@ -1108,14 +1105,12 @@ void NeonSession::HEAD( const ::rtl::OUString & inPath,
// -------------------------------------------------------------------
uno::Reference< io::XInputStream >
NeonSession::GET( const rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
NeonRequestContext aCtx( xInputStream );
@@ -1125,23 +1120,23 @@ NeonSession::GET( const rtl::OUString & inPath,
NeonSession_ResponseBlockReader,
false,
&aCtx );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
+
return uno::Reference< io::XInputStream >( xInputStream.get() );
}
// -------------------------------------------------------------------
// GET
// -------------------------------------------------------------------
-void NeonSession::GET( const rtl::OUString & inPath,
+void NeonSession::GET( const rtl::OUString & inPath,
uno::Reference< io::XOutputStream > & ioOutputStream,
const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
NeonRequestContext aCtx( ioOutputStream );
int theRetVal = GET( m_pHttpSession,
@@ -1150,7 +1145,8 @@ void NeonSession::GET( const rtl::OUString & inPath,
NeonSession_ResponseBlockWriter,
false,
&aCtx );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
@@ -1158,16 +1154,14 @@ void NeonSession::GET( const rtl::OUString & inPath,
// -------------------------------------------------------------------
uno::Reference< io::XInputStream >
NeonSession::GET( const rtl::OUString & inPath,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
ioResource.uri = inPath;
ioResource.properties.clear();
@@ -1180,7 +1174,9 @@ NeonSession::GET( const rtl::OUString & inPath,
NeonSession_ResponseBlockReader,
true,
&aCtx );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
+
return uno::Reference< io::XInputStream >( xInputStream.get() );
}
@@ -1188,17 +1184,15 @@ NeonSession::GET( const rtl::OUString & inPath,
// GET
// -------------------------------------------------------------------
void NeonSession::GET( const rtl::OUString & inPath,
- uno::Reference< io::XOutputStream > & ioOutputStream,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
+ uno::Reference< io::XOutputStream > & ioOutputStream,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
ioResource.uri = inPath;
ioResource.properties.clear();
@@ -1210,27 +1204,26 @@ void NeonSession::GET( const rtl::OUString & inPath,
NeonSession_ResponseBlockWriter,
true,
&aCtx );
- HandleError( theRetVal );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
// PUT
// -------------------------------------------------------------------
-void NeonSession::PUT( const rtl::OUString & inPath,
+void NeonSession::PUT( const rtl::OUString & inPath,
const uno::Reference< io::XInputStream > & inInputStream,
const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
-
uno::Sequence< sal_Int8 > aDataToSend;
if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
throw DAVException( DAVException::DAV_INVALID_ARG );
+ Init( rEnv );
+
int theRetVal = PUT( m_pHttpSession,
rtl::OUStringToOString(
inPath, RTL_TEXTENCODING_UTF8 ),
@@ -1238,7 +1231,7 @@ void NeonSession::PUT( const rtl::OUString & inPath,
aDataToSend.getConstArray() ),
aDataToSend.getLength() );
- HandleError( theRetVal );
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
@@ -1246,10 +1239,10 @@ void NeonSession::PUT( const rtl::OUString & inPath,
// -------------------------------------------------------------------
uno::Reference< io::XInputStream >
NeonSession::POST( const rtl::OUString & inPath,
- const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const uno::Reference< io::XInputStream > & inInputStream,
- const DAVRequestEnvironment & rEnv )
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const uno::Reference< io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
@@ -1258,15 +1251,13 @@ NeonSession::POST( const rtl::OUString & inPath,
if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
throw DAVException( DAVException::DAV_INVALID_ARG );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
NeonRequestContext aCtx( xInputStream );
int theRetVal = POST( m_pHttpSession,
rtl::OUStringToOString(
- inPath, RTL_TEXTENCODING_UTF8 ),
+ inPath, RTL_TEXTENCODING_UTF8 ),
reinterpret_cast< const char * >(
aDataToSend.getConstArray() ),
NeonSession_ResponseBlockReader,
@@ -1274,7 +1265,8 @@ NeonSession::POST( const rtl::OUString & inPath,
rContentType,
rReferer );
- HandleError( theRetVal );
+ HandleError( theRetVal, inPath, rEnv );
+
return uno::Reference< io::XInputStream >( xInputStream.get() );
}
@@ -1295,9 +1287,7 @@ void NeonSession::POST( const rtl::OUString & inPath,
if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
throw DAVException( DAVException::DAV_INVALID_ARG );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
NeonRequestContext aCtx( oOutputStream );
int theRetVal = POST( m_pHttpSession,
@@ -1310,17 +1300,7 @@ void NeonSession::POST( const rtl::OUString & inPath,
rContentType,
rReferer );
- HandleError( theRetVal );
-}
-
-// -------------------------------------------------------------------
-// ABORT
-// -------------------------------------------------------------------
-void NeonSession::ABORT()
- throw ( DAVException )
-{
- if (NULL !=m_pHttpSession)
- ne_close_connection(m_pHttpSession);
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
@@ -1332,30 +1312,27 @@ void NeonSession::MKCOL( const rtl::OUString & inPath,
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
int theRetVal = ne_mkcol( m_pHttpSession,
rtl::OUStringToOString(
- inPath, RTL_TEXTENCODING_UTF8 ) );
- HandleError( theRetVal );
+ inPath, RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
// COPY
// -------------------------------------------------------------------
-void NeonSession::COPY( const rtl::OUString & inSourceURL,
- const rtl::OUString & inDestinationURL,
+void NeonSession::COPY( const rtl::OUString & inSourceURL,
+ const rtl::OUString & inDestinationURL,
const DAVRequestEnvironment & rEnv,
- sal_Bool inOverWrite )
+ sal_Bool inOverWrite )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
NeonUri theSourceUri( inSourceURL );
NeonUri theDestinationUri( inDestinationURL );
@@ -1364,12 +1341,13 @@ void NeonSession::COPY( const rtl::OUString & inSourceURL,
inOverWrite ? 1 : 0,
NE_DEPTH_INFINITE,
rtl::OUStringToOString(
- theSourceUri.GetPath(),
- RTL_TEXTENCODING_UTF8 ),
+ theSourceUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ),
rtl::OUStringToOString(
- theDestinationUri.GetPath(),
- RTL_TEXTENCODING_UTF8 ) );
- HandleError( theRetVal );
+ theDestinationUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inSourceURL, rEnv );
}
// -------------------------------------------------------------------
@@ -1383,21 +1361,20 @@ void NeonSession::MOVE( const rtl::OUString & inSourceURL,
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
NeonUri theSourceUri( inSourceURL );
NeonUri theDestinationUri( inDestinationURL );
int theRetVal = ne_move( m_pHttpSession,
inOverWrite ? 1 : 0,
rtl::OUStringToOString(
- theSourceUri.GetPath(),
- RTL_TEXTENCODING_UTF8 ),
+ theSourceUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ),
rtl::OUStringToOString(
- theDestinationUri.GetPath(),
- RTL_TEXTENCODING_UTF8 ) );
- HandleError( theRetVal );
+ theDestinationUri.GetPath(),
+ RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inSourceURL, rEnv );
}
// -------------------------------------------------------------------
@@ -1409,53 +1386,279 @@ void NeonSession::DESTROY( const rtl::OUString & inPath,
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
-
- m_aEnv = rEnv;
+ Init( rEnv );
int theRetVal = ne_delete( m_pHttpSession,
rtl::OUStringToOString(
- inPath, RTL_TEXTENCODING_UTF8 ) );
- HandleError( theRetVal );
+ inPath, RTL_TEXTENCODING_UTF8 ) );
+
+ HandleError( theRetVal, inPath, rEnv );
}
// -------------------------------------------------------------------
-// LOCK
+namespace
+{
+ sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
+ int timeout )
+ {
+ TimeValue aEnd;
+ osl_getSystemTime( &aEnd );
+
+ // Try to estimate a safe absolute time for sending the
+ // lock refresh request.
+ sal_Int32 lastChanceToSendRefreshRequest = -1;
+ if ( timeout != NE_TIMEOUT_INFINITE )
+ {
+ sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
+ if ( calltime <= timeout )
+ {
+ lastChanceToSendRefreshRequest
+ = aEnd.Seconds + timeout - calltime;
+ }
+ else
+ {
+ OSL_TRACE( "No chance to refresh lock before timeout!" );
+ }
+ }
+ return lastChanceToSendRefreshRequest;
+ }
+
+} // namespace
+
+// -------------------------------------------------------------------
+// LOCK (set new lock)
// -------------------------------------------------------------------
-// Note: Uncomment the following if locking support is required
-/*
-void NeonSession::LOCK( const Lock & inLock,
+void NeonSession::LOCK( const ::rtl::OUString & inPath,
+ ucb::Lock & rLock,
const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
+ Init( rEnv );
- m_aEnv = rEnv;
+ /* Create a depth zero, exclusive write lock, with default timeout
+ * (allowing a server to pick a default). token, owner and uri are
+ * unset. */
+ NeonLock * theLock = ne_lock_create();
+
+ // Set the lock uri
+ ne_uri aUri;
+ ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ &aUri );
+ theLock->uri = aUri;
+
+ // Set the lock depth
+ switch( rLock.Depth )
+ {
+ case ucb::LockDepth_ZERO:
+ theLock->depth = NE_DEPTH_ZERO;
+ break;
+ case ucb::LockDepth_ONE:
+ theLock->depth = NE_DEPTH_ONE;
+ break;
+ case ucb::LockDepth_INFINITY:
+ theLock->depth = NE_DEPTH_INFINITE;
+ break;
+ default:
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ }
+
+ // Set the lock scope
+ switch ( rLock.Scope )
+ {
+ case ucb::LockScope_EXCLUSIVE:
+ theLock->scope = ne_lockscope_exclusive;
+ break;
+ case ucb::LockScope_SHARED:
+ theLock->scope = ne_lockscope_shared;
+ break;
+ default:
+ throw DAVException( DAVException::DAV_INVALID_ARG );
+ break;
+ }
+
+ // Set the lock timeout
+ theLock->timeout = (long)rLock.Timeout;
+
+ // Set the lock owner
+ rtl::OUString aValue;
+ rLock.Owner >>= aValue;
+ theLock->owner =
+ ne_strdup( rtl::OUStringToOString( aValue,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ int theRetVal = ne_lock( m_pHttpSession, theLock );
+
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.addLock( theLock,
+ this,
+ lastChanceToSendRefreshRequest(
+ startCall, theLock->timeout ) );
+
+ uno::Sequence< rtl::OUString > aTokens( 1 );
+ aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token );
+ rLock.LockTokens = aTokens;
+
+ OSL_TRACE( "NeonSession::LOCK: created lock for %s. token: %s",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr(),
+ theLock->token );
+ }
+ else
+ {
+ ne_lock_destroy( theLock );
+
+ OSL_TRACE( "NeonSession::LOCK: obtaining lock for %s failed!",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// LOCK (refresh existing lock)
+// -------------------------------------------------------------------
+sal_Int64 NeonSession::LOCK( const ::rtl::OUString & inPath,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+ // Try to get the neon lock from lock store
+ NeonLock * theLock
+ = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
+ if ( !theLock )
+ throw DAVException( DAVException::DAV_NOT_LOCKED );
+
+ Init( rEnv );
+
+ // refresh existing lock.
+ theLock->timeout = nTimeout;
- Lockit( inLock, true );
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
+
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.updateLock( theLock,
+ lastChanceToSendRefreshRequest(
+ startCall, theLock->timeout ) );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+
+ return theLock->timeout;
+}
+
+// -------------------------------------------------------------------
+// LOCK (refresh existing lock)
+// -------------------------------------------------------------------
+bool NeonSession::LOCK( NeonLock * pLock,
+ sal_Int32 & rlastChanceToSendRefreshRequest )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+#if OSL_DEBUG_LEVEL > 0
+ char * p = ne_uri_unparse( &(pLock->uri) );
+ OSL_TRACE( "NeonSession::LOCK: Refreshing lock for %s.", p );
+ ne_free( p );
+#endif
+
+ // refresh existing lock.
+
+ TimeValue startCall;
+ osl_getSystemTime( &startCall );
+
+ if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK )
+ {
+ rlastChanceToSendRefreshRequest
+ = lastChanceToSendRefreshRequest( startCall, pLock->timeout );
+
+ OSL_TRACE( "Lock successfully refreshed." );
+ return true;
+ }
+ else
+ {
+ OSL_TRACE( "Lock not refreshed!" );
+ return false;
+ }
}
-*/
// -------------------------------------------------------------------
// UNLOCK
// -------------------------------------------------------------------
-// Note: Uncomment the following if locking support is required
-/*
-void NeonSession::UNLOCK( const Lock & inLock,
+void NeonSession::UNLOCK( const ::rtl::OUString & inPath,
const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
osl::Guard< osl::Mutex > theGuard( m_aMutex );
- Init();
+ // get the neon lock from lock store
+ NeonLock * theLock
+ = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
+ if ( !theLock )
+ throw DAVException( DAVException::DAV_NOT_LOCKED );
- m_aEnv = rEnv;
+ Init( rEnv );
+
+ int theRetVal = ne_unlock( m_pHttpSession, theLock );
- Lockit( inLock, false );
+ if ( theRetVal == NE_OK )
+ {
+ m_aNeonLockStore.removeLock( theLock );
+ ne_lock_destroy( theLock );
+ }
+ else
+ {
+ OSL_TRACE( "NeonSession::UNLOCK: unlocking of %s failed.",
+ rtl::OUStringToOString( makeAbsoluteURL( inPath ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ HandleError( theRetVal, inPath, rEnv );
+}
+
+// -------------------------------------------------------------------
+// UNLOCK
+// -------------------------------------------------------------------
+bool NeonSession::UNLOCK( NeonLock * pLock )
+{
+ osl::Guard< osl::Mutex > theGuard( m_aMutex );
+
+#if OSL_DEBUG_LEVEL > 0
+ char * p = ne_uri_unparse( &(pLock->uri) );
+ OSL_TRACE( "NeonSession::UNLOCK: Unlocking %s.", p );
+ ne_free( p );
+#endif
+
+ if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK )
+ {
+ OSL_TRACE( "UNLOCK succeeded." );
+ return true;
+ }
+ else
+ {
+ OSL_TRACE( "UNLOCK failed!" );
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+void NeonSession::abort()
+ throw ( DAVException )
+{
+ if ( m_pHttpSession )
+ ne_close_connection( m_pHttpSession );
}
-*/
// -------------------------------------------------------------------
const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
@@ -1476,10 +1679,95 @@ const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
}
// -------------------------------------------------------------------
+namespace {
+
+bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
+ const char * token )
+{
+ for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
+ {
+ const uno::Sequence< rtl::OUString > & rTokens
+ = rLocks[ n ].LockTokens;
+ for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
+ {
+ if ( rTokens[ m ].equalsAscii( token ) )
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+// -------------------------------------------------------------------
+bool NeonSession::removeExpiredLocktoken( const rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv )
+{
+ NeonLock * theLock = m_aNeonLockStore.findByUri( inURL );
+ if ( !theLock )
+ return false;
+
+ // do a lockdiscovery to check whether this lock is still valid.
+ try
+ {
+ // @@@ Alternative: use ne_lock_discover() => less overhead
+
+ std::vector< DAVResource > aResources;
+ std::vector< rtl::OUString > aPropNames;
+ aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
+
+ PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
+
+ if ( aResources.size() == 0 )
+ return false;
+
+ std::vector< DAVPropertyValue >::const_iterator it
+ = aResources[ 0 ].properties.begin();
+ std::vector< DAVPropertyValue >::const_iterator end
+ = aResources[ 0 ].properties.end();
+
+ while ( it != end )
+ {
+ if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
+ {
+ uno::Sequence< ucb::Lock > aLocks;
+ if ( !( (*it).Value >>= aLocks ) )
+ return false;
+
+ if ( !containsLocktoken( aLocks, theLock->token ) )
+ {
+ // expired!
+
+ OSL_TRACE( "NeonSession::removeExpiredLocktoken: Removing "
+ " expired lock token for %s. token: %s",
+ rtl::OUStringToOString( inURL,
+ RTL_TEXTENCODING_UTF8 )
+ .getStr(),
+ theLock->token );
+
+ m_aNeonLockStore.removeLock( theLock );
+ ne_lock_destroy( theLock );
+ return true;
+ }
+ // still valid.
+ return false;
+ }
+ ++it;
+ }
+ }
+ catch ( DAVException const & )
+ {
+ }
+ return false;
+}
+
+// -------------------------------------------------------------------
// HandleError
// Common Error Handler
// -------------------------------------------------------------------
-void NeonSession::HandleError( int nError )
+void NeonSession::HandleError( int nError,
+ const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
throw ( DAVException )
{
m_aEnv = DAVRequestEnvironment();
@@ -1488,60 +1776,86 @@ void NeonSession::HandleError( int nError )
switch ( nError )
{
case NE_OK:
- // Cleanup.
return;
case NE_ERROR: // Generic error
{
rtl::OUString aText = rtl::OUString::createFromAscii(
- ne_get_error( m_pHttpSession ) );
- throw DAVException( DAVException::DAV_HTTP_ERROR,
- aText,
- makeStatusCode( aText ) );
- }
+ ne_get_error( m_pHttpSession ) );
+ sal_uInt16 code = makeStatusCode( aText );
+
+ if ( code == SC_LOCKED )
+ {
+ if ( m_aNeonLockStore.findByUri(
+ makeAbsoluteURL( inPath ) ) == 0 )
+ {
+ // locked by 3rd party
+ throw DAVException( DAVException::DAV_LOCKED );
+ }
+ else
+ {
+ // locked by ourself
+ throw DAVException( DAVException::DAV_LOCKED_SELF );
+ }
+ }
+
+ // Special handling for 400 and 412 status codes, which may indicate
+ // that a lock previously obtained by us has been released meanwhile
+ // by the server. Unfortunately, RFC is not clear at this point,
+ // thus server implementations behave different...
+ else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
+ {
+ if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
+ throw DAVException( DAVException::DAV_LOCK_EXPIRED );
+ }
+ else
+ {
+ throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
+ }
+ }
case NE_LOOKUP: // Name lookup failed.
throw DAVException( DAVException::DAV_HTTP_LOOKUP,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_AUTH: // User authentication failed on server
throw DAVException( DAVException::DAV_HTTP_AUTH,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_PROXYAUTH: // User authentication failed on proxy
throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
NeonUri::makeConnectionEndPointString(
- m_aProxyName, m_nProxyPort ) );
+ m_aProxyName, m_nProxyPort ) );
case NE_CONNECT: // Could not connect to server
throw DAVException( DAVException::DAV_HTTP_CONNECT,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_TIMEOUT: // Connection timed out
throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_FAILED: // The precondition failed
throw DAVException( DAVException::DAV_HTTP_FAILED,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_RETRY: // Retry request (ne_end_request ONLY)
throw DAVException( DAVException::DAV_HTTP_RETRY,
NeonUri::makeConnectionEndPointString(
- m_aHostName, m_nPort ) );
+ m_aHostName, m_nPort ) );
case NE_REDIRECT:
{
NeonUri aUri( ne_redirect_location( m_pHttpSession ) );
throw DAVException(
- DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
+ DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
}
- default:
+ default:
{
OSL_TRACE( "NeonSession::HandleError : Unknown Neon error code!" );
throw DAVException( DAVException::DAV_HTTP_ERROR,
@@ -1551,78 +1865,6 @@ void NeonSession::HandleError( int nError )
}
}
-// Note: Uncomment the following if locking support is required
-/*
-void NeonSession::Lockit( const Lock & inLock, bool inLockit )
- throw ( DAVException )
-{
- osl::Guard< osl::Mutex > theGuard( m_aMutex );
-
- // Create the neon lock
- NeonLock * theLock = new NeonLock;
- int theRetVal;
-
- // Set the lock uri
- NeonUri theUri( inLock.uri );
- theLock->uri = const_cast< char * >
- ( rtl::OUStringToOString(
- theUri.GetPath(), RTL_TEXTENCODING_UTF8 ).getStr() );
-
- if ( inLockit )
- {
- // Set the lock depth
- switch( inLock.depth )
- {
- case DAVZERO:
- case DAVINFINITY:
- theLock->depth = int ( inLock.depth );
- break;
- default:
- throw DAVException( DAVException::DAV_INVALID_ARG );
- break;
- }
-
- // Set the lock scope
- switch ( inLock.scope )
- {
- case EXCLUSIVE:
- theLock->scope = ne_lockscope_exclusive;
- break;
- case SHARED:
- theLock->scope = ne_lockscope_shared;
- break;
- default:
- throw DAVException( DAVException::DAV_INVALID_ARG );
- break;
- }
-
- // Set the lock owner
- const char * theOwner = rtl::OUStringToOString( inLock.owner,
- RTL_TEXTENCODING_UTF8 );
- theLock->owner = const_cast< char * > ( theOwner );
-
- // Set the lock timeout
- // Note: Neon ignores the timeout
- //theLock->timeout = inLock.timeout;
-
- theRetVal = ne_lock( m_pHttpSession, theLock );
- }
- else
- {
-
- // Set the lock token
- rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ];
- theLock->token = const_cast< char * >
- ( rtl::OUStringToOString(
- theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
-
- theRetVal = ne_unlock( m_pHttpSession, theLock );
- }
-
- HandleError( theRetVal );
-}
-*/
-
// -------------------------------------------------------------------
namespace {
@@ -1699,7 +1941,8 @@ int NeonSession::GET( ne_session * sess,
#if NEON_VERSION < 0x0250
if ( getheaders )
- ne_add_response_header_catcher( req, runResponseHeaderHandler, userdata );
+ ne_add_response_header_catcher(
+ req, runResponseHeaderHandler, userdata );
#endif
ne_add_response_body_reader( req, ne_accept_2xx, reader, userdata );
@@ -1708,13 +1951,12 @@ int NeonSession::GET( ne_session * sess,
#if NEON_VERSION >= 0x0250
if ( getheaders )
{
- while ((cursor = ne_response_header_iterate(req, cursor, &name, &value))
- != NULL)
+ while ( ( cursor = ne_response_header_iterate(
+ req, cursor, &name, &value ) ) != NULL )
{
char buffer[8192];
ne_snprintf(buffer, sizeof buffer, "%s: %s", name, value);
-
runResponseHeaderHandler(userdata, buffer);
}
}
@@ -1809,10 +2051,11 @@ int NeonSession::POST( ne_session * sess,
// -------------------------------------------------------------------
// static
-bool NeonSession::getDataFromInputStream(
- const uno::Reference< io::XInputStream > & xStream,
- uno::Sequence< sal_Int8 > & rData,
- bool bAppendTrailingZeroByte )
+bool
+NeonSession::getDataFromInputStream(
+ const uno::Reference< io::XInputStream > & xStream,
+ uno::Sequence< sal_Int8 > & rData,
+ bool bAppendTrailingZeroByte )
{
if ( xStream.is() )
{
@@ -1895,32 +2138,56 @@ bool NeonSession::getDataFromInputStream(
}
return false;
}
-// -------------------------------------------------------------------
-//static
-
-NeonSession::Map NeonSession::certMap;
// ---------------------------------------------------------------------
sal_Bool
-NeonSession::isDomainMatch( rtl::OUString certHostName)
+NeonSession::isDomainMatch( rtl::OUString certHostName )
{
rtl::OUString hostName = getHostName();
- if (hostName.equalsIgnoreAsciiCase( certHostName ))
+ if (hostName.equalsIgnoreAsciiCase( certHostName ) )
return sal_True;
-
-
- if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && hostName.getLength() >= certHostName.getLength() )
+ if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
+ hostName.getLength() >= certHostName.getLength() )
{
rtl::OUString cmpStr = certHostName.copy( 1 );
- if ( hostName.matchIgnoreAsciiCase( cmpStr, hostName.getLength( ) - cmpStr.getLength()) )
+ if ( hostName.matchIgnoreAsciiCase(
+ cmpStr, hostName.getLength() - cmpStr.getLength() ) )
return sal_True;
-
}
-
return sal_False;
}
-
+// ---------------------------------------------------------------------
+rtl::OUString NeonSession::makeAbsoluteURL( rtl::OUString const & rURL ) const
+{
+ try
+ {
+ // Is URL relative or already absolute?
+ if ( rURL[ 0 ] != sal_Unicode( '/' ) )
+ {
+ // absolute.
+ return rtl::OUString( rURL );
+ }
+ else
+ {
+ ne_uri aUri;
+ memset( &aUri, 0, sizeof( aUri ) );
+
+ ne_fill_server_uri( m_pHttpSession, &aUri );
+ aUri.path
+ = ne_strdup( rtl::OUStringToOString(
+ rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+ NeonUri aNeonUri( &aUri );
+ ne_uri_free( &aUri );
+ return aNeonUri.GetURI();
+ }
+ }
+ catch ( DAVException const & )
+ {
+ }
+ // error.
+ return rtl::OUString();
+}
diff --git a/ucb/source/ucp/webdav/NeonSession.hxx b/ucb/source/ucp/webdav/NeonSession.hxx
index 263169ae452a..bb6bbbb8d3c3 100644
--- a/ucb/source/ucp/webdav/NeonSession.hxx
+++ b/ucb/source/ucp/webdav/NeonSession.hxx
@@ -35,10 +35,9 @@
#include <osl/mutex.hxx>
#include "DAVSession.hxx"
#include "NeonTypes.hxx"
+#include "NeonLockStore.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-using namespace com::sun::star;
-
namespace ucbhelper { class ProxyDecider; }
namespace webdav_ucp
@@ -51,236 +50,249 @@ namespace webdav_ucp
class NeonSession : public DAVSession
{
- private:
- osl::Mutex m_aMutex;
- static osl::Mutex m_aGlobalMutex;
- rtl::OUString m_aScheme;
- rtl::OUString m_aHostName;
- rtl::OUString m_aProxyName;
- sal_Int32 m_nPort;
- sal_Int32 m_nProxyPort;
- HttpSession * m_pHttpSession;
- void * m_pRequestData;
- const ucbhelper::InternetProxyDecider & m_rProxyDecider;
-
- // @@@ This should really be per-request data. But Neon currently
- // (0.23.5) has no interface for passing per-request user data.
- // Theoretically, a NeonSession instance could handle multiple requests
- // at a time --currently it doesn't. Thus this is not an issue at the
- // moment.
- DAVRequestEnvironment m_aEnv;
-
- // Note: Uncomment the following if locking support is required
- // NeonLockSession * mNeonLockSession;
-
- static bool m_bGlobalsInited;
-
- protected:
- virtual ~NeonSession();
-
- public:
- NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
- const rtl::OUString& inUri,
- const ucbhelper::InternetProxyDecider & rProxyDecider )
- throw ( DAVException );
-
- // DAVSession methods
- virtual sal_Bool CanUse( const ::rtl::OUString & inUri );
-
- virtual sal_Bool UsesProxy();
-
- const DAVRequestEnvironment & getRequestEnvironment() const
- { return m_aEnv; }
-
- virtual void
- OPTIONS( const ::rtl::OUString & inPath,
- DAVCapabilities & outCapabilities,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- // allprop & named
- virtual void
- PROPFIND( const ::rtl::OUString & inPath,
- const Depth inDepth,
- const std::vector< ::rtl::OUString > & inPropNames,
- std::vector< DAVResource > & ioResources,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- // propnames
- virtual void
- PROPFIND( const ::rtl::OUString & inPath,
- const Depth inDepth,
- std::vector< DAVResourceInfo >& ioResInfo,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void
- PROPPATCH( const ::rtl::OUString & inPath,
- const std::vector< ProppatchValue > & inValues,
- const DAVRequestEnvironment & rEnv )
- throw( DAVException );
-
- virtual void
- HEAD( const ::rtl::OUString & inPath,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
- throw( DAVException );
-
- virtual com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream >
- GET( const ::rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void
- GET( const ::rtl::OUString & inPath,
- com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & ioOutputStream,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream >
- GET( const ::rtl::OUString & inPath,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
+private:
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aScheme;
+ rtl::OUString m_aHostName;
+ rtl::OUString m_aProxyName;
+ sal_Int32 m_nPort;
+ sal_Int32 m_nProxyPort;
+ HttpSession * m_pHttpSession;
+ void * m_pRequestData;
+ const ucbhelper::InternetProxyDecider & m_rProxyDecider;
+
+ // @@@ This should really be per-request data. But Neon currently
+ // (0.23.5) has no interface for passing per-request user data.
+ // Theoretically, a NeonSession instance could handle multiple requests
+ // at a time --currently it doesn't. Thus this is not an issue at the
+ // moment.
+ DAVRequestEnvironment m_aEnv;
+
+ static bool m_bGlobalsInited;
+ static osl::Mutex m_aGlobalMutex;
+ static NeonLockStore m_aNeonLockStore;
+
+protected:
+ virtual ~NeonSession();
+
+public:
+ NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
+ const rtl::OUString& inUri,
+ const ucbhelper::InternetProxyDecider & rProxyDecider )
+ throw ( DAVException );
+
+ // DAVSession methods
+ virtual sal_Bool CanUse( const ::rtl::OUString & inUri );
+
+ virtual sal_Bool UsesProxy();
+
+ const DAVRequestEnvironment & getRequestEnvironment() const
+ { return m_aEnv; }
+
+ virtual void
+ OPTIONS( const ::rtl::OUString & inPath,
+ DAVCapabilities & outCapabilities,
const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void
- GET( const ::rtl::OUString & inPath,
- com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & ioOutputStream,
- const std::vector< ::rtl::OUString > & inHeaderNames,
- DAVResource & ioResource,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void
- PUT( const ::rtl::OUString & inPath,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & inInputStream,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream >
- POST( const rtl::OUString & inPath,
- const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & inInputStream,
+ throw ( DAVException );
+
+ // allprop & named
+ virtual void
+ PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ const std::vector< ::rtl::OUString > & inPropNames,
+ std::vector< DAVResource > & ioResources,
const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
+ throw ( DAVException );
- virtual void
- POST( const rtl::OUString & inPath,
- const rtl::OUString & rContentType,
- const rtl::OUString & rReferer,
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & inInputStream,
- com::sun::star::uno::Reference<
- com::sun::star::io::XOutputStream > & oOutputStream,
+ // propnames
+ virtual void
+ PROPFIND( const ::rtl::OUString & inPath,
+ const Depth inDepth,
+ std::vector< DAVResourceInfo >& ioResInfo,
const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
+ throw ( DAVException );
- virtual void
- MKCOL( const ::rtl::OUString & inPath,
+ virtual void
+ PROPPATCH( const ::rtl::OUString & inPath,
+ const std::vector< ProppatchValue > & inValues,
const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void
- COPY( const ::rtl::OUString & inSourceURL,
- const ::rtl::OUString & inDestinationURL,
- const DAVRequestEnvironment & rEnv,
- sal_Bool inOverWrite )
- throw ( DAVException );
-
- virtual void
- MOVE( const ::rtl::OUString & inSourceURL,
- const ::rtl::OUString & inDestinationURL,
- const DAVRequestEnvironment & rEnv,
- sal_Bool inOverWrite )
- throw ( DAVException );
-
- virtual void DESTROY( const ::rtl::OUString & inPath,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void ABORT()
- throw ( DAVException );
-
- // Note: Uncomment the following if locking support is required
- /*
- virtual void LOCK (const Lock & inLock,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
-
- virtual void UNLOCK (const Lock & inLock,
- const DAVRequestEnvironment & rEnv )
- throw ( DAVException );
- */
-
- // helpers
- const rtl::OUString & getHostName() const { return m_aHostName; }
-
- const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF() { return m_xFactory->getServiceFactory(); }
-
- const void * getRequestData() const { return m_pRequestData; }
-
- sal_Bool isDomainMatch( rtl::OUString certHostName );
-
- private:
- // Initialise "Neon sockets"
- void Init( void )
- throw ( DAVException );
-
- void HandleError( int nError )
- throw ( DAVException );
-
- const ucbhelper::InternetProxyServer & getProxySettings() const;
-
- // Note: Uncomment the following if locking support is required
- // void Lockit( const Lock & inLock, bool inLockit )
- // throw ( DAVException );
-
- // low level GET implementation, used by public GET implementations
- static int GET( ne_session * sess,
- const char * uri,
- ne_block_reader reader,
- bool getheaders,
- void * userdata );
-
- // Buffer-based PUT implementation. Neon only has file descriptor-
- // based API.
- static int PUT( ne_session * sess,
- const char * uri,
- const char * buffer,
- size_t size );
-
- // Buffer-based POST implementation. Neon only has file descriptor-
- // based API.
- int POST( ne_session * sess,
- const char * uri,
- const char * buffer,
- ne_block_reader reader,
- void * userdata,
- const rtl::OUString & rContentType,
- const rtl::OUString & rReferer );
-
- // Helper: XInputStream -> Sequence< sal_Int8 >
- static bool getDataFromInputStream(
- const com::sun::star::uno::Reference<
- com::sun::star::io::XInputStream > & xStream,
- com::sun::star::uno::Sequence< sal_Int8 > & rData,
- bool bAppendTrailingZeroByte );
-
- typedef std::map< ::rtl::OUString, ::rtl::OUString > Map;
- static Map certMap;
+ throw ( DAVException );
+
+ virtual void
+ HEAD( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & ioOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ GET( const ::rtl::OUString & inPath,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ GET( const ::rtl::OUString & inPath,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & ioOutputStream,
+ const std::vector< ::rtl::OUString > & inHeaderNames,
+ DAVResource & ioResource,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ PUT( const ::rtl::OUString & inPath,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ POST( const rtl::OUString & inPath,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & inInputStream,
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & oOutputStream,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ MKCOL( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void
+ COPY( const ::rtl::OUString & inSourceURL,
+ const ::rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException );
+
+ virtual void
+ MOVE( const ::rtl::OUString & inSourceURL,
+ const ::rtl::OUString & inDestinationURL,
+ const DAVRequestEnvironment & rEnv,
+ sal_Bool inOverWrite )
+ throw ( DAVException );
+
+ virtual void DESTROY( const ::rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // set new lock.
+ virtual void LOCK( const ::rtl::OUString & inURL,
+ com::sun::star::ucb::Lock & inLock,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // refresh existing lock.
+ virtual sal_Int64 LOCK( const ::rtl::OUString & inURL,
+ sal_Int64 nTimeout,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ virtual void UNLOCK( const ::rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // helpers
+ virtual void abort()
+ throw ( DAVException );
+
+ const rtl::OUString & getHostName() const { return m_aHostName; }
+
+ const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF()
+ { return m_xFactory->getServiceFactory(); }
+
+ const void * getRequestData() const { return m_pRequestData; }
+
+ sal_Bool isDomainMatch( rtl::OUString certHostName );
+
+private:
+ friend class NeonLockStore;
+
+ void Init( void )
+ throw ( DAVException );
+
+ void Init( const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ // ret: true => retry request.
+ void HandleError( int nError,
+ const rtl::OUString & inPath,
+ const DAVRequestEnvironment & rEnv )
+ throw ( DAVException );
+
+ const ucbhelper::InternetProxyServer & getProxySettings() const;
+
+ bool removeExpiredLocktoken( const rtl::OUString & inURL,
+ const DAVRequestEnvironment & rEnv );
+
+ // refresh lock, called by NeonLockStore::refreshLocks
+ bool LOCK( NeonLock * pLock,
+ sal_Int32 & rlastChanceToSendRefreshRequest );
+
+ // unlock, called by NeonLockStore::~NeonLockStore
+ bool UNLOCK( NeonLock * pLock );
+
+ // low level GET implementation, used by public GET implementations
+ static int GET( ne_session * sess,
+ const char * uri,
+ ne_block_reader reader,
+ bool getheaders,
+ void * userdata );
+
+ // Buffer-based PUT implementation. Neon only has file descriptor-
+ // based API.
+ static int PUT( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ size_t size );
+
+ // Buffer-based POST implementation. Neon only has file descriptor-
+ // based API.
+ int POST( ne_session * sess,
+ const char * uri,
+ const char * buffer,
+ ne_block_reader reader,
+ void * userdata,
+ const rtl::OUString & rContentType,
+ const rtl::OUString & rReferer );
+
+ // Helper: XInputStream -> Sequence< sal_Int8 >
+ static bool getDataFromInputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > & xStream,
+ com::sun::star::uno::Sequence< sal_Int8 > & rData,
+ bool bAppendTrailingZeroByte );
+
+ rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const;
};
-} // namespace_ucp
+} // namespace webdav_ucp
#endif // _NEONSESSION_HXX_
diff --git a/ucb/source/ucp/webdav/NeonTypes.hxx b/ucb/source/ucp/webdav/NeonTypes.hxx
index 2e97af4c963b..939e25d3812d 100644
--- a/ucb/source/ucp/webdav/NeonTypes.hxx
+++ b/ucb/source/ucp/webdav/NeonTypes.hxx
@@ -35,6 +35,7 @@
#include <ne_utils.h>
#include <ne_basic.h>
#include <ne_props.h>
+#include <ne_locks.h>
typedef ne_session HttpSession;
typedef ne_status HttpStatus;
@@ -43,4 +44,6 @@ typedef ne_server_capabilities HttpServerCapabilities;
typedef ne_propname NeonPropName;
typedef ne_prop_result_set NeonPropFindResultSet;
+typedef struct ne_lock NeonLock;
+
#endif // _NEONTYPES_HXX_
diff --git a/ucb/source/ucp/webdav/NeonUri.cxx b/ucb/source/ucp/webdav/NeonUri.cxx
index 5c49179f6b20..97fdeb40bcc7 100644
--- a/ucb/source/ucp/webdav/NeonUri.cxx
+++ b/ucb/source/ucp/webdav/NeonUri.cxx
@@ -42,11 +42,6 @@
using namespace webdav_ucp;
- char *scheme;
- char *host, *userinfo;
- unsigned int port;
- char *path, *query, *fragment;
-
# if defined __SUNPRO_CC
// FIXME: not sure whether initializing a ne_uri statically is supposed to work
// the string fields of ne_uri are char*, not const char*
diff --git a/ucb/source/ucp/webdav/makefile.mk b/ucb/source/ucp/webdav/makefile.mk
index c8891723cd2c..1b4265a74559 100644
--- a/ucb/source/ucp/webdav/makefile.mk
+++ b/ucb/source/ucp/webdav/makefile.mk
@@ -87,25 +87,26 @@ CFLAGS+= $(OPENSSL_CFLAGS)
# --- General -----------------------------------------------------
SLOFILES=\
- $(SLO)$/webdavservices.obj \
- $(SLO)$/webdavprovider.obj \
- $(SLO)$/webdavcontent.obj \
- $(SLO)$/webdavcontentcaps.obj \
- $(SLO)$/webdavresultset.obj \
- $(SLO)$/webdavdatasupplier.obj \
- $(SLO)$/ContentProperties.obj \
- $(SLO)$/DAVProperties.obj \
- $(SLO)$/DAVSessionFactory.obj \
- $(SLO)$/DAVResourceAccess.obj \
- $(SLO)$/NeonUri.obj \
- $(SLO)$/NeonInputStream.obj \
- $(SLO)$/NeonPropFindRequest.obj \
- $(SLO)$/NeonHeadRequest.obj \
- $(SLO)$/NeonSession.obj \
- $(SLO)$/DateTimeHelper.obj \
- $(SLO)$/LinkSequence.obj \
- $(SLO)$/LockSequence.obj \
- $(SLO)$/LockEntrySequence.obj \
+ $(SLO)$/webdavservices.obj \
+ $(SLO)$/webdavprovider.obj \
+ $(SLO)$/webdavcontent.obj \
+ $(SLO)$/webdavcontentcaps.obj \
+ $(SLO)$/webdavresultset.obj \
+ $(SLO)$/webdavdatasupplier.obj \
+ $(SLO)$/ContentProperties.obj \
+ $(SLO)$/DAVProperties.obj \
+ $(SLO)$/DAVSessionFactory.obj \
+ $(SLO)$/DAVResourceAccess.obj \
+ $(SLO)$/NeonUri.obj \
+ $(SLO)$/NeonInputStream.obj \
+ $(SLO)$/NeonPropFindRequest.obj \
+ $(SLO)$/NeonHeadRequest.obj \
+ $(SLO)$/NeonSession.obj \
+ $(SLO)$/NeonLockStore.obj \
+ $(SLO)$/DateTimeHelper.obj \
+ $(SLO)$/LinkSequence.obj \
+ $(SLO)$/LockSequence.obj \
+ $(SLO)$/LockEntrySequence.obj \
$(SLO)$/UCBDeadPropertyValue.obj
LIB1TARGET=$(SLB)$/_$(TARGET).lib
@@ -119,13 +120,13 @@ SHL1IMPLIB=i$(TARGET)
SHL1VERSIONMAP=exports.map
SHL1STDLIBS=\
- $(CPPUHELPERLIB) \
- $(CPPULIB) \
- $(SALLIB) \
- $(SALHELPERLIB) \
- $(UCBHELPERLIB) \
- $(COMPHELPERLIB) \
- $(NEON3RDLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(NEON3RDLIB) \
$(LIBXML2LIB)
@@ -165,4 +166,3 @@ DEF1NAME=$(SHL1TARGET)
# --- Targets ----------------------------------------------------------
.INCLUDE: target.mk
-
diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx
index afe2f2d3a7a8..ae6623ff4492 100644
--- a/ucb/source/ucp/webdav/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav/webdavcontent.cxx
@@ -54,14 +54,13 @@
#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>
@@ -137,7 +136,6 @@ public:
throw (uno::RuntimeException);
private:
-
void
handleAuthenticationRequest(
ucb::AuthenticationRequest const&,
@@ -190,52 +188,34 @@ void SAL_CALL CommandEnvironment_Impl::handle(
return;
uno::Sequence< uno::Reference< task::XInteractionContinuation > >
- rContinuations = rIRequest->getContinuations();
+ 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;
+ for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
+ {
xSupplyAuthentication
= uno::Reference< ucb::XInteractionSupplyAuthentication >(
rContinuations[i], uno::UNO_QUERY );
if( xSupplyAuthentication.is() )
- continue;
+ break;
}
- 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
+ if (!xSupplyAuthentication.is())
+ return;
+
+ ucb::RememberAuthentication eDefault;
+ uno::Sequence< ucb::RememberAuthentication > aModes(
+ xSupplyAuthentication->getRememberPasswordModes(eDefault));
+ bool bRememberPersistent = false;
+ for (sal_Int32 i = 0; i < aModes.getLength(); ++i)
{
- bRemember = false;
- bRememberPersistent = false;
+ if (aModes[i] == ucb::RememberAuthentication_PERSISTENT)
+ {
+ bRememberPersistent = true;
+ break;
+ }
}
uno::Reference< task::XPasswordContainer > xContainer;
@@ -334,7 +314,6 @@ void SAL_CALL CommandEnvironment_Impl::handle(
catch (task::NoMasterException const &)
{} // user did not enter master password
}
- return;
}
//=========================================================================
@@ -630,17 +609,20 @@ uno::Any SAL_CALL Content::execute(
ucb::CommandAbortedException,
uno::RuntimeException )
{
+ OSL_TRACE( "Content::execute: start %s",
+ rtl::OUStringToOString( aCommand.Name,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
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 +634,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 +656,7 @@ uno::Any SAL_CALL Content::execute(
// Unreachable
}
- if ( !aProperties.getLength() )
+ if ( !aProperties.getLength() )
{
ucbhelper::cancelCommandExecution(
uno::makeAny( lang::IllegalArgumentException(
@@ -713,8 +695,8 @@ uno::Any SAL_CALL Content::execute(
RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
{
//////////////////////////////////////////////////////////////////
- // open
- //////////////////////////////////////////////////////////////////
+ // open
+ //////////////////////////////////////////////////////////////////
ucb::OpenCommandArgument2 aOpenCommand;
if ( !( aCommand.Argument >>= aOpenCommand ) )
@@ -735,11 +717,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 +733,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 +805,7 @@ uno::Any SAL_CALL Content::execute(
{
//////////////////////////////////////////////////////////////////
// post
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
ucb::PostCommandArgument2 aArg;
if ( !( aCommand.Argument >>= aArg ) )
@@ -840,20 +822,44 @@ 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
{
- //////////////////////////////////////////////////////////////////
- // 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 %s",
+ rtl::OUStringToOString( aCommand.Name,
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+
return aRet;
}
@@ -863,19 +869,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 +902,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 +911,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 +959,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 +1038,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 +1048,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 +1279,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 +1288,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 +1347,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() );
@@ -1400,15 +1409,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 +1434,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 +1488,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 +1498,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
catch ( DAVException const & e )
{
bNetworkAccessAllowed
- = shouldAccessNetworkAfterException( e );
+ = shouldAccessNetworkAfterException( e );
if ( !bNetworkAccessAllowed )
{
@@ -1523,16 +1538,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 +1563,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 +1580,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
@@ -1603,14 +1616,12 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
// Add BaseURI property, if requested.
if ( !xProps->contains(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) ) )
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ) ) )
{
- xProps->addProperty( rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM(
- "BaseURI" ) ),
- uno::makeAny(
- getBaseURI( xResAccess ) ),
- true );
+ xProps->addProperty(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) ),
+ uno::makeAny( getBaseURI( xResAccess ) ),
+ true );
}
uno::Reference< sdbc::XRow > xResultRow
@@ -1663,7 +1674,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 +1735,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(
@@ -2035,7 +2046,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 +2054,8 @@ uno::Sequence< uno::Any > Content::setPropertyValues(
if ( nChanged > 0 )
{
- aChanges.realloc( nChanged );
- notifyPropertiesChange( aChanges );
+ aChanges.realloc( nChanged );
+ notifyPropertiesChange( aChanges );
}
{
@@ -2150,7 +2161,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 +2207,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 +2421,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 +2901,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 +3043,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 +3117,6 @@ uno::Any Content::MapDAVException( const DAVException & e, sal_Bool bWrite )
aArgs );
return aException;
}
-
default:
break;
}
@@ -3022,14 +3128,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 +3152,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 +3169,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 +3188,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 +3282,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 +3344,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 +3364,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 +3385,6 @@ const Content::ResourceType & Content::getResourceType(
}
}
m_eResourceType = eResourceType;
-
}
return m_eResourceType;
}
diff --git a/ucb/source/ucp/webdav/webdavcontent.hxx b/ucb/source/ucp/webdav/webdavcontent.hxx
index 861e48bdfcee..caf6ec9677a9 100644
--- a/ucb/source/ucp/webdav/webdavcontent.hxx
+++ b/ucb/source/ucp/webdav/webdavcontent.hxx
@@ -88,7 +88,7 @@ class Content : public ::ucbhelper::ContentImplHelper,
rtl::OUString m_aEscapedTitle;
ResourceType m_eResourceType;
ContentProvider* m_pProvider; // No need for a ref, base class holds object
- bool m_bTransient;
+ bool m_bTransient;
bool m_bCollection;
bool m_bDidGetOrHead;
std::vector< rtl::OUString > m_aFailedPropNames;
@@ -96,81 +96,91 @@ class Content : public ::ucbhelper::ContentImplHelper,
private:
virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
getProperties( const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
getCommands( const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv );
- virtual ::rtl::OUString getParentURL();
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
- sal_Bool isFolder( const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ sal_Bool isFolder( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( ::com::sun::star::uno::Exception );
- ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
- getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
::com::sun::star::beans::Property >& rProperties,
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( ::com::sun::star::uno::Exception );
::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
- setPropertyValues(
- const ::com::sun::star::uno::Sequence<
- ::com::sun::star::beans::PropertyValue >& rValues,
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( ::com::sun::star::uno::Exception );
typedef rtl::Reference< Content > ContentRef;
- typedef std::list< ContentRef > ContentRefList;
- void queryChildren( ContentRefList& rChildren);
+ typedef std::list< ContentRef > ContentRefList;
+ void queryChildren( ContentRefList& rChildren);
- sal_Bool exchangeIdentity(
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+ sal_Bool
+ exchangeIdentity( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
- const rtl::OUString getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess );
+ const rtl::OUString
+ getBaseURI( const std::auto_ptr< DAVResourceAccess > & rResAccess );
- const ResourceType & getResourceType(
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ const ResourceType &
+ getResourceType( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw ( ::com::sun::star::uno::Exception );
- const ResourceType & getResourceType(
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XCommandEnvironment >& xEnv,
- const std::auto_ptr< DAVResourceAccess > & rResAccess )
+ const ResourceType &
+ getResourceType( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv,
+ const std::auto_ptr< DAVResourceAccess > & rResAccess )
throw ( ::com::sun::star::uno::Exception );
// Command "open"
com::sun::star::uno::Any open(
const com::sun::star::ucb::OpenCommandArgument2 & rArg,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
throw( ::com::sun::star::uno::Exception );
// Command "post"
void post( const com::sun::star::ucb::PostCommandArgument2 & rArg,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ com::sun::star::ucb::XCommandEnvironment > & xEnv )
throw( ::com::sun::star::uno::Exception );
- // Command "insert"
- void insert( const ::com::sun::star::uno::Reference<
- ::com::sun::star::io::XInputStream > & xInputStream,
- sal_Bool bReplaceExisting,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& Environment )
+ // Command "insert"
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > & xInputStream,
+ sal_Bool bReplaceExisting,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
throw( ::com::sun::star::uno::Exception );
// Command "transfer"
void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& Environment )
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
throw( ::com::sun::star::uno::Exception );
// Command "delete"
- void destroy( sal_Bool bDeletePhysical )
+ void destroy( sal_Bool bDeletePhysical )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "lock"
+ void lock( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( ::com::sun::star::uno::Exception );
+
+ // Command "unlock"
+ void unlock( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
throw( ::com::sun::star::uno::Exception );
::com::sun::star::uno::Any MapDAVException( const DAVException & e,
@@ -184,57 +194,62 @@ private:
static bool shouldAccessNetworkAfterException( const DAVException & e );
+ bool supportsExclusiveWriteLock(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment );
+
public:
- Content( const ::com::sun::star::uno::Reference<
- ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
- ContentProvider* pProvider,
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
rtl::Reference< DAVSessionFactory > const & rSessionFactory )
throw ( ::com::sun::star::ucb::ContentCreationException );
- Content( const ::com::sun::star::uno::Reference<
- ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
- ContentProvider* pProvider,
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::ucb::XContentIdentifier >& Identifier,
+ Content( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& Identifier,
rtl::Reference< DAVSessionFactory > const & rSessionFactory,
- sal_Bool isCollection )
+ sal_Bool isCollection )
throw ( ::com::sun::star::ucb::ContentCreationException );
- virtual ~Content();
+ virtual ~Content();
- // XInterface
- XINTERFACE_DECL()
+ // XInterface
+ XINTERFACE_DECL()
// XTypeProvider
XTYPEPROVIDER_DECL()
// XServiceInfo
virtual ::rtl::OUString SAL_CALL
- getImplementationName()
+ getImplementationName()
throw( ::com::sun::star::uno::RuntimeException );
- virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
- getSupportedServiceNames()
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
throw( ::com::sun::star::uno::RuntimeException );
- // XContent
- virtual rtl::OUString SAL_CALL
- getContentType()
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
throw( com::sun::star::uno::RuntimeException );
- // XCommandProcessor
- virtual com::sun::star::uno::Any SAL_CALL
- execute( const com::sun::star::ucb::Command& aCommand,
- sal_Int32 CommandId,
- const com::sun::star::uno::Reference<
- com::sun::star::ucb::XCommandEnvironment >& Environment )
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
throw( com::sun::star::uno::Exception,
- com::sun::star::ucb::CommandAbortedException,
- com::sun::star::uno::RuntimeException );
- virtual void SAL_CALL
- abort( sal_Int32 CommandId )
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
throw( com::sun::star::uno::RuntimeException );
- // XPropertyContainer
+ // XPropertyContainer
virtual void SAL_CALL
addProperty( const rtl::OUString& Name,
sal_Int16 Attributes,
@@ -250,36 +265,36 @@ public:
com::sun::star::beans::NotRemoveableException,
com::sun::star::uno::RuntimeException );
- //////////////////////////////////////////////////////////////////////
- // Additional interfaces
- //////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
- // XContentCreator
+ // XContentCreator
virtual com::sun::star::uno::Sequence<
com::sun::star::ucb::ContentInfo > SAL_CALL
- queryCreatableContentsInfo()
+ queryCreatableContentsInfo()
throw( com::sun::star::uno::RuntimeException );
- virtual com::sun::star::uno::Reference<
- com::sun::star::ucb::XContent > SAL_CALL
- createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
throw( com::sun::star::uno::RuntimeException );
- //////////////////////////////////////////////////////////////////////
- // Non-interface methods.
- //////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
DAVResourceAccess & getResourceAccess() { return *m_xResAccess; }
- // Called from resultset data supplier.
- static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
- getPropertyValues( const ::com::sun::star::uno::Reference<
- ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ // Called from resultset data supplier.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
const ::com::sun::star::uno::Sequence<
- ::com::sun::star::beans::Property >& rProperties,
- const ContentProperties& rData,
+ ::com::sun::star::beans::Property >& rProperties,
+ const ContentProperties& rData,
const rtl::Reference<
::ucbhelper::ContentProviderImplHelper >& rProvider,
- const ::rtl::OUString& rContentId );
+ const ::rtl::OUString& rContentId );
};
}
diff --git a/ucb/source/ucp/webdav/webdavcontentcaps.cxx b/ucb/source/ucp/webdav/webdavcontentcaps.cxx
index 305d509b4e2c..cda93cfd855e 100644
--- a/ucb/source/ucp/webdav/webdavcontentcaps.cxx
+++ b/ucb/source/ucp/webdav/webdavcontentcaps.cxx
@@ -31,7 +31,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"
/**************************************************************************
- TODO
+ TODO
**************************************************************************
*************************************************************************/
@@ -46,19 +46,13 @@
#include <com/sun/star/ucb/PostCommandArgument2.hpp>
#include <com/sun/star/ucb/TransferInfo.hpp>
#include <com/sun/star/uno/Sequence.hxx>
-#ifndef _COM_SUN_STAR_UTIL_DATETIME_HXX_
#include <com/sun/star/util/DateTime.hpp>
-#endif
#include <com/sun/star/ucb/Link.hpp>
#include <com/sun/star/ucb/Lock.hpp>
#include <com/sun/star/ucb/LockEntry.hpp>
#include "webdavcontent.hxx"
-#ifndef _WEBDAV_UCP_PROVIDFER_HXX
#include "webdavprovider.hxx"
-#endif
-#ifndef _WEBDAV_SESSION_HXX
#include "DAVSession.hxx"
-#endif
#include "ContentProperties.hxx"
using namespace com::sun::star;
@@ -221,17 +215,16 @@ bool ContentProvider::getProperty(
m_pProps->insert(
beans::Property(
- DAVProperties::LOCKDISCOVERY,
+ DAVProperties::LOCKDISCOVERY,
-1,
getCppuType( static_cast<
- const uno::Sequence<
- com::sun::star::ucb::Lock > * >( 0 ) ),
+ const uno::Sequence< ucb::Lock > * >( 0 ) ),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY ) );
m_pProps->insert(
beans::Property(
- DAVProperties::RESOURCETYPE,
+ DAVProperties::RESOURCETYPE,
-1,
getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
beans::PropertyAttribute::BOUND
@@ -239,27 +232,25 @@ bool ContentProvider::getProperty(
m_pProps->insert(
beans::Property(
- DAVProperties::SOURCE,
+ DAVProperties::SOURCE,
-1,
getCppuType( static_cast<
- const uno::Sequence<
- com::sun::star::ucb::Link > * >( 0 ) ),
+ const uno::Sequence< ucb::Link > * >( 0 ) ),
beans::PropertyAttribute::BOUND ) );
m_pProps->insert(
beans::Property(
- DAVProperties::SUPPORTEDLOCK,
+ DAVProperties::SUPPORTEDLOCK,
-1,
getCppuType( static_cast<
const uno::Sequence<
- com::sun::star::ucb::LockEntry > * >(
- 0 ) ),
+ ucb::LockEntry > * >( 0 ) ),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::READONLY ) );
m_pProps->insert(
beans::Property(
- DAVProperties::EXECUTABLE,
+ DAVProperties::EXECUTABLE,
-1,
getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
beans::PropertyAttribute::BOUND ) );
@@ -301,7 +292,7 @@ bool ContentProvider::getProperty(
// virtual
uno::Sequence< beans::Property > Content::getProperties(
- const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
{
sal_Bool bTransient;
std::auto_ptr< DAVResourceAccess > xResAccess;
@@ -314,7 +305,8 @@ uno::Sequence< beans::Property > Content::getProperties(
bTransient = m_bTransient;
xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
if ( m_xCachedProps.get() )
- xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
+ xCachedProps.reset(
+ new ContentProperties( *m_xCachedProps.get() ) );
xProvider.set( m_pProvider );
}
@@ -525,236 +517,129 @@ uno::Sequence< beans::Property > Content::getProperties(
//=========================================================================
// virtual
-uno::Sequence< com::sun::star::ucb::CommandInfo > Content::getCommands(
- const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
{
osl::Guard< osl::Mutex > aGuard( m_aMutex );
- sal_Bool bFolder = sal_False;
-
- try
- {
- bFolder = isFolder( xEnv );
- }
- catch ( uno::Exception const & )
- {
- static com::sun::star::ucb::CommandInfo aDefaultCommandInfoTable[] =
- {
- ///////////////////////////////////////////////////////////////
- // Just mandatory commands avail.
- ///////////////////////////////////////////////////////////////
-
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
- -1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
- -1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
- -1,
- getCppuType( static_cast<
- uno::Sequence< beans::Property > * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
- -1,
- getCppuType( static_cast<
- uno::Sequence< beans::PropertyValue > * >( 0 ) )
- )
- };
- return uno::Sequence< com::sun::star::ucb::CommandInfo >(
- aDefaultCommandInfoTable, 4 );
- }
-
- if ( bFolder )
- {
- //=================================================================
- //
- // Folder: Supported commands
- //
- //=================================================================
+ uno::Sequence< ucb::CommandInfo > aCmdInfo( 8 );
- static com::sun::star::ucb::CommandInfo aFolderCommandInfoTable[] =
- {
- ///////////////////////////////////////////////////////////////
- // Required commands
- ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////////
- com::sun::star::ucb::CommandInfo(
+ aCmdInfo[ 0 ] =
+ ucb::CommandInfo(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
-1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
+ getCppuVoidType() );
+ aCmdInfo[ 1 ] =
+ ucb::CommandInfo(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
-1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
+ getCppuVoidType() );
+ aCmdInfo[ 2 ] =
+ ucb::CommandInfo(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
-1,
getCppuType( static_cast<
- uno::Sequence< beans::Property > * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
+ uno::Sequence< beans::Property > * >( 0 ) ) );
+ aCmdInfo[ 3 ] =
+ ucb::CommandInfo(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
-1,
getCppuType( static_cast<
- uno::Sequence< beans::PropertyValue > * >( 0 ) )
- ),
+ uno::Sequence< beans::PropertyValue > * >( 0 ) ) );
- ///////////////////////////////////////////////////////////////
- // Optional standard commands
- ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
- com::sun::star::ucb::CommandInfo(
+ aCmdInfo[ 4 ] =
+ ucb::CommandInfo(
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
-1,
- getCppuBooleanType()
- ),
- com::sun::star::ucb::CommandInfo(
+ getCppuBooleanType() );
+ aCmdInfo[ 5 ] =
+ ucb::CommandInfo(
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
-1,
getCppuType( static_cast<
- com::sun::star::ucb::InsertCommandArgument * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
+ ucb::InsertCommandArgument * >( 0 ) ) );
+ aCmdInfo[ 6 ] =
+ ucb::CommandInfo(
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
-1,
getCppuType( static_cast<
- com::sun::star::ucb::OpenCommandArgument2 * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
- -1,
- getCppuType( static_cast<
- com::sun::star::ucb::TransferInfo * >( 0 ) )
- )
+ ucb::OpenCommandArgument2 * >( 0 ) ) );
- ///////////////////////////////////////////////////////////////
- // New commands
- ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////////
- /*
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COPY" ) ),
- -1,
- getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MOVE" ) ),
+ aCmdInfo[ 7 ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "post" ) ),
-1,
- getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
- )
- */
- };
+ getCppuType( static_cast<
+ ucb::PostCommandArgument2 * >( 0 ) ) );
- return uno::Sequence< com::sun::star::ucb::CommandInfo >(
- aFolderCommandInfoTable, 8 );
+ sal_Bool bFolder = sal_False;
+
+ try
+ {
+ bFolder = isFolder( xEnv );
}
- else
+ catch ( uno::Exception const & )
{
- //=================================================================
- //
- // Document: Supported commands
- //
- //=================================================================
-
- static com::sun::star::ucb::CommandInfo aDocumentCommandInfoTable[] =
- {
- ///////////////////////////////////////////////////////////////
- // Required commands
- ///////////////////////////////////////////////////////////////
-
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
- -1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
- -1,
- getCppuVoidType()
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
- -1,
- getCppuType( static_cast<
- uno::Sequence< beans::Property > * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
- -1,
- getCppuType( static_cast<
- uno::Sequence< beans::PropertyValue > * >( 0 ) )
- ),
+ return aCmdInfo;
+ }
- ///////////////////////////////////////////////////////////////
- // Optional standard commands
- ///////////////////////////////////////////////////////////////
+ sal_Bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
- -1,
- getCppuBooleanType()
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
- -1,
- getCppuType( static_cast<
- com::sun::star::ucb::InsertCommandArgument * >( 0 ) )
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
- -1,
- getCppuType( static_cast<
- com::sun::star::ucb::OpenCommandArgument2 * >( 0 ) )
- ),
+ sal_Int32 nPos = aCmdInfo.getLength();
+ sal_Int32 nMoreCmds = ( bFolder ? 1 : 0 ) + ( bSupportsLocking ? 2 : 0 );
+ if ( nMoreCmds )
+ aCmdInfo.realloc( nPos + nMoreCmds );
+ else
+ return aCmdInfo;
- ///////////////////////////////////////////////////////////////
- // New commands
- ///////////////////////////////////////////////////////////////
+ if ( bFolder )
+ {
+ ///////////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////////
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "post" ) ),
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
-1,
- getCppuType( static_cast<
- com::sun::star::ucb::PostCommandArgument2 * >( 0 ) )
- )
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) ) );
+ nPos++;
+ }
+ else
+ {
+ // no document-only commands at the moment.
+ }
- /*
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COPY" ) ),
+ if ( bSupportsLocking )
+ {
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lock" ) ),
-1,
- getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
- ),
- com::sun::star::ucb::CommandInfo(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MOVE" ) ),
+ getCppuVoidType() );
+ nPos++;
+ aCmdInfo[ nPos ] =
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unlock" ) ),
-1,
- getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
- )
- */
- };
-
- return uno::Sequence< com::sun::star::ucb::CommandInfo >(
- aDocumentCommandInfoTable, 8 );
+ getCppuVoidType() );
+ nPos++;
}
+ return aCmdInfo;
}
-
diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx
index 996fd24e531d..29f380b2a7a0 100644
--- a/uui/source/iahndl.cxx
+++ b/uui/source/iahndl.cxx
@@ -86,6 +86,9 @@
#include "com/sun/star/ucb/InteractiveAppException.hpp"
#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
#include "com/sun/star/ucb/InteractiveCHAOSException.hpp"
+#include "com/sun/star/ucb/InteractiveLockingLockedException.hpp"
+#include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp"
+#include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp"
#include "com/sun/star/ucb/InteractiveNetworkConnectException.hpp"
#include "com/sun/star/ucb/InteractiveNetworkException.hpp"
#include "com/sun/star/ucb/InteractiveNetworkGeneralException.hpp"
@@ -1105,6 +1108,58 @@ bool UUIInteractionHelper::handleMessageboxRequests(
return true;
}
+ star::ucb::InteractiveLockingLockedException aLLException;
+ if (aAnyRequest >>= aLLException)
+ {
+ ErrCode nErrorCode = aLLException.SelfOwned
+ ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED;
+ std::vector< rtl::OUString > aArguments;
+ aArguments.push_back( aLLException.Url );
+
+ handleErrorRequest( aLLException.Classification,
+ nErrorCode,
+ aArguments,
+ rRequest->getContinuations(),
+ bObtainErrorStringOnly,
+ bHasErrorString,
+ rErrorString );
+ return true;
+ }
+
+ star::ucb::InteractiveLockingNotLockedException aLNLException;
+ if (aAnyRequest >>= aLNLException)
+ {
+ ErrCode nErrorCode = ERRCODE_UUI_LOCKING_NOT_LOCKED;
+ std::vector< rtl::OUString > aArguments;
+ aArguments.push_back( aLNLException.Url );
+
+ handleErrorRequest( aLNLException.Classification,
+ nErrorCode,
+ aArguments,
+ rRequest->getContinuations(),
+ bObtainErrorStringOnly,
+ bHasErrorString,
+ rErrorString );
+ return true;
+ }
+
+ star::ucb::InteractiveLockingLockExpiredException aLLEException;
+ if (aAnyRequest >>= aLLEException)
+ {
+ ErrCode nErrorCode = ERRCODE_UUI_LOCKING_LOCK_EXPIRED;
+ std::vector< rtl::OUString > aArguments;
+ aArguments.push_back( aLLEException.Url );
+
+ handleErrorRequest( aLLEException.Classification,
+ nErrorCode,
+ aArguments,
+ rRequest->getContinuations(),
+ bObtainErrorStringOnly,
+ bHasErrorString,
+ rErrorString );
+ return true;
+ }
+
return false;
}
diff --git a/uui/source/ids.hrc b/uui/source/ids.hrc
index 08624a3dda4e..7259b8ba86e3 100644
--- a/uui/source/ids.hrc
+++ b/uui/source/ids.hrc
@@ -149,6 +149,10 @@
#define ERRCODE_UUI_CONFIGURATION_BACKENDMISSING_WITHRECOVER (ERRCODE_AREA_UUI + 56)
#define ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA (ERRCODE_AREA_UUI + 57)
#define ERRCODE_UUI_IO_MODULESIZEEXCEEDED (ERRCODE_AREA_UUI + 58)
+#define ERRCODE_UUI_LOCKING_LOCKED (ERRCODE_AREA_UUI + 59)
+#define ERRCODE_UUI_LOCKING_LOCKED_SELF (ERRCODE_AREA_UUI + 60)
+#define ERRCODE_UUI_LOCKING_NOT_LOCKED (ERRCODE_AREA_UUI + 61)
+#define ERRCODE_UUI_LOCKING_LOCK_EXPIRED (ERRCODE_AREA_UUI + 62)
#define ERRCODE_AREA_UUI_UNKNOWNAUTH 25000
#define SSLWARN_TYPE_DOMAINMISMATCH 10
diff --git a/uui/source/ids.src b/uui/source/ids.src
index fc82161bbb81..0d692a13fa71 100644
--- a/uui/source/ids.src
+++ b/uui/source/ids.src
@@ -1,3 +1,4 @@
+
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -351,6 +352,27 @@ Resource RID_UUI_ERRHDL
Text [ en-US ] = "The form contains invalid data. Do you still want to continue?";
};
+ String (ERRCODE_UUI_LOCKING_LOCKED & ERRCODE_RES_MASK)
+ {
+ Text [ en-US ] = "The file $(ARG1) is locked by another user. Currently, another write access to this file cannot be granted.";
+
+ };
+
+ String (ERRCODE_UUI_LOCKING_LOCKED_SELF & ERRCODE_RES_MASK)
+ {
+ Text [ en-US ] = "The file $(ARG1) is locked by yourself. Currently, another write access to this file cannot be granted.";
+ };
+
+ String (ERRCODE_UUI_LOCKING_NOT_LOCKED & ERRCODE_RES_MASK)
+ {
+ Text [ en-US ] = "The file $(ARG1) is currently not locked by yourself.";
+ };
+
+ String (ERRCODE_UUI_LOCKING_LOCK_EXPIRED & ERRCODE_RES_MASK)
+ {
+ Text [ en-US ] = "The previously obtained lock for file $(ARG1) has expired.\nThis can happen due to problems on the server managing the file lock. It cannot be guaranteed that write operations on this file will not overwrite changes done by other users!";
+ };
+
STRING (ERRCODE_UUI_UNKNOWNAUTH_UNTRUSTED)
{
Text [ en-US ] = "Unable to verify the identity of $(ARG1) site.\n\nBefore accepting this certificate, you should examine this site's certificate carefully. Are you willing to accept this certificate for the purpose of identifying the Web site $(ARG1)?";