diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-10-04 17:17:53 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-10-04 20:16:37 +0100 |
commit | 03ded70913f957460f90608465e4d0a182879074 (patch) | |
tree | 75e35619a3949e3442f160b9e144ea69a478d100 /ucb/source/ucp/webdav-neon/ContentProperties.cxx | |
parent | 5d0c1f0ac8875292c49989e4f77fafc52a7e84a6 (diff) |
rename ucb/source/ucp/webdav to webdav-neon
Diffstat (limited to 'ucb/source/ucp/webdav-neon/ContentProperties.cxx')
-rw-r--r-- | ucb/source/ucp/webdav-neon/ContentProperties.cxx | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-neon/ContentProperties.cxx b/ucb/source/ucp/webdav-neon/ContentProperties.cxx new file mode 100644 index 000000000000..dc9b03fe43cd --- /dev/null +++ b/ucb/source/ucp/webdav-neon/ContentProperties.cxx @@ -0,0 +1,621 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +#include <osl/diagnose.h> +#include <com/sun/star/util/DateTime.hpp> +#include "NeonUri.hxx" +#include "DAVResource.hxx" +#include "DAVProperties.hxx" +#include "DateTimeHelper.hxx" +#include "webdavprovider.hxx" +#include "ContentProperties.hxx" + +using namespace com::sun::star; +using namespace webdav_ucp; + +/* +============================================================================= + + Property Mapping + +============================================================================= +HTTP (entity header) WebDAV (property) UCB (property) +============================================================================= + +Allow +Content-Encoding +Content-Language getcontentlanguage +Content-Length getcontentlength Size +Content-Location +Content-MD5 +Content-Range +Content-Type getcontenttype MediaType +Expires +Last-Modified getlastmodified DateModified + creationdate DateCreated + resourcetype IsFolder,IsDocument,ContentType + displayname +ETag (actually getetag +a response header ) + lockdiscovery + supportedlock + source + Title (always taken from URI) + +============================================================================= + +Important: HTTP headers will not be mapped to DAV properties; only to UCB + properties. (Content-Length,Content-Type,Last-Modified) +*/ + +//========================================================================= +//========================================================================= +// +// ContentProperties Implementation. +// +//========================================================================= +//========================================================================= + +// static member! +uno::Any ContentProperties::m_aEmptyAny; + +ContentProperties::ContentProperties( const DAVResource& rResource ) +: m_xProps( new PropertyValueMap ), + m_bTrailingSlash( false ) +{ + OSL_ENSURE( !rResource.uri.isEmpty(), + "ContentProperties ctor - Empty resource URI!" ); + + // Title + try + { + NeonUri aURI( rResource.uri ); + m_aEscapedTitle = aURI.GetPathBaseName(); + + (*m_xProps)[ rtl::OUString("Title") ] + = PropertyValue( + uno::makeAny( aURI.GetPathBaseNameUnescaped() ), true ); + } + catch ( DAVException const & ) + { + (*m_xProps)[ rtl::OUString("Title") ] + = PropertyValue( + uno::makeAny( + rtl::OUString( + "*** unknown ***" ) ), + true ); + } + + std::vector< DAVPropertyValue >::const_iterator it + = rResource.properties.begin(); + std::vector< DAVPropertyValue >::const_iterator end + = rResource.properties.end(); + + while ( it != end ) + { + addProperty( (*it) ); + ++it; + } + + if ( rResource.uri.getStr()[ rResource.uri.getLength() - 1 ] + == sal_Unicode( '/' ) ) + m_bTrailingSlash = sal_True; +} + +//========================================================================= +ContentProperties::ContentProperties( + const rtl::OUString & rTitle, sal_Bool bFolder ) +: m_xProps( new PropertyValueMap ), + m_bTrailingSlash( sal_False ) +{ + (*m_xProps)[ rtl::OUString("Title") ] + = PropertyValue( uno::makeAny( rTitle ), true ); + (*m_xProps)[ rtl::OUString("IsFolder") ] + = PropertyValue( uno::makeAny( bFolder ), true ); + (*m_xProps)[ rtl::OUString("IsDocument") ] + = PropertyValue( uno::makeAny( sal_Bool( !bFolder ) ), true ); +} + +//========================================================================= +ContentProperties::ContentProperties( const rtl::OUString & rTitle ) +: m_xProps( new PropertyValueMap ), + m_bTrailingSlash( sal_False ) +{ + (*m_xProps)[ rtl::OUString("Title") ] + = PropertyValue( uno::makeAny( rTitle ), true ); +} + +//========================================================================= +ContentProperties::ContentProperties() +: m_xProps( new PropertyValueMap ), + m_bTrailingSlash( sal_False ) +{ +} + +//========================================================================= +ContentProperties::ContentProperties( const ContentProperties & rOther ) +: m_aEscapedTitle( rOther.m_aEscapedTitle ), + m_xProps( rOther.m_xProps.get() + ? new PropertyValueMap( *rOther.m_xProps ) + : new PropertyValueMap ), + m_bTrailingSlash( rOther.m_bTrailingSlash ) +{ +} + +//========================================================================= +bool ContentProperties::contains( const rtl::OUString & rName ) const +{ + if ( get( rName ) ) + return true; + else + return false; +} + +//========================================================================= +const uno::Any & ContentProperties::getValue( + const rtl::OUString & rName ) const +{ + const PropertyValue * pProp = get( rName ); + if ( pProp ) + return pProp->value(); + else + return m_aEmptyAny; +} + +//========================================================================= +const PropertyValue * ContentProperties::get( + const rtl::OUString & rName ) const +{ + PropertyValueMap::const_iterator it = m_xProps->find( rName ); + const PropertyValueMap::const_iterator end = m_xProps->end(); + + if ( it == end ) + { + it = m_xProps->begin(); + while ( it != end ) + { + if ( (*it).first.equalsIgnoreAsciiCase( rName ) ) + return &(*it).second; + + ++it; + } + return 0; + } + else + return &(*it).second; +} + +//========================================================================= +// static +void ContentProperties::UCBNamesToDAVNames( + const uno::Sequence< beans::Property > & rProps, + std::vector< rtl::OUString > & propertyNames, + bool bIncludeUnmatched /* = true */ ) +{ + ////////////////////////////////////////////////////////////// + // Assemble list of DAV properties to obtain from server. + // Append DAV properties needed to obtain requested UCB props. + ////////////////////////////////////////////////////////////// + + // DAV UCB + // creationdate <- DateCreated + // getlastmodified <- DateModified + // getcontenttype <- MediaType + // getcontentlength <- Size + // resourcetype <- IsFolder, IsDocument, ContentType + // (taken from URI) <- Title + + sal_Bool bCreationDate = sal_False; + sal_Bool bLastModified = sal_False; + sal_Bool bContentType = sal_False; + sal_Bool bContentLength = sal_False; + sal_Bool bResourceType = sal_False; + + sal_Int32 nCount = rProps.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const beans::Property & rProp = rProps[ n ]; + + if ( rProp.Name == "Title" ) + { + // Title is always obtained from resource's URI. + continue; + } + else if ( rProp.Name == "DateCreated" || rProp.Name == DAVProperties::CREATIONDATE ) + { + if ( !bCreationDate ) + { + propertyNames.push_back( DAVProperties::CREATIONDATE ); + bCreationDate = sal_True; + } + } + else if ( rProp.Name == "DateModified" || rProp.Name == DAVProperties::GETLASTMODIFIED ) + { + if ( !bLastModified ) + { + propertyNames.push_back( + DAVProperties::GETLASTMODIFIED ); + bLastModified = sal_True; + } + } + else if ( rProp.Name == "MediaType" || rProp.Name == DAVProperties::GETCONTENTTYPE ) + { + if ( !bContentType ) + { + propertyNames.push_back( + DAVProperties::GETCONTENTTYPE ); + bContentType = sal_True; + } + } + else if ( rProp.Name == "Size" || rProp.Name == DAVProperties::GETCONTENTLENGTH ) + { + if ( !bContentLength ) + { + propertyNames.push_back( + DAVProperties::GETCONTENTLENGTH ); + bContentLength = sal_True; + } + } + else if ( rProp.Name == "ContentType" || rProp.Name == "IsDocument" || rProp.Name == "IsFolder" || rProp.Name == DAVProperties::RESOURCETYPE ) + { + if ( !bResourceType ) + { + propertyNames.push_back( DAVProperties::RESOURCETYPE ); + bResourceType = sal_True; + } + } + else + { + if ( bIncludeUnmatched ) + propertyNames.push_back( rProp.Name ); + } + } +} + +//========================================================================= +// static +void ContentProperties::UCBNamesToHTTPNames( + const uno::Sequence< beans::Property > & rProps, + std::vector< rtl::OUString > & propertyNames, + bool bIncludeUnmatched /* = true */ ) +{ + ////////////////////////////////////////////////////////////// + // Assemble list of HTTP header names to obtain from server. + // Append HTTP headers needed to obtain requested UCB props. + ////////////////////////////////////////////////////////////// + + // HTTP UCB + // Last-Modified <- DateModified + // Content-Type <- MediaType + // Content-Length <- Size + + sal_Int32 nCount = rProps.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const beans::Property & rProp = rProps[ n ]; + + if ( rProp.Name == "DateModified" ) + { + propertyNames.push_back( + rtl::OUString("Last-Modified") ); + } + else if ( rProp.Name == "MediaType" ) + { + propertyNames.push_back( + rtl::OUString("Content-Type") ); + } + else if ( rProp.Name == "Size" ) + { + propertyNames.push_back( + rtl::OUString("Content-Length") ); + } + else + { + if ( bIncludeUnmatched ) + propertyNames.push_back( rProp.Name ); + } + } +} + +//========================================================================= +bool ContentProperties::containsAllNames( + const uno::Sequence< beans::Property >& rProps, + std::vector< rtl::OUString > & rNamesNotContained ) const +{ + rNamesNotContained.clear(); + + sal_Int32 nCount = rProps.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const rtl::OUString & rName = rProps[ n ].Name; + if ( !contains( rName ) ) + { + // Not found. + rNamesNotContained.push_back( rName ); + } + } + + return ( rNamesNotContained.empty() ); +} + +//========================================================================= +void ContentProperties::addProperties( + const std::vector< rtl::OUString > & rProps, + const ContentProperties & rContentProps ) +{ + std::vector< rtl::OUString >::const_iterator it = rProps.begin(); + std::vector< rtl::OUString >::const_iterator end = rProps.end(); + + while ( it != end ) + { + const rtl::OUString & rName = (*it); + + if ( !contains( rName ) ) // ignore duplicates + { + const PropertyValue * pProp = rContentProps.get( rName ); + if ( pProp ) + { + // Add it. + addProperty( rName, pProp->value(), pProp->isCaseSensitive() ); + } + else + { + addProperty( rName, uno::Any(), false ); + } + } + ++it; + } +} + +//========================================================================= +void ContentProperties::addProperty( const DAVPropertyValue & rProp ) +{ + addProperty( rProp.Name, rProp.Value, rProp.IsCaseSensitive ); +} + +//========================================================================= +void ContentProperties::addProperty( const rtl::OUString & rName, + const com::sun::star::uno::Any & rValue, + bool bIsCaseSensitive ) +{ + if ( rName.equals( DAVProperties::CREATIONDATE ) ) + { + // Map DAV:creationdate to UCP:DateCreated + rtl::OUString aValue; + rValue >>= aValue; + util::DateTime aDate; + DateTimeHelper::convert( aValue, aDate ); + + (*m_xProps)[ rtl::OUString("DateCreated") ] + = PropertyValue( uno::makeAny( aDate ), true ); + } + // else if ( rName.equals( DAVProperties::DISPLAYNAME ) ) + // { + // } + // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) ) + // { + // } + else if ( rName.equals( DAVProperties::GETCONTENTLENGTH ) ) + { + // Map DAV:getcontentlength to UCP:Size + rtl::OUString aValue; + rValue >>= aValue; + + (*m_xProps)[ rtl::OUString("Size") ] + = PropertyValue( uno::makeAny( aValue.toInt64() ), true ); + } + else if ( rName == "Content-Length" ) + { + // Do NOT map Content-Lenght entity header to DAV:getcontentlength! + // Only DAV resources have this property. + + // Map Content-Length entity header to UCP:Size + rtl::OUString aValue; + rValue >>= aValue; + + (*m_xProps)[ rtl::OUString("Size") ] + = PropertyValue( uno::makeAny( aValue.toInt64() ), true ); + } + else if ( rName.equals( DAVProperties::GETCONTENTTYPE ) ) + { + // Map DAV:getcontenttype to UCP:MediaType (1:1) + (*m_xProps)[ rtl::OUString("MediaType") ] + = PropertyValue( rValue, true ); + } + else if ( rName == "Content-Type" ) + { + // Do NOT map Content-Type entity header to DAV:getcontenttype! + // Only DAV resources have this property. + + // Map DAV:getcontenttype to UCP:MediaType (1:1) + (*m_xProps)[ rtl::OUString("MediaType") ] + = PropertyValue( rValue, true ); + } + // else if ( rName.equals( DAVProperties::GETETAG ) ) + // { + // } + else if ( rName.equals( DAVProperties::GETLASTMODIFIED ) ) + { + // Map the DAV:getlastmodified entity header to UCP:DateModified + rtl::OUString aValue; + rValue >>= aValue; + util::DateTime aDate; + DateTimeHelper::convert( aValue, aDate ); + + (*m_xProps)[ rtl::OUString("DateModified") ] + = PropertyValue( uno::makeAny( aDate ), true ); + } + else if ( rName == "Last-Modified" ) + { + // Do not map Last-Modified entity header to DAV:getlastmodified! + // Only DAV resources have this property. + + // Map the Last-Modified entity header to UCP:DateModified + rtl::OUString aValue; + rValue >>= aValue; + util::DateTime aDate; + DateTimeHelper::convert( aValue, aDate ); + + (*m_xProps)[ rtl::OUString("DateModified") ] + = PropertyValue( uno::makeAny( aDate ), true ); + } + // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) ) + // { + // } + else if ( rName.equals( DAVProperties::RESOURCETYPE ) ) + { + rtl::OUString aValue; + rValue >>= aValue; + + // Map DAV:resourceype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType + sal_Bool bFolder = + aValue.equalsIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM( "collection" ) ); + + (*m_xProps)[ rtl::OUString("IsFolder") ] + = PropertyValue( uno::makeAny( bFolder ), true ); + (*m_xProps)[ rtl::OUString("IsDocument") ] + = PropertyValue( uno::makeAny( sal_Bool( !bFolder ) ), true ); + (*m_xProps)[ rtl::OUString("ContentType") ] + = PropertyValue( uno::makeAny( bFolder + ? rtl::OUString( WEBDAV_COLLECTION_TYPE ) + : rtl::OUString( WEBDAV_CONTENT_TYPE ) ), true ); + } + // else if ( rName.equals( DAVProperties::SOURCE ) ) + // { + // } + // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) ) + // { + // } + + // Save property. + (*m_xProps)[ rName ] = PropertyValue( rValue, bIsCaseSensitive ); +} + +//========================================================================= +//========================================================================= +// +// CachableContentProperties Implementation. +// +//========================================================================= +//========================================================================= + +namespace +{ + bool isCachable( rtl::OUString const & rName, + bool isCaseSensitive ) + { + static rtl::OUString aNonCachableProps [] = + { + DAVProperties::LOCKDISCOVERY, + + DAVProperties::GETETAG, + rtl::OUString( "ETag" ), + + rtl::OUString( "DateModified" ), + rtl::OUString( "Last-Modified" ), + DAVProperties::GETLASTMODIFIED, + + rtl::OUString( "Size" ), + rtl::OUString( "Content-Length" ), + DAVProperties::GETCONTENTLENGTH, + + rtl::OUString( "Date" ) + }; + + for ( sal_uInt32 n = 0; + n < ( sizeof( aNonCachableProps ) + / sizeof( aNonCachableProps[ 0 ] ) ); + ++n ) + { + if ( isCaseSensitive ) + { + if ( rName.equals( aNonCachableProps[ n ] ) ) + return false; + } + else + if ( rName.equalsIgnoreAsciiCase( aNonCachableProps[ n ] ) ) + return false; + } + return true; + } + +} // namespace + +//========================================================================= +CachableContentProperties::CachableContentProperties( + const ContentProperties & rProps ) +{ + addProperties( rProps ); +} + +//========================================================================= +void CachableContentProperties::addProperties( + const ContentProperties & rProps ) +{ + SAL_WNODEPRECATED_DECLARATIONS_PUSH + const std::auto_ptr< PropertyValueMap > & props = rProps.getProperties(); + SAL_WNODEPRECATED_DECLARATIONS_POP + + PropertyValueMap::const_iterator it = props->begin(); + const PropertyValueMap::const_iterator end = props->end(); + + while ( it != end ) + { + if ( isCachable( (*it).first, (*it).second.isCaseSensitive() ) ) + m_aProps.addProperty( (*it).first, + (*it).second.value(), + (*it).second.isCaseSensitive() ); + + ++it; + } +} + +//========================================================================= +void CachableContentProperties::addProperties( + const std::vector< DAVPropertyValue > & rProps ) +{ + std::vector< DAVPropertyValue >::const_iterator it = rProps.begin(); + const std::vector< DAVPropertyValue >::const_iterator end = rProps.end(); + + while ( it != end ) + { + if ( isCachable( (*it).Name, (*it).IsCaseSensitive ) ) + m_aProps.addProperty( (*it) ); + + ++it; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |